File size: 3,122 Bytes
7f59544
4057e14
 
 
1c359f1
 
 
 
e85a261
7f59544
1c359f1
 
 
 
7f59544
1c359f1
 
 
 
7f59544
1c359f1
4057e14
1c359f1
 
 
4057e14
1c359f1
 
4057e14
1c359f1
 
 
 
 
 
 
 
 
 
4057e14
1c359f1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4057e14
 
 
1c359f1
 
4057e14
1c359f1
 
 
 
4057e14
1c359f1
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
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')

# leemos diccionario de entidades
diccionario = pd.read_excel('diccionario.xlsx')
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 predict(text):

  diccionario = entities_dict.copy()
  tokens = word_tokenize(text, language = 'spanish')
  tokens_lower = [unidecode(token.lower()) for token in tokens] # tokens en minuscula

  dict_tokens = {tokens_lower[i]: tokens[i] for i in range(len(tokens))}
  dict_keys = {unidecode(key.lower()): key for key in diccionario.keys()}

  # presencia de ngrams
  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 = text
  for i in range(5, 1, -1):
    try:
      # obtener todos los ngramas de nivel "i"
      for j in range(len(grams_detected[i])):
        tmp_text = tmp_text.replace(grams_detected[i][j], f'{i}{sep}{j}')
    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))

    return labeled_tokens

  # si hay entidades de largo 2 o mas, devuelvo solo las entidades etiquetadas
  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]]))
      else:
        labeled_tokens.append((token, None))
      
    return labeled_tokens

demo = gr.Interface(
    predict,
    gr.Textbox(placeholder = "Ingresa el texto acá", label = 'Texto'),
    gr.Highlightedtext(label = 'Etiquetas'),
    examples=[
        ['hola!! estoy en santiago manejando en mi ferrari que compré en marzo'],
        ['este septiembre iremos manejando a temuco en un toyota para pasar las fiestas patrias'],
        ['no puedo, tengo que irme desde san pedro de la paz hasta santiago'],
        ['no puedo, tengo que irme desde san pedro hasta la reina y luego hasta san pedro de la paz']
    ],
    title = 'Detección de Entidades'
)

demo.launch()