Commit d42044c486532763190da438028c558d18bed44c

Authored by Erickson Silva
1 parent ff7863f2
Exists in master and in 1 other branch devel

Altera alexp para aceitar acentuação na sentença

Showing 1 changed file with 38 additions and 17 deletions   Show diff stats
src/new/alexp.py
... ... @@ -31,15 +31,11 @@ import re, string,nltk,platform
31 31 from os.path import expanduser
32 32 from Aelius.Extras import carrega
33 33 from Aelius import AnotaCorpus
  34 +from nltk_tgrep import tgrep_positions, tgrep_nodes
  35 +from unicodedata import normalize
34 36  
35   -# definição de algumas variáveis globais para
36   -# facilitar utilização das diferentes funções do módulo
37 37  
38   -# eventualmente será preciso incluir aqui outros sinais
39   -# de pontuação, como o travessão
40   -PUNCT=string.punctuation
41   -
42   -SENTENCA_ANOTADA=""
  38 +sentenca_anotada=""
43 39  
44 40  
45 41 def toqueniza(s):
... ... @@ -49,13 +45,14 @@ def toqueniza(s):
49 45 return AnotaCorpus.TOK_PORT.tokenize(decodificada)
50 46  
51 47 def getAnaliseMorfologica():
52   - return SENTENCA_ANOTADA
  48 + return sentenca_anotada
53 49  
54 50 def etiquetaSentenca(s):
55 51 """Aplica um dos etiquetadores do Aelius na etiquetagem da sentença dada como lista de tokens.
56 52 """
57 53 etiquetador = carrega("AeliusHunPos")
58 54 anotada = AnotaCorpus.anota_sentencas([s],etiquetador,"hunpos")[0]
  55 + anotada[0] = (anotada[0][0].lower(), anotada[0][1])
59 56 return anotada
60 57  
61 58 def geraEntradasLexicais(lista):
... ... @@ -67,7 +64,7 @@ def geraEntradasLexicais(lista):
67 64 # que não são aceitos pelo NLTK como símbolos não terminais
68 65 c=re.sub(r"[-+]","_",e[1])
69 66 c=re.sub(r"\$","_S",c)
70   - entradas.append("%s -> '%s'" % (c, e[0].lower()))
  67 + entradas.append("%s -> '%s'" % (c, removeAcento(e[0].lower())))
71 68 return entradas
72 69  
73 70 def corrigeAnotacao(lista):
... ... @@ -101,33 +98,57 @@ def extraiSintaxe():
101 98 return sintaxe
102 99 else:
103 100 print "Arquivo %s não encontrado em nenhum dos diretórios de dados do NLTK:\n%s" % (caminho,"\n".join(nltk.data.path))
104   -
105 101  
106 102 def analisaSentenca(sentenca):
107 103 """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.
108 104 """
109 105 parser=constroiAnalisador(sentenca)
110   - codificada=[w.encode("utf-8") for w in sentenca]
  106 + codificada=[removeAcento(w).encode("utf-8") for w in sentenca]
111 107 trees=parser.parse_one(codificada)
112 108 return trees
113 109  
114 110 def constroiAnalisador(s):
115 111 """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.
116 112 """
117   - global SENTENCA_ANOTADA
118   - SENTENCA_ANOTADA=etiquetaSentenca(s)
119   - corrigeAnotacao(SENTENCA_ANOTADA)
120   - entradas=geraEntradasLexicais(SENTENCA_ANOTADA)
  113 + global sentenca_anotada
  114 + sentenca_anotada=etiquetaSentenca(s)
  115 + corrigeAnotacao(sentenca_anotada)
  116 + entradas=geraEntradasLexicais(sentenca_anotada)
121 117 lexico="\n".join(entradas)
122 118 gramatica="%s\n%s" % (extraiSintaxe().strip(),lexico)
123 119 cfg=nltk.CFG.fromstring(gramatica)
124 120 return nltk.ChartParser(cfg)
125 121  
  122 +def corrigeArvore(arvore):
  123 + lista_pos_arv = []
  124 + for tupla in sentenca_anotada:
  125 + string_grep = adaptaAnotacao(tupla[1]) + " < " + tupla[0].lower()
  126 + node = tgrep_positions(arvore, string_grep)
  127 + if not node:
  128 + string_grep = adaptaAnotacao(tupla[1]) + " < " + removeAcento(tupla[0].lower())
  129 + node = tgrep_positions(arvore, string_grep)
  130 + if node[0] in lista_pos_arv:
  131 + node.reverse()
  132 + lista_pos_arv.append(node[0])
  133 + for i in range(0, len(sentenca_anotada)):
  134 + if arvore[lista_pos_arv[i]][0] != sentenca_anotada[i][0]:
  135 + arvore[lista_pos_arv[i]][0] = sentenca_anotada[i][0]
  136 + return arvore
  137 +
  138 +def removeAcento(texto):
  139 + return normalize('NFKD', texto.encode('utf-8').decode('utf-8')).encode('ascii', 'ignore')
  140 +
  141 +def adaptaAnotacao(anotacao):
  142 + split = anotacao.split('_')
  143 + for i in range(0, len(split)):
  144 + split[i] = split[i].replace('-','_')
  145 + return "-".join(split)
  146 +
126 147 def exibeArvores(arvores):
127 148 """Função 'wrapper' para a função de exibição de árvores do NLTK"""
128 149 nltk.draw.draw_trees(*arvores)
129 150  
130 151 def run(sentenca):
131 152 tokens=toqueniza(sentenca)
132   - trees=analisaSentenca(tokens)
133   - return trees
134 153 \ No newline at end of file
  154 + tree=analisaSentenca(tokens)
  155 + return corrigeArvore(tree)
135 156 \ No newline at end of file
... ...