Fundación Universitaria Konrad Lorenz
Docente: Viviana Márquez vivianam.penama@konradlorenz.edu.co
Clase #5: Marzo 11, 2021
Codeshare: https://codeshare.io/2BNvnL
Tokenización (Analizador léxico) es el proceso de convertir una secuencia de caracteres en una secuencia de tokens (componentes léxicos)
Léxico: Conjunto de palabras que conforma un determinado lecto. (Ósea, el vocabulario)
import re
texto = "¡Hola! ¿Cómo estás? Este es mi número: 555-777-888"
texto = texto.lower() # Minúscula
texto = re.sub(r"[\W\d]", " ", texto) # Dejar sólo letras
texto = texto.strip()
texto = texto.split() # Tokenizar
texto
# ¿Problemas en la instalación?
import nltk
nltk.download('stopwords') # Esta línea se corre sólo la primera vez
from nltk.corpus import stopwords
stopwords_sp = stopwords.words('spanish')
texto = [palabra for palabra in texto if palabra not in stopwords_sp]
texto
Stemming es el proceso de remover los sufijos para reducir una palabra a su raíz para que todas sus variantes sean representadas de la misma manera.
Los algoritmos más populares son:
Aunque muchas veces el proceso de stemming lingüísticamente no produce la forma correcta base de la palabra, se usa frecuentemente en los motores de busqueda para traer los resultados relevantes.
from nltk.stem.snowball import SnowballStemmer
englishStemmer = SnowballStemmer("english")
spanishStemmer = SnowballStemmer("spanish")
englishStemmer.stem("car")
englishStemmer.stem("cars")
spanishStemmer.stem("cantar")
spanishStemmer.stem("cantamos")
Nuestro texto
texto
texto_stem = []
for palabra in texto:
raiz = spanishStemmer.stem(palabra)
texto_stem.append(raiz)
texto_stem
Lematización es el proceso de hallar el lema de una palabra (representante de todas las formas de una misma palabra).
En lingüística, el lema es una unidad autónoma constituyente del léxico de un idioma.
import nltk
from nltk.stem import WordNetLemmatizer
nltk.download('wordnet') # Sólo se corre la primera vez
lemmatizer = WordNetLemmatizer()
lemmatizer.lemmatize("dancing", pos='v')
englishStemmer.stem('dancing')
• El stemming funciona con palabras sin conocer su contexto y es por eso que la raíz tiene una precisión menor, pero, es más rápida que la lematización.
• La lematización devuelve una palabra real.
• Si no importa el nivel de precisión y todo lo que necesitas es velocidad el stemming es mejor.
Sustantivo: Jessica
Adjetivo: Bella
Artículo: La
Pronombre: Ella
Verbo: Cantar
Adverbio: Rápidamente
Interjección: ¡Ay!
Preposición: Entre
Conjunción: y
Instalar librerias:
pip install spacy
python -m spacy download es_core_news_sm
import es_core_news_sm
nlp = es_core_news_sm.load()
doc = nlp("¡Hola! ¿Cómo estás? Este es mi número 314-1592. ¡Vamos a bailar porque es juernes!")
[(palabra.text, palabra.pos_) for palabra in doc]
from spacy import displacy
displacy.render(doc, style="dep", jupyter=True, options = {'distance': 200})
Herramientas generales de limpieza de texto
Herramientas específicas de pre-procesamiento de texto en NLP
Ejemplo: Imágenes
Una imagen es representada en un computador en la forma de una matriz donde cada $celda[i,j]$ representa el píxel $i,j$ de la imagen.
De manera similar, un video es una colección de fotogramas, donde cada fotograma es una imágen. Por lo tanto, cualquier video puede ser representado como una colección de matrices.
(Des)afortunadamente, representar texto de manera numérica no es tan sencillo.
%%time
#Libraries
import sys
import numpy as np
import re
#Useful functions
def load_glove(filename):
dic = {}
with open(filename) as f:
for line in f:
vec = line.split()
dic[vec[0]]= np.array(vec[1:], dtype=float)
return dic
def analogies(gloves, x, y, z, n):
dif_1 = gloves[x] - gloves[y]
distances=[]
for key,val in gloves.items():
if z!=key:
dif_2 = gloves[z]-gloves[key]
distances.append((np.linalg.norm(dif_1-dif_2),key))
distances.sort()
return [d[1] for d in distances[0:n]]
gloves = load_glove("../archivos/glove.6B.300d.txt")
def print_analogy():
print("Enter a word or 'x:y as z:'")
cmd = input("> ")
while cmd!=None:
try:
match = re.search(r'(\w+):(\w+) as (\w+):', cmd)
x = match.group(1).lower()
y = match.group(2).lower()
z = match.group(3).lower()
words = analogies(gloves, x, y, z, 5)
print("%s is to %s as %s is to {%s}" % (x,y,z,' '.join(words)))
cmd = input("> ")
except:
print("Bye mis cielas!")
break
print_analogy()
Imaginemos que todas las palabras y sus significados viven en un espacio de altas dimensiones. Nosotros lo llamáremos espacio semántico vectorial
Cada dimensión en el espacio semántico vectorial representa algún aspecto del significado de la palabra
Los conceptos y las palabras que significan cosas similares deben vivir cerca en este espacio
Corpus lingüístico: Conjunto amplio y estructurado de ejemplos reales de uso de la lengua.
Mapear cada palabra en el vocabulario del corpus de texto a una identificación única
import pandas as pd
import numpy as np
corpus = {'D1': 'perro muerde hombre',
'D2': 'hombre muerde perro',
'D3': 'perro come carne',
'D4': 'hombre come comida'}
corpus = pd.DataFrame.from_dict(corpus, orient='index', columns=['texto'])
corpus
# Obtener el vocabulario
vocabulario = corpus['texto'].str.cat(sep=" ")
vocabulario = set(vocabulario.split())
vocabulario = [(palabra,i) for i,palabra in enumerate(vocabulario)]
print(vocabulario)
# One-Hot Encoding
vocab_onehot = np.array([[0]*len(vocabulario)]*len(vocabulario))
for palabra,i in vocabulario:
vocab_onehot[i,i] = 1
# print(f"Palabra: {palabra}")
# print(f"One-hot encoding: {vocab_onehot[i,:]}")
# print()
vocab_onehot = pd.DataFrame(vocab_onehot)
vocab_onehot.columns = [palabra[0] for palabra in vocabulario]
vocab_onehot.index = [palabra[0] for palabra in vocabulario]
vocab_onehot
def one_hot_encoder(frase):
frase_onehot = []
for palabra in frase.split():
frase_onehot.append(vocab_onehot[palabra].tolist())
print(frase_onehot)
one_hot_encoder("perro muerde hombre perro")
print(vocabulario) # sigue siendo el mismo
def bow(frase):
frase_bow = [0]*len(vocabulario)
for palabra,i in vocabulario:
if palabra in frase.split():
frase_bow[i] = 1
print(frase_bow)
bow("perro muerde hombre")
bow("perro muerde hombre")
one_hot_encoder("perro muerde hombre")
np.sum(np.array([[0, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 1]]),0)
from sklearn.feature_extraction.text import CountVectorizer
count_vect = CountVectorizer(binary=True)
bow_rep = count_vect.fit_transform(corpus.texto.values)
print("Vocabulario: ", count_vect.vocabulary_)
# print(corpus.iloc[0])
# print(bow_rep[0].toarray())
corpus['bow'] = [row for row in bow_rep.toarray()]
corpus
Si no nos importa la frecuencia, binary=True
ej = ["perro y perro son amigos perros"]
temp = count_vect.transform(ej)
print(count_vect.vocabulary_)
temp.toarray()
Método bastante usado en la industria
corpus
count_vect = CountVectorizer(ngram_range=(1,2))
bow_rep = count_vect.fit_transform(corpus.texto.values)
print("Vocabulario: ", count_vect.vocabulary_)
print("Representación bow 'perro muerde hombre'", bow_rep[0].toarray())
Modo:
Proyecto:
Ideas para conseguir datos:
Taller # 4: Representación vectorial de textos (Parte 1)
Fecha de entrega: Marzo 18, 2021. (Antes del inicio de la próxima clase)