Skip to content

Commit

Permalink
Complementando a classe Elastic
Browse files Browse the repository at this point in the history
Novos métodos da classe Elastic (termos e analisadores) e retornando os scores ordenados pelo maior score no classificador
  • Loading branch information
luizanisio authored Aug 26, 2018
1 parent f105e27 commit 7297e37
Showing 1 changed file with 72 additions and 9 deletions.
81 changes: 72 additions & 9 deletions exemplo_classificador.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from requests.auth import HTTPBasicAuth
import requests
import json
from collections import Counter

class Elastic:
def __init__(self, host='http://elasticsearch:9200', indice='', tipo='', usuario=None, senha=None):
Expand Down Expand Up @@ -80,6 +81,50 @@ def analyze(self, analyzer, campo, texto):
else:
return {}

def analyze_counter(self, analyzer, campo, texto):
an = self.analyze(analyzer, campo, texto)
if not an:
return None
return Counter([k.get('token') for k in an])

def term_vector(self, campo, texto):
dados = {"doc": {campo: texto},
"field_statistics": False,
"term_statistics": True,
"positions": False,
"offsets": False,
"filter": {}}
termos = self.post(self.url_term_vectors(), dados)
if termos:
if termos.get('status') == 404:
raise ValueError(''.join(['Não foi possível identificar os vetores do campo especificado [', campo,
'] não é inválido para o índice [', self.indice, '/', self.tipo,
'] - erro 404']))
try:
print(termos)
termos = termos.get('term_vectors')
if termos:
termos = termos.get(campo)['terms']
except KeyError:
termos = {}
else:
termos = {}
return termos

def term_vector_counter(self, campo, texto, normalizado=False):
termos = self.term_vector(campo, texto)
if not termos:
return Counter({})
# print('TERMOS>>>>',termos.keys())
try:
pesos = {k: termos.get(k).get('score') for k in termos.keys()}
except KeyError:
pesos = Counter({})
if normalizado:
return TermosCounter.normaliza_counter(pesos)
else:
return pesos

def classificar(self, query, campo_classe):
assert query and campo_classe and len(query)>0 and len(campo_classe)>0, "Elastic.classificar: É necessário informar a query e o campo_classe usados na classificação"
res = self.search(query)
Expand All @@ -91,18 +136,36 @@ def classificar(self, query, campo_classe):
classe = r.get('_source', {}).get(campo_classe, '')
score = r.get('_score', 0)
scores[classe] = score + scores.get(classe, 0)
return scores
return TermosCounter.ordena(counter=scores,reverso=True)

class TermosCounter:
# Normaliza os valores de pesos de um counter entre 1 e 2 para multiplicação
@staticmethod
def normaliza_counter(counter):
if not counter:
return Counter({})
# normaliza os pesos >> 1+peso/total de pesos
maxV = max(counter.values())
minV = min(counter.values())
if maxV - minV == 0:
return counter
return Counter({k: 1 + ((counter.get(k, 1) - minV) / (maxV - minV)) for k in counter.keys()})

# Multiplica um counter de termos por um de pesos
@staticmethod
def ajusta_counter(counter_origem, counter_pesos):
if not counter_origem:
return Counter({})
if not counter_pesos:
return counter_origem
return Counter({k: counter_origem.get(k, 1) * counter_pesos.get(k, 1) for k in counter_origem.keys()})

@staticmethod
def ordena(counter, reverso=False):
return sorted(Counter(counter).items(), key=lambda i: i[1], reverse=reverso)

if __name__ == "__main__":
elastic = Elastic('http://localhost:9200', 'meustextos', 'textos', '', '')
'''print("## Dados do elastic ###############################")
res = elastic.search({"size" : 1000})
res = res.get('hits',{}).get('hits',[])
res = [ r.get('_source',{}) for r in res]
[ print ("POST meustextos/textos/{}\n".format(r.get('Id')),r,"\n") for r in res]
'''

print('### Retorno da classificação do texto')
textoNovo="isso é muito legal, adoro esse texto"
campo='Classificacao'
Expand Down

0 comments on commit 7297e37

Please sign in to comment.