File size: 3,254 Bytes
2695555 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | """Junta as frases geradas e tira: repetidas, já existentes, e qualquer uma
AVISO (4.0 Endurance Neo): este script de desenvolvimento usa o tars_classificador.py
(Naive Bayes), que saiu do openTARS. Pra rodar, pegue esse arquivo da 4.0 Endurance.
parecida com uma frase de teste EM QUALQUER IDIOMA.
As frases de teste entram aqui nos 5 idiomas: as da avaliação já existem
traduzidas (idiomas/*.json) e as de tests/frases_classificador.py foram
traduzidas só pra este filtro (filtro_traducoes_teste.json). Assim some
também a TRADUÇÃO de uma frase de teste, não só a cópia.
Sai: parecida (pedaços de letras ou palavras) OU que divide com uma frase
de teste uma palavra rara (número de 2+ dígitos, ou palavra que quase não
aparece no resto dos dados, tipo "mona", "framework").
"""
import glob
import json
import os
import re
import sys
AQUI = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, AQUI)
from dados import teste, treino, RAIZ, TAREFAS # noqa: E402
sys.path.insert(0, RAIZ)
import tars_classificador as cl # noqa: E402
from sklearn.feature_extraction.text import TfidfVectorizer # noqa: E402
from sklearn.metrics.pairwise import cosine_similarity # noqa: E402
av, ex = teste()
T = [f for f, _, _ in av + ex]
for item in json.load(open(os.path.join(AQUI, "filtro_traducoes_teste.json"), encoding="utf-8")):
T += [item[k] for k in ("pt_BR", "en", "es", "fr", "de") if item.get(k)]
existentes = {cl.normalizar(f) for f, _ in treino()}
def palavras(f):
return set(cl.tokens(cl.normalizar(f))) - cl.VAZIAS
gerado, vistos = [], set()
for arq in sorted(glob.glob(os.path.join(AQUI, "gerado", "*.json"))):
idioma = os.path.basename(arq)[:-5]
for cat, lista in json.load(open(arq, encoding="utf-8")).items():
assert cat in TAREFAS, cat
for f in lista:
k = cl.normalizar(f)
if k in vistos or k in existentes:
continue
vistos.add(k)
gerado.append((f, cat, idioma))
# frequência de cada palavra em todos os dados de treino (pra achar as raras)
df = {}
for f in [g[0] for g in gerado] + [f for f, _ in treino()]:
for w in palavras(f):
df[w] = df.get(w, 0) + 1
Tp = [palavras(t) for t in T]
raras_teste = set()
for p in Tp:
for w in p:
if re.fullmatch(r"\d{2,}", w) or (len(w) >= 4 and df.get(w, 0) <= 2):
raras_teste.add(w)
vec = TfidfVectorizer(analyzer="char_wb", ngram_range=(3, 5)).fit([g[0] for g in gerado] + T)
sim = cosine_similarity(vec.transform([g[0] for g in gerado]), vec.transform(T))
limpo, fora = [], []
for i, (f, cat, idi) in enumerate(gerado):
a = palavras(f)
jac = max((len(a & b) / len(a | b) if a and b else 0) for b in Tp)
rara = a & raras_teste
if sim[i].max() >= 0.6 or jac >= 0.4 or rara:
fora.append((f, T[sim[i].argmax()], round(float(sim[i].max()), 2), round(jac, 2), sorted(rara)))
else:
limpo.append((f, cat, idi))
with open(os.path.join(AQUI, "gerado_limpo.json"), "w", encoding="utf-8") as saida:
json.dump(limpo, saida, ensure_ascii=False, indent=0)
print(f"geradas {len(gerado)} · ficaram {len(limpo)} · saíram por parecer teste {len(fora)}")
if "-v" in sys.argv:
for x in fora:
print(" ", x)
|