250 likes | 333 Views
Resolução. Segundo Trabalho Prático de GTI. 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.
E N D
Resolução Segundo Trabalho Prático de GTI
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 • [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][0-9]|3276[0-8] • [+-]?[0-9]*\.?[0-9]+ • [A-Za-z](?=.*\d).{3,7} • ((ht)|f)tp(s)?://([a-zA-Z0-9]+\.)+((pt)|(com))(/[a-zA-Z0-9_\.]*)+(\?([a-zA-Z0-0_]+=[a-zA-Z0-0_])(\&([a-zA-Z0-9_]+=[a-zA-Z0-9_]))*)? • (([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?[1-9])|([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.