Segundo Trabalho Prático de GTI
Resolução
Exercício 1
Escreva as expressões regulares correspondentes a cada uma das seguintes
situações:



Aceitar um inteiro positivo com um máximo de 5 dígitos entre 0 e 32768
(sem zeros na esquerda)
Aceitar um número real positivo ou negativo.
Aceitar uma password entre 4 e 8 caracteres, que comece com uma letra
e tenha pelo menos um dígito.

Aceitar um URL bem formado.

Aceitar uma data no formato “MONTH_NAME DD, YYYY”
Exercício 1
1) [0-9]|[1-9][0-9]{1,3}|[1-2][0-9]{4}|3[0-1][0-9]{3}|32[0-6][0-9]{2}|327[0-5][09]|3276[0-8]
2) [+-]?[0-9]*\.?[0-9]+
3) [A-Za-z](?=.*\d).{3,7}
4) ((ht)|f)tp(s)?://([a-zA-Z0-9]+\.)+((pt)|(com))(/[a-zA-Z0-9_\.]*)+(\?([a-zA-Z00_]+=[a-zA-Z0-0_])(\&([a-zA-Z0-9_]+=[a-zA-Z0-9_]))*)?
5) (([Jj]aneiro)|([Ff]evereiro)|([Mm]arço)|([Aa]bril)|([Mm]aio)|([Jj]unho)|([Jj]ulho)|([
Aa]gosto)|([Ss]etembro)|([Oo]utubro)|([Nn]ovembro)|([Dd]ezembro))((0?[19])|([1-2][0-9)]|(3[0-1])) [0-9]{1-4}
Exercício 2

Escreva um ficheiro de configuração para a
ferramenta Web-harvest que permita aceder à página
Web com endereço
http://www.ist.utl.pt/information.php?boardId=7557 e
extrair do seu conteúdo todas as noticias. A saída do
processo de extracção deverá obedecer ao formato
RSS. Na resolução deve constar o ficheiro de
configuração do Web-harvest, o documento RSS
usado como entrada e o resultado de saída.
Exercício 2
<?xml version="1.0" encoding="UTF-8"?>
<config charset="UTF-8">
<var-def name="url">http://www.ist.utl.pt/information.php?boardId=7557</var-def>
<file action="write" path="data/data.xml" charset="UTF-8">
<![CDATA[
<rss version="2.0">
<channel>
<title>Noticias do IST</title>
<description>Noticias extraidas do site do IST</description>
<link>]]><var name="url"/><![CDATA[</link>]]>
Exercício 2
<xquery>
<xq-param name="doc">
<html-to-xml outputtype="pretty">
<http url="${url}"/>
</html-to-xml>
</xq-param>
<xq-expression><![CDATA[
declare variable $doc as node() external;
for $i in 1 to count($doc//h3)
let $title := data($doc//h3[@class='mtop2'])[$i]
let $description := data($doc//div[@class='ann'])[$i]
let $date := data($doc//p[@class='post_date'])[$i]
let $author := data($doc//div[@class='ann']/p[@class='grey_bright']/a)[$i]
Exercício 2
return
<item>
<title>{normalize-space($title)}</title>
<description>{normalize-space($description)}</description>
<pubDate>{normalize-space($date)}</pubDate>
<author>{normalize-space($author)}</author>
</item>
]]></xq-expression>
</xquery>
<![CDATA[
</channel>
</rss>]]>
</file>
</config>
Exercício 3

Escreva um programa Java que, utilizando o LingPipe,
faça a extracção de todas as datas mencionadas no
ficheiro RSS obtido como saída no Exercício 2. Na
resolução deve constar o código Java e o resultado da
extracção.
Exercício 3
import com.aliasi.chunk.*;
import java.util.*;
import java.io.*;
import javax.xml.xpath.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import org.w3c.dom.*;
import org.xml.sax.*;
public class RecognizeDates {
private static final String CHUNK_TYPE = "date";
Exercício 3
private static final String regexp1 = "[0-9][0-9]( de)?
((Janeiro)|(Fevereiro)|(Março)|(Maio)|(Abril)|(Maio)|(Junho)|(Julho)|(Agosto)|(Setembro)|(
Outubro)|(Novembro)|(Dezembro))
[0-9][0-9][0-9][0-9]";
private static final double score1 = 1.0;
private RegExChunker chunker1;
private static final String regexp2 =
"((jan)|(fev)|(mar)|(mai)|(abr)|(mai)|(jun)|(jul)|(ago)|(set)|(out)|(nov)|(dez))(\\.)?(
de)? [0-9][0-9][0-9][0-9]";
private static final double score2 = 0.8;
private RegExChunker chunker2;
Exercício 3
public RecognizeDates() {
chunker1 = new RegExChunker(regexp1,CHUNK_TYPE,score1);
chunker2 = new RegExChunker(regexp2,CHUNK_TYPE,score2);
}
Exercício 3
private void printChunks ( Chunker chunker, String text ) {
Chunking chunking = chunker.chunk(text);
Set chunkSet = chunking.chunkSet();
Iterator it = chunkSet.iterator();
while (it.hasNext()) {
Chunk chunk = (Chunk) it.next();
int start = chunk.start();
int end = chunk.end();
String stext = text.substring(start,end);
System.out.println("chunk="+chunk+" text="+stext);
}
}
Exercício 3
public static void main ( String args[] ) throws Exception {
RecognizeDates recognizer = new RecognizeDates();
DocumentBuilder builder =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse("data/data.xml");
XPath xp = XPathFactory.newInstance().newXPath();
XPathExpression expr = xp.compile("//item");
NodeList nodes = (NodeList)expr.evaluate(doc,XPathConstants.NODESET);
Exercício 3
for (int i=0; i<nodes.getLength(); i++) {
Node item = nodes.item(i);
String text = (String) xp.compile("pubDate").evaluate(item,
XPathConstants.STRING) + " - " +
(String)xp.compile("description").evaluate(item, XPathConstants.STRING);
System.out.println("*** Texto");
System.out.println(text);
System.out.println("*** Resultados para o item " + i);
recognizer.printChunks(recognizer.chunker1,text);
recognizer.printChunks(recognizer.chunker2,text);
System.out.println("***");
} }}
Exercício 4




Escreva um programa que, utilizando a ferramenta
LingPipe, faça a extracção de todos os nomes de
departamentos do IST a partir do ficheiro RSS obtido
como saída no Exercício 2. Pretende-se que a cada
notícia seja associada a lista de departamentos nela
mencionados. Deverá ser considerada a seguinte lista de
departamentos do IST:
Departamento de Engenharia Civil e Arquitectura (DECivil)
Departamento de Engenharia Electrotécnica e de
Computadores (DEEC)
etc.
Exercício 4
import com.aliasi.chunk.*;
import com.aliasi.dict.*;
import com.aliasi.tokenizer.*;
import java.util.*;
import java.io.*;
import javax.xml.xpath.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import org.w3c.dom.*;
import org.xml.sax.*;
Exercício 4
public class RecognizeDepartments {
private MapDictionary dictionary;
private ExactDictionaryChunker chunker;
public RecognizeDepartments() {
dictionary = new MapDictionary();
Exercício 4
dictionary.addEntry(new DictionaryEntry("Departamento de Engenharia Civil e
Arquitectura","DECivil",1.0));
dictionary.addEntry(new DictionaryEntry("Departamento de Engenharia
Civil","DECivil",0.8));
dictionary.addEntry(new DictionaryEntry("DECivil","DECivil",0.8));
dictionary.addEntry(new DictionaryEntry("Engenharia Civil","DECivil",0.4));
dictionary.addEntry(new DictionaryEntry("Civil","DECivil",0.1));
dictionary.addEntry(new DictionaryEntry("Departamento de Engenharia
Informática","DEI",1.0));
dictionary.addEntry(new DictionaryEntry("DEI","DEI",0.5));
dictionary.addEntry(new DictionaryEntry("Engenharia Informática","DEI",0.4));
dictionary.addEntry(new DictionaryEntry("Informática","DEI",0.1));
// Repetir para os restantes departamentos
Exercício 4
chunker = new
ExactDictionaryChunker(dictionary,IndoEuropeanTokenizerFactory.FACTORY,
true, true);
}
Exercício 4
public String recognizeDepartments ( String text ) {
StringBuffer aux = new StringBuffer();
Set result = new HashSet();
Chunking chunking = chunker.chunk(text);
Set chunkSet = chunking.chunkSet();
Iterator it = chunkSet.iterator();
while (it.hasNext()) {
Chunk chunk = (Chunk) it.next();
if(aux.length()!=0) aux.append(",");
aux.append(chunk.type());
}
return aux.toString();
}
Exercício 4
public static void main ( String args[] ) throws Exception {
RecognizeDepartments chunker = new RecognizeDepartments();
DocumentBuilder builder =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse("data/data.xml");
XPath xp = XPathFactory.newInstance().newXPath();
XPathExpression expr = xp.compile("//item");
NodeList nodes = (NodeList)expr.evaluate(doc,XPathConstants.NODESET);
Exercício 4
for (int i=0; i<nodes.getLength(); i++) {
Node item = nodes.item(i);
String text = (String) xp.compile("title").evaluate(item,
XPathConstants.STRING) + " - " +
(String) xp.compile("description").evaluate(item,
XPathConstants.STRING);
String result = chunker.recognizeDepartments(text);
System.out.println("*** Texto");
System.out.println(text);
System.out.println("Resultado para o item " + i + " : " + result);
System.out.println("***");
} }}
Exercício 5
Responda às seguintes alíneas:



Indique dois algoritmos de aprendizagem automática
(Machine Learning) suportados pelo LingPipe. Com que
finalidade pode cada um deles ser utilizado?
Explique sucintamente o algoritmo de classificação Naive
Bayes.
Explique qual a assunção feita por um classificador Naive
Bayes em relação aos termos individuais (i.e. explicar
porque se diz que o classificador é “Naive”).
Exercício 5


O LingPipe suporta os algoritmos de classificação Naive Bayes e Language
Modeling (LMClassifier). Ambos se baseiam em processos estatísticos que
assentam no teorema de Bayes, diferindo no facto de considerarem ou não
a independência entre os termos. Outras respostas possíveis seriam um
classificador baseado em redes neuronais (PerceptronClassifier) ou um
classificador "vizinho mais próximo" (KNNClassifier).
Um classificador Naive Bayes usa um processo estatístico baseado no
teorema de Bayes, calculando a probabilidade do documento a classificar
pertencer a uma dada classe (i.e. a classe de maior probabilidade é a
escolhida para classificar o documento). O teorema de Bayes permite
inverter o calculo desta probabilidade, podendo a mesma ser obtida a partir
da probabilidade de ocorrência de um dado documento tendo-se a classe
(esta podem ser estimada a partir da ocorrência de termos individuais num
conjunto de treino) e da probabilidade de ocorrência de uma dada classe
(que também pode ser estimada a partir de um conjunto de treino)
Exercício 5

Um classificador Naive Bayes assume a independência entre os termos
(e.g. a ocorrência de uma palavra num texto é independente da ocorrência
de outras palavras) para efeitos de simplificação do calculo das
probabilidades condicionais.
Download

Segundo Trabalho Prático de GTI