Spaces:
Runtime error
Runtime error
File size: 6,941 Bytes
7f59544 4057e14 1c359f1 e85a261 9a541e5 7f59544 1c359f1 c6ba15f 4ab86fc 4707333 1c359f1 7f59544 1c359f1 7f59544 9a541e5 4057e14 7968b20 1c359f1 9a541e5 4057e14 1c359f1 9a541e5 4057e14 7968b20 1c359f1 4057e14 1c359f1 9a541e5 1c359f1 7968b20 1c359f1 7968b20 1c359f1 7968b20 1c359f1 4057e14 9a541e5 b5221e6 9a541e5 b5221e6 9a541e5 b5221e6 9a541e5 b5221e6 9a541e5 b5221e6 9a541e5 b5221e6 9a541e5 b5221e6 9a541e5 b5221e6 9a541e5 b5221e6 4057e14 9a541e5 4057e14 9a541e5 7968b20 9a541e5 4057e14 9a541e5 4057e14 1c359f1 |
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 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
import gradio as gr
import pandas as pd
import numpy as np
import pickle
import nltk
from nltk import word_tokenize
from nltk.util import ngrams
from unidecode import unidecode
nltk.download('punkt')
import re
# leemos diccionario de entidades
diccionario = pd.read_csv('diccionario.csv', encoding = 'utf-8-sig', usecols = ['Entidad', 'Categoria'])
diccionario = diccionario.dropna()
diccionario = diccionario[diccionario['Categoria'] != 'Año']
diccionario = diccionario.iloc[1:]
all_dicts = diccionario.apply(lambda x: {x['Entidad']: x['Categoria']}, axis = 1)
# formateamos diccionario
entities_dict = {}
for i in all_dicts:
entities_dict.update(i)
def f_remove_accents(old: str):
'''
Función que limpia acentos de las letras.
old: texto a limpiar (str)
'''
new = re.sub(r'[àáâãäå]', 'a', old)
new = re.sub(r'[èéêë]', 'e', new)
new = re.sub(r'[ìíîï]', 'i', new)
new = re.sub(r'[òóôõö]', 'o', new)
new = re.sub(r'[ùúûü]', 'u', new)
return new
def predict(text: str, goal = ''):
output_sernac, output_sernac_categories, output_other, output_objective = np.nan, np.nan, np.nan, np.nan
diccionario = entities_dict.copy()
tokens = word_tokenize(text, language = 'spanish')
tokens_lower = [f_remove_accents(token.lower()) for token in tokens] # tokens en minuscula
dict_tokens = {tokens_lower[i]: tokens[i] for i in range(len(tokens))}
dict_keys = {f_remove_accents(key.lower()): key for key in diccionario.keys()}
# Evaluar el grado de ngramas en texto
ngram_range = 5 # rango de ngramas a evaluar
nmin = 1 # numero minimo de ngramas presente en el texto
grams_detected = {}
for i in range(2, ngram_range + 1):
n_grams = [' '.join(ngram) for ngram in list(nltk.ngrams(tokens_lower, i))]
intersection = list(set(n_grams) & set(dict_keys.keys()))
if len(intersection) > 0:
nmin = i
grams_detected.update({nmin: intersection})
sep = '%$·'
tmp_text = ' '.join(tokens_lower)
for i in range(5, 1, -1):
try:
# obtener todos los ngramas de nivel "i"
for j in range(len(grams_detected[i])):
entity = grams_detected[i][j]
tokens_entity = tuple(word_tokenize(entity))
ngrams = list(nltk.ngrams(tmp_text.split(' '), i))
tmp_list = [(f'{i}{sep}{j}',) if ngram == tokens_entity else ngram for ngram in ngrams]
pos_list = [key for key, value in dict(enumerate(tmp_list)).items() if f'{i}{sep}{j}' in value[0]]
exclude_list = [value + k for value in pos_list for k in range(1, i)]
tmp_list = [value for key, value in dict(enumerate(tmp_list)).items() if key not in exclude_list]
tmp_text = ' '.join([i[0] for i in tmp_list] + [token for token in tmp_text.split(' ')[-i+1:] if token not in tokens_entity])
except KeyError: # en caso de que no existan ngramas de nivel "i", pass
pass
labeled_tokens = []
# si hay solo entidades de largo 1, devuelvo oracion etiquetada token a token
if nmin < 2:
for token in tokens_lower:
labeled_tokens.append((dict_tokens[token], diccionario[dict_keys[token]]) if token in dict_keys.keys() else (token, None))
# si hay entidades de largo 2 o mas, devuelvo texto etiquetado con ngramas
else:
tmp_text = ' '.join(tmp_text.split()) # texto sin espacios
tmp_tokens = tmp_text.split()
for token in tmp_tokens:
if sep in token:
level, pos = token.split(sep)
encoded_token = grams_detected[int(level)][int(pos)]
labeled_tokens.append((encoded_token, diccionario[dict_keys[encoded_token]]))
elif token in dict_keys.keys():
#labeled_tokens.append((dict_tokens[token], diccionario[dict_keys[token]]))
labeled_tokens.append((token, diccionario[dict_keys[token]]))
else:
labeled_tokens.append((token, None))
# CLASSIFICATION
input = np.array([text, goal], ndmin = 2)
# SERNAC CLASSIFICATION
with open('sernac_model.pkl', 'rb') as model:
clf = pickle.load(model)
labels = [label for label in clf.classes_]
probas = clf.predict_proba(input)
sernac_probas = {labels[i]: float(probas[0][i]) for i in range(probas.shape[1])}
sernac_categories, other_categories = {}, {}
if clf.predict(input) == 'SERNAC':
# SERNAC CATEGORIES CLASSIFICATION
with open('sernac_categories_model.pkl', 'rb') as model:
clf = pickle.load(model)
labels = [label for label in clf.classes_]
probas = clf.predict_proba(input)
sernac_categories = {labels[i]: float(probas[0][i]) for i in range(probas.shape[1])}
else:
# OTHER CATEGORIES CLASSIFICATION
with open('other_categories_model.pkl', 'rb') as model:
clf = pickle.load(model)
labels = [label for label in clf.classes_]
probas = clf.predict_proba(input)
other_categories = {labels[i]: float(probas[0][i]) for i in range(probas.shape[1])}
objective_categories = {}
if goal != '':
with open('objective_model.pkl', 'rb') as model:
clf = pickle.load(model)
labels = [label for label in clf.classes_]
probas = clf.predict_proba(input)
objective_categories = {labels[i]: float(probas[0][i]) for i in range(probas.shape[1])}
# RETURN
return labeled_tokens, sernac_probas, sernac_categories, other_categories, objective_categories
# DEMO
demo = gr.Interface(
predict,
inputs = [gr.Textbox(placeholder = "Ingresa el reclamo acá", label = 'Reclamo'), gr.Textbox(placeholder = "Ingresa el objetivo acá (opcional)", label = 'Objetivo')],
outputs = [gr.Highlightedtext(label = 'Entidades detectadas'),
gr.outputs.Label(label = 'Clasificación SERNAC'),
gr.outputs.Label(label = 'Clasificación categorías SERNAC'),
gr.outputs.Label(label = 'Clasificación categorías No SERNAC'),
gr.outputs.Label(label = 'Clasificación objetivo')],
examples=[
['este septiembre iremos manejando a tEmUco en un tóyòtA para pasar las fiestas patrias', 'ir a temuco'],
['no puedo, tengo que ir desde san pedro hasta la reina y luego hasta san pedro de la paz', ''],
['Buenas tardes, hace unas semanas compre un suzuki swift a derco de santiago, llevaba 2 semanas y la caja de cambios se echó a perder. Tengo asegurado el auto con BCI, pero aun no obtengo respuesta.', 'exijo una explicación!'],
['Tengo un toyota urban cruiser 1.3 año 2010 el cual consume mucho aceite y nunca me han respondido si tiene alguna solución o garantía me gustaría que fueran más concretas las respuestas gracias', 'Obtener una solucion Que reparación hay que hacer o si tiene garantía?'],
['Mi auto del año presenta Falla de motor y sensores siendo que lo compre nuevo 0km y tiene recién 5400kms.. Es un Peugeot 2008 gti... El servicio es como las pelotas.. Me mandaron a un servicio técnico en Calama que estaba cerrado', '']
],
title = 'Demo ML'
)
demo.launch() |