def desambiguar(self, ctx, ambigua, pos, nbest=True,\ lematizar=True, stem=True, stop=True,\ usar_ontologia=False, usr_ex=False,\ busca_ampla=False, med_sim='cosine', cands=[ ]): # Para gerar chave do CACHE vars_locais = dict(locals()) dir_cache_tmp = None dir_bases = self.cfgs['caminho_bases'] self.usar_cache = False if self.usar_cache: obj_dir_cache_des = dir_bases + '/' + self.cfgs['oxford']['cache'][ 'desambiguador'] del vars_locais['self'] del vars_locais['ambigua'] k_vars = self.construir_chave_cache(vars_locais) dir_completo_obj = "%s/%s.json" % (obj_dir_cache_des, ambigua) Util.abrir_json(dir_completo_obj, criarsenaoexiste=True) if k_vars in obj_cache: return obj_cache[k_vars] if len(pos) == 1: pos = Util.cvrsr_pos_wn_oxford(pos) lem, st = (med_sim == 'cosine'), (med_sim == 'cosine') todas_assinaturas = [] try: todas_assinaturas = self.assinatura_significado( ambigua, usar_exemplos=usr_ex, lematizar=lem, stem=st) for candidato_iter in cands: todas_assinaturas += self.assinatura_significado( candidato_iter, usar_exemplos=usr_ex, lematizar=lem, stem=st) todas_assinaturas = [ assi for assi in todas_assinaturas if pos == assi[0].split('.')[1] ] # Tirando palavras de tamanho 1 ctx = [p for p in Util.tokenize(ctx.lower()) if len(p) > 1] ctx = Util.normalizar_ctx(ctx, stop=stop, lematizar=lem, stem=st) except KeyboardInterrupt, ke: pass
class DesOx(object): INSTANCE = None cache_objs_json = {} def __init__(self, cfgs, base_ox, rep_vetorial=None): self.cfgs = cfgs self.base_ox = base_ox self.rep_conceitos = None self.rep_vetorial = rep_vetorial self.usar_cache = True self.dir_cache = cfgs['oxford']['cache']['desambiguador'] self.tam_max_ngram = 4 def assinatura_significado_aux(self, lema, pos, definicao, lista_exemplos): retornar_valida = Util.retornar_valida_pra_indexar assinatura = retornar_valida(definicao.replace('.', '')).lower() assinatura = [ p for p in Util.tokenize(assinatura) if not p in [',', ';', '.'] ] if lista_exemplos: assinatura += list( itertools.chain( *[retornar_valida(ex).split() for ex in lista_exemplos])) assinatura += lema assinatura = [p for p in assinatura if len(p) > 1] return assinatura # "lematizar,True::nbest,True::stop,True::ctx,frase.::pos,r::usar_ontologia,False:: # stem,True::usar_exemplos,True::busca_ampla,False" def construir_chave_cache(self, vars): vars = [ ",".join((unicode(k), unicode(v))) for k, v in vars.iteritems() ] return "::".join(vars) # Metodo Cosseno feito para o dicionario de Oxford # Retorna dados ordenados de forma decrescente def desambiguar(self, ctx, ambigua, pos, nbest=True,\ lematizar=True, stem=True, stop=True,\ usar_ontologia=False, usr_ex=False,\ busca_ampla=False, med_sim='cosine', cands=[ ]): # Para gerar chave do CACHE vars_locais = dict(locals()) dir_cache_tmp = None dir_bases = self.cfgs['caminho_bases'] self.usar_cache = False if self.usar_cache: obj_dir_cache_des = dir_bases + '/' + self.cfgs['oxford']['cache'][ 'desambiguador'] del vars_locais['self'] del vars_locais['ambigua'] k_vars = self.construir_chave_cache(vars_locais) dir_completo_obj = "%s/%s.json" % (obj_dir_cache_des, ambigua) Util.abrir_json(dir_completo_obj, criarsenaoexiste=True) if k_vars in obj_cache: return obj_cache[k_vars] if len(pos) == 1: pos = Util.cvrsr_pos_wn_oxford(pos) lem, st = (med_sim == 'cosine'), (med_sim == 'cosine') todas_assinaturas = [] try: todas_assinaturas = self.assinatura_significado( ambigua, usar_exemplos=usr_ex, lematizar=lem, stem=st) for candidato_iter in cands: todas_assinaturas += self.assinatura_significado( candidato_iter, usar_exemplos=usr_ex, lematizar=lem, stem=st) todas_assinaturas = [ assi for assi in todas_assinaturas if pos == assi[0].split('.')[1] ] # Tirando palavras de tamanho 1 ctx = [p for p in Util.tokenize(ctx.lower()) if len(p) > 1] ctx = Util.normalizar_ctx(ctx, stop=stop, lematizar=lem, stem=st) except KeyboardInterrupt, ke: pass pontuacao = [] for assi in todas_assinaturas: ass_definicao = Util.normalizar_ctx(assi[3], stop=stop, lematizar=lematizar, stem=stem) label_def, desc_def, frase_def, ass_def = assi reg_def = (label_def, desc_def, frase_def) if med_sim == 'cosine': func_sim = cos_sim elif med_sim == 'word_move_distance': func_sim = self.rep_vetorial.word_move_distance dist_simi = func_sim(" ".join(ctx), " ".join(ass_definicao)) # Colocando valor infinito if dist_simi == float('inf'): dist_simi = float(Util.MAX_WMD) if dist_simi == 'cosine' and dist_simi == 0.00: pass else: pontuacao.append((dist_simi, reg_def)) # Ordenacao da saida do desambiguador (cosine=decrescente, wmd=crescente) ordem_crescente = (med_sim == 'cosine') res_des = [(s, p) for p, s in sorted(pontuacao, reverse=ordem_crescente)] if self.usar_cache: obj_cache[k_vars] = res_des Util.salvar_json(dir_completo_obj, obj_cache) return res_des
def assinatura_significado(self, lema, lematizar=True,\ stem=False, stop=True,\ extrair_relacao_semantica=False,\ usar_exemplos=False): resultado = BaseOx.construir_objeto_unificado(self.base_ox, lema) if not resultado: resultado = {} lema = lemmatize(lema) assinaturas_significados = [] # (nome, definicao, exemplos) for pos in resultado.keys(): todos_significados = resultado[pos].keys() indice = 1 for sig in todos_significados: nome_sig = "%s.%s.%d" % (lema, pos, indice) indice += 1 if usar_exemplos: exemplos = resultado[pos][sig]['exemplos'] else: exemplos = [] # nome, definicao, exemplos, assinatura definicao_corrente = [nome_sig, sig, exemplos, []] assinaturas_significados.append(definicao_corrente) # Colocando exemplos na assinatura definicao_corrente[len(definicao_corrente) - 1] += self.assinatura_significado_aux( lema, pos, sig, exemplos) sig_secundarios = resultado[pos][sig]['def_secs'] for ss in sig_secundarios: nome_sig_sec = "%s.%s.%d" % (lema, pos, indice) if usar_exemplos: exemplos_secundarios = resultado[pos][sig]['def_secs'][ ss]['exemplos'] else: exemplos_secundarios = [] definicao_corrente_sec = [ nome_sig_sec, ss, exemplos_secundarios, [] ] assinaturas_significados.append(definicao_corrente_sec) definicao_corrente_sec[ len(definicao_corrente) - 1] += self.assinatura_significado_aux( lema, pos, ss, exemplos_secundarios) indice += 1 for sig in assinaturas_significados: sig[3] = Util.normalizar_ctx(sig[3], stop=True, lematizar=True, stem=True) return [tuple(a) for a in assinaturas_significados]
def cosine_lesk_inventario_estendido(context_sentence, ambiguous_word, \ pos=None, lemma=True, stem=True, hyperhypo=True, \ stop=True, context_is_lemmatized=False, \ nbest=False, synsets_signatures=None, busca_ampla=False): """ In line with vector space models, we can use cosine to calculate overlaps instead of using raw overlap counts. Essentially, the idea of using signatures (aka 'sense paraphrases') is lesk-like. """ # Ensure that ambiguous word is a lemma. if lemma: ambiguous_word = lemmatize(ambiguous_word) # If ambiguous word not in WordNet return None #if not wn.synsets(ambiguous_word): if not criar_inventario_des_wn(ambiguous_word, busca_ampla=busca_ampla): return None if context_is_lemmatized: context_sentence = " ".join(context_sentence.split()) else: context_sentence = " ".join(lemmatize_sentence(context_sentence)) scores = [] chave_assinatura = "%s.%s.%s.%s.%s.%s" % (ambiguous_word, pos, lemma, stem, hyperhypo, busca_ampla) if not chave_assinatura in DesWordnet.cache_assinaturas: synsets_signatures = simple_signature(ambiguous_word, pos, lemma, stem, hyperhypo, busca_ampla=busca_ampla) DesWordnet.cache_assinaturas[chave_assinatura] = [] for ss, signature in synsets_signatures.items(): # Lowercase and replace "_" with spaces. signature = " ".join(map(str, signature)).lower().replace("_", " ") # Removes punctuation. signature = [i for i in Util.word_tokenize(signature) \ if i not in string.punctuation] signature = Util.normalizar_ctx(signature, stop=stop, lematizar=lemma, stem=stem) scores.append((cos_sim(context_sentence, " ".join(signature)), ss)) DesWordnet.cache_assinaturas[chave_assinatura].append( (ss, signature)) else: synsets_signatures = DesWordnet.cache_assinaturas[chave_assinatura] for ss, signature in synsets_signatures: scores.append((cos_sim(context_sentence, " ".join(signature)), ss)) if not nbest: return sorted(scores, reverse=True)[0][1] else: return [(j, i) for i, j in sorted(scores, reverse=True)]