From d42044c486532763190da438028c558d18bed44c Mon Sep 17 00:00:00 2001 From: Erickson Silva Date: Wed, 25 Feb 2015 16:03:28 -0300 Subject: [PATCH] Altera alexp para aceitar acentuação na sentença --- src/new/alexp.py | 55 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/src/new/alexp.py b/src/new/alexp.py index 3099572..dc185df 100644 --- a/src/new/alexp.py +++ b/src/new/alexp.py @@ -31,15 +31,11 @@ import re, string,nltk,platform from os.path import expanduser from Aelius.Extras import carrega from Aelius import AnotaCorpus +from nltk_tgrep import tgrep_positions, tgrep_nodes +from unicodedata import normalize -# definição de algumas variáveis globais para -# facilitar utilização das diferentes funções do módulo -# eventualmente será preciso incluir aqui outros sinais -# de pontuação, como o travessão -PUNCT=string.punctuation - -SENTENCA_ANOTADA="" +sentenca_anotada="" def toqueniza(s): @@ -49,13 +45,14 @@ def toqueniza(s): return AnotaCorpus.TOK_PORT.tokenize(decodificada) def getAnaliseMorfologica(): - return SENTENCA_ANOTADA + return sentenca_anotada def etiquetaSentenca(s): """Aplica um dos etiquetadores do Aelius na etiquetagem da sentença dada como lista de tokens. """ etiquetador = carrega("AeliusHunPos") anotada = AnotaCorpus.anota_sentencas([s],etiquetador,"hunpos")[0] + anotada[0] = (anotada[0][0].lower(), anotada[0][1]) return anotada def geraEntradasLexicais(lista): @@ -67,7 +64,7 @@ def geraEntradasLexicais(lista): # que não são aceitos pelo NLTK como símbolos não terminais c=re.sub(r"[-+]","_",e[1]) c=re.sub(r"\$","_S",c) - entradas.append("%s -> '%s'" % (c, e[0].lower())) + entradas.append("%s -> '%s'" % (c, removeAcento(e[0].lower()))) return entradas def corrigeAnotacao(lista): @@ -101,33 +98,57 @@ def extraiSintaxe(): return sintaxe else: print "Arquivo %s não encontrado em nenhum dos diretórios de dados do NLTK:\n%s" % (caminho,"\n".join(nltk.data.path)) - def analisaSentenca(sentenca): """Retorna lista de árvores de estrutura sintagmática para a sentença dada sob a forma de uma lista de tokens, com base na gramática CFG cujo caminho é especificado como segundo argumento da função. Esse caminho é relativo à pasta nltk_data da instalação local do NLTK. A partir da etiquetagem morfossintática da sentença são geradas entradas lexicais que passam a integrar a gramática CFG. O caminho da gramática e o parser gerado são armazenados como tupla na variável ANALISADORES. """ parser=constroiAnalisador(sentenca) - codificada=[w.encode("utf-8") for w in sentenca] + codificada=[removeAcento(w).encode("utf-8") for w in sentenca] trees=parser.parse_one(codificada) return trees def constroiAnalisador(s): """Constrói analisador a partir de uma única sentença não anotada, dada como lista de tokens, e uma lista de regras sintáticas no formato CFG, armazenadas em arquivo. Esta função tem um bug, causado pela maneira como o Aelius etiqueta sentenças usando o módulo ProcessaNomesProprios: quando a sentença se inicia por paravra com inicial minúscula, essa palavra não é incorporada ao léxico, mas a versão com inicial maiúscula. """ - global SENTENCA_ANOTADA - SENTENCA_ANOTADA=etiquetaSentenca(s) - corrigeAnotacao(SENTENCA_ANOTADA) - entradas=geraEntradasLexicais(SENTENCA_ANOTADA) + global sentenca_anotada + sentenca_anotada=etiquetaSentenca(s) + corrigeAnotacao(sentenca_anotada) + entradas=geraEntradasLexicais(sentenca_anotada) lexico="\n".join(entradas) gramatica="%s\n%s" % (extraiSintaxe().strip(),lexico) cfg=nltk.CFG.fromstring(gramatica) return nltk.ChartParser(cfg) +def corrigeArvore(arvore): + lista_pos_arv = [] + for tupla in sentenca_anotada: + string_grep = adaptaAnotacao(tupla[1]) + " < " + tupla[0].lower() + node = tgrep_positions(arvore, string_grep) + if not node: + string_grep = adaptaAnotacao(tupla[1]) + " < " + removeAcento(tupla[0].lower()) + node = tgrep_positions(arvore, string_grep) + if node[0] in lista_pos_arv: + node.reverse() + lista_pos_arv.append(node[0]) + for i in range(0, len(sentenca_anotada)): + if arvore[lista_pos_arv[i]][0] != sentenca_anotada[i][0]: + arvore[lista_pos_arv[i]][0] = sentenca_anotada[i][0] + return arvore + +def removeAcento(texto): + return normalize('NFKD', texto.encode('utf-8').decode('utf-8')).encode('ascii', 'ignore') + +def adaptaAnotacao(anotacao): + split = anotacao.split('_') + for i in range(0, len(split)): + split[i] = split[i].replace('-','_') + return "-".join(split) + def exibeArvores(arvores): """Função 'wrapper' para a função de exibição de árvores do NLTK""" nltk.draw.draw_trees(*arvores) def run(sentenca): tokens=toqueniza(sentenca) - trees=analisaSentenca(tokens) - return trees \ No newline at end of file + tree=analisaSentenca(tokens) + return corrigeArvore(tree) \ No newline at end of file -- libgit2 0.21.2