Word embeddings

Estoy fascinado con word embeddings.

En NLP y Machine Learning, las word embeddings son representaciones vectoriales de palabras que permiten a las computadoras comprender mejor el significado y contexto del texto. Imaginate representar geométricamente el contexto y significado de una frase.

Los word embeddings se generan utilizando técnicas de aprendizaje no supervisado, estos algoritmos utilizan grandes cantidades de datos de texto para aprender las representaciones vectoriales de las palabras, incluso hay una muy buena librería open source para generar embeddings de texto e imagenes. Tambien podes usar GPT-3 para usar sus embeddings y los contextos que aprendió.

Una propiedad interesante de las word embeddings es que se pueden explorar geométricamente en el espacio vectorial. Al utilizar operaciones matemáticas en estos vectores, podemos explorar las relaciones entre palabras e incluso descubrir nuevas relaciones que pueden no ser inmediatamente evidentes. Por ejemplo, al restar la representación vectorial de "hombre" a "rey" y agregar la representación vectorial de "mujer", podemos obtener un nuevo vector que está muy cerca de la representación vectorial de "reina" 🤯.

Un ejemplo concreto de similaridad

Supongamos que tenes un listado de FAQs y queres armar un buscador que dado un texto ingresado por el usuario muestre las FAQs mas relevantes calculando la distancia geometrica del texto con las preguntas que estan en el listado:

%%capture
!pip install -U sentence-transformers

from sentence_transformers import SentenceTransformer

# nuestro listado de preguntas frecuentes
faqs = [
  "¿Cuáles son las posiciones actuales en la NBA?",
  "¿Quién ganó la Copa del Mundo en 2018?",
  "¿Qué es el aprendizaje supervisado en el aprendizaje automático?",
  "¿Cuál jugador de la NBA tiene el promedio más alto de puntos por partido de todos los tiempos?",
  "¿Cuál es el formato del torneo de la Copa del Mundo?",
  "¿Qué es el aprendizaje no supervisado en el aprendizaje automático?",
  "¿Quién es el máximo anotador de todos los tiempos en la NBA?",
  "¿Qué país ha ganado la mayoría de los campeonatos de la Copa del Mundo?",
  "¿Qué es el aprendizaje por refuerzo en el aprendizaje automático?",
  "¿Quién ganó el campeonato de la NBA en 2020?",
  "¿Cuál es la mayor cantidad de goles anotados en un solo torneo de la Copa del Mundo?",
  "¿Qué es una red neuronal en el aprendizaje automático?",
  "¿Cuáles son las reglas de tiempo extra en la NBA?",
  "¿Qué equipos participan en la Liga de Campeones de la UEFA?",
  "¿Qué es el aprendizaje profundo en el aprendizaje automático?",
  "¿Quién es el actual MVP de la NBA?",
  "¿Cuál es el país anfitrión de la próxima Copa del Mundo?",
  "¿Qué es el modelo de regresión lineal en el aprendizaje automático?",
  "¿Quién es el jugador más alto en la NBA?",
  "¿Qué país ganó el primer campeonato de la Copa del Mundo?",
  "¿Qué es el modelo de árbol de decisión en el aprendizaje automático?",
  "¿Quién es el jugador más bajo en la NBA?",
  "¿Cuál es la mayor diferencia de puntos en un partido de la NBA?",
  "¿Qué equipo ha ganado más campeonatos de la NBA en la historia?",
  "¿Quién es el actual goleador líder en la Copa del Mundo?",
  "¿Qué es el modelo de clasificación en el aprendizaje automático?",
  "¿Cuál es el jugador más valioso en la NBA?",
  "¿Cuál es la mayor asistencia en un partido de la NBA?",
  "¿Qué es la precisión en el aprendizaje automático?",
  "Cuanta RAM tiene una mac?"
]

model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')
faqs_embeddings = model.encode(faqs)
print(faqs_embeddings)

Lo que se imprimira seran los word embeddings o representaciones en vectores de las preguntas.

[[-0.00951469  0.03625762 -0.06713071 ...  0.06920597  0.12715752
  -0.06214901]
 [-0.037561    0.08685268  0.00472029 ... -0.0136954  -0.0175276
  -0.03501687]
 [-0.00665751 -0.03037143 -0.06498507 ...  0.04875717  0.00592298
  -0.04371774]
 ...
 [ 0.05778816  0.03107005 -0.08002586 ...  0.06526564  0.07141099
  -0.0628504 ]
 [-0.02005051  0.01298255 -0.03917712 ...  0.05991555 -0.01678353
  -0.04403912]
 [-0.0277065   0.02095841 -0.08323775 ...  0.0221856  -0.02101326
   0.00769026]]

Ahora, vamos a generar el vector de un texto (embedding) y ver cuales son las preguntas frequentes del listado mas relacionadas.

Usamos semantic_search para calcular la distancia entre nuestro vector y los embeddings de las preguntas frecuentes. Le pedimos las top 3:

# semantic_search se usa para calcular la distancia entre los vectores
from sentence_transformers.util import semantic_search

# generamos el embedding de la pregunta
query_embeddings = model.encode("Quien es el mas bajo de la nba?")

# usamos `semantic_search` para calcular la distancia entre nuestro vector de pregunta y los embeddings de las preguntas frecuentes. Le pedimos las top 3
hits = semantic_search(query_embeddings, faqs_embeddings, top_k=3)

print([faqs[hits[0][i]['corpus_id']] for i in range(len(hits[0]))])

> ['¿Quién es el jugador más bajo en la NBA?',
   '¿Quién es el jugador más alto en la NBA?',
   '¿Cuál es el jugador más valioso en la NBA?']

Me parece increible poder representar palabras, contextos y significados en el espacio vectorial para despues poder hacer operaciones geometricas con esa representacion.