Embeddings: el significado como geometría
¿Cómo convierte una máquina el significado en distancias?
Lección completa
Si quieres:
Un cliente escribe «quiero mi dinero de vuelta», y el artículo correcto habla de «reembolso». No comparten ni una palabra. ¿Cómo puede una máquina ver que significan lo mismo?
Sin voz: la lección avanza sola con subtítulos.
La voz de esta lección está en preparación: por ahora avanza sola con subtítulos.
Modo revisiónComentar este pasoTerminé la lección
Qué lograrás
- Explicar por qué un vector denso y aprendido representa el significado mejor que una casilla por palabra (one-hot).
- Calcular la similitud coseno entre dos vectores e interpretar vecinos, mapas 2D y aritmética de significados, con sus límites.
- Reconocer cómo los sesgos del texto viajan al espacio de vectores y cómo evaluar una búsqueda semántica con casos propios.
Ideas clave
- Un embedding es un vector denso y aprendido: una fila de una tabla que se ajusta con los datos, en lugar de una casilla fija por palabra.
- Lo que aparece en contextos parecidos acaba con vectores parecidos: el significado se vuelve ángulo y distancia.
- La similitud coseno compara direcciones, no longitudes. Un mapa 2D es una proyección y pierde información: sirve para explorar, no para medir.
- La aritmética de significados es real pero frágil: hay que excluir las palabras de entrada y funciona mejor con relaciones limpias, como país y capital.
- Los vectores heredan los sesgos del texto. La búsqueda semántica rescata paráfrasis, y su calidad se mide con tus propios casos.
Lo que mucha gente cree
Creencia común «Rey − hombre + mujer = reina» demuestra que el modelo entiende qué es la realeza y qué es el género.
Lo correcto Es una regularidad geométrica real, pero frágil: solo sale excluyendo las palabras de entrada, falla con muchas relaciones, y los mismos vectores arrastran los sesgos del texto. Medir no es entender.
Compruébalo
Cuatro preguntas. Sin nota ni cuenta: sirven para ver si la idea quedó.
Por dentroPara quien quiere las fórmulas y el código. No hace falta para seguir el curso.
Un embedding es una fila de una matriz
Sea el tamaño del vocabulario y la dimensión de los vectores. La tabla es una matriz . La palabra de índice es el vector one-hot (un uno en la posición , ceros en el resto) y su embedding es
Multiplicar por un one-hot equivale a elegir una fila: es una capa lineal sin activación (lección 7) cuyos pesos se aprenden. Con y son de números. En la práctica no se multiplica: se consulta la fila. El mismo mecanismo abre los modelos de lenguaje: en GPT-2 pequeño la tabla es de millones de parámetros (lecciones 20 y 22).
Similitud coseno
Si los dos vectores tienen longitud 1, y : ordenar por coseno y ordenar por distancia euclídea da el mismo orden. Ejemplo: y dan , un ángulo de unos . Con ("perro" y "gato") el ángulo es .
¿De dónde salen los números?
Skip-gram (Mikolov et al., 2013) maximiza la probabilidad promedio de las palabras vecinas de cada palabra , con una ventana de tamaño :
Cada palabra tiene un vector de entrada (su embedding) y uno de salida . El denominador recorre todo el vocabulario, y por eso el artículo propone aproximaciones, como el muestreo negativo. GloVe (Pennington et al., 2014) ajusta en cambio
donde cuenta cuántas veces aparece cerca de en el corpus, y se entrena con AdaGrad. Dos caminos, una misma idea: las palabras que comparten contextos acaban con vectores parecidos.
La aritmética, paso a paso
La pregunta « es a como es a ...» se responde con
Con vectores de longitud 1, no depende de , así que esto equivale a maximizar . La exclusión no es un detalle: Linzen (2016) midió que, sin ella, la más cercana era en el 93 % de los casos y en el 5 %. En esta lección, con los 100 números de GloVe y eligiendo entre sus 400 000 palabras:
| Preguntas | Con exclusión | Sin exclusión | La más cercana era una de las 3 de entrada |
|---|---|---|---|
| Capital–país (342) | 80.1 % (274) | 68.1 % | 19.3 % |
| Género (90) | 85.6 % (77) | 55.6 % | 41.1 % |
Los pares los elegí yo y son relaciones limpias; el conjunto de Mikolov et al. (19 544 preguntas, 14 tipos, y solo cuenta la palabra exacta, no sinónimos) es más difícil: su mejor modelo llegó a 65.6 %. Con solo las 880 palabras de la lección el examen es mucho más fácil (94.4 % y 85.6 %): hay menos candidatos entre los que equivocarse. Linzen añade que el método mezcla la consistencia del desplazamiento con la estructura de vecindad: no mide solo «relaciones».
Cómo se mide el sesgo en la lección
Con = {mujer, niña, madre, esposa, hermana, hija} y = {hombre, niño, padre, esposo, hermano, hijo} (en inglés en los datos), el puntaje de una palabra es
Positivo es más cerca de lo femenino. Se usan conjuntos y no un par porque «man» tiene varios sentidos. Es una versión simplificada de las pruebas de asociación de Caliskan et al. (2017). Resultado con las 52 profesiones del vocabulario: de («boss») a («receptionist»); 26 objetos sin género (mesa, árbol, río…) quedan entre y . La correlación de Spearman con el puntaje «she» − «he» en GloVe completo es 0.91. El puntaje mezcla género con tema (en el texto, lo femenino aparece más junto a «vestido» o «jabón»): sirve para ver la pendiente, no para dar un veredicto sobre una persona. Si a cada vector se le resta su componente en (normalizado), el puntaje en ese eje vale 0 por construcción; aun así, adivinar si cada profesión estaba por encima o por debajo de la mediana del puntaje original, con el centroide más cercano por coseno y dejando una fuera cada vez, acierta 41 de 52 antes y 35 de 52 después (azar: 26). Es un experimento mínimo, con pocas palabras, en el espíritu del de Gonen y Goldberg (2019), quienes mostraron que los métodos para «desagregar» el sesgo en gran medida lo esconden, no lo quitan.
Búsqueda semántica
El promedio de un texto con palabras es ; se ordenan los documentos por . Comparar contra documentos cuesta por consulta, y con millones se usan índices aproximados. Los vectores de oraciones (Reimers y Gurevych, 2019) se calculan una sola vez por documento: encontrar el par más parecido entre 10 000 oraciones con BERT exige unos 50 millones de inferencias (unas 65 horas); con vectores de oraciones, unos 5 segundos. La tercera columna de la escena usa paraphrase-multilingual-MiniLM-L12-v2 (Apache-2.0, 384 dimensiones, más de 50 idiomas; Reimers y Gurevych, 2020), con promedio de los vectores de salida y coseno. Sus puntajes se calcularon fuera de línea para las 36 preguntas de prueba.
Con 36 preguntas, 19 aciertos son 52.8 % con un intervalo de Wilson al 95 % de 37 % a 68 %: un margen de unos ±15 puntos. Por eso la lección 34 insiste en el tamaño de la muestra.
En código
Con vectores de juguete (números inventados) se ve el mecanismo completo:
import numpy as np
# Tabla de embeddings de juguete: una fila por palabra, 3 números cada una (inventados; un modelo real usa cientos).
palabras = ["rey", "reina", "hombre", "mujer", "pan"]
E = np.array([
[4.0, 3.0, 1.0], # rey
[4.0, 0.5, -2.0], # reina
[4.0, 0.0, 1.0], # hombre
[4.0, 0.0, -1.0], # mujer
[0.0, 0.5, 3.0], # pan
])
E = E / np.linalg.norm(E, axis=1, keepdims=True) # longitud 1: el producto punto es el coseno
fila = {w: i for i, w in enumerate(palabras)}
def coseno(a, b):
return float(a @ b / (np.linalg.norm(a) * np.linalg.norm(b)))
def cercanas(v, excluir=()):
pares = [(w, round(coseno(v, E[i]), 2)) for w, i in fila.items() if w not in excluir]
return sorted(pares, key=lambda p: -p[1])[:3]
print(round(coseno(E[fila["rey"]], E[fila["reina"]]), 2)) # rey y reina
v = E[fila["rey"]] - E[fila["hombre"]] + E[fila["mujer"]] # rey - hombre + mujer
print(cercanas(v)) # sin excluir
print(cercanas(v, excluir=["rey", "hombre", "mujer"])) # excluyendo las tres de entrada
# 0.68
# [('rey', 0.89), ('reina', 0.87), ('mujer', 0.81)]
# [('reina', 0.87), ('pan', -0.18)]
Y con los vectores reales de GloVe (el archivo glove.6B.100d.txt sale de la página de Stanford, ver las fuentes; leerlo tarda unos segundos):
import numpy as np
palabras, filas = [], []
with open("glove.6B.100d.txt", encoding="utf8") as f:
for linea in f:
w, _, resto = linea.partition(" ")
palabras.append(w)
filas.append(np.asarray(resto.split(), dtype=np.float32))
E = np.stack(filas)
E /= np.linalg.norm(E, axis=1, keepdims=True) # longitud 1: el producto punto es el coseno
idx = {w: i for i, w in enumerate(palabras)}
def cercanas(v, k=5, excluir=()):
s = E @ (v / np.linalg.norm(v))
for w in excluir:
s[idx[w]] = -1
top = np.argsort(-s)[:k]
return [(palabras[i], round(float(s[i]), 2)) for i in top]
print(cercanas(E[idx["dog"]], 5, excluir=["dog"]))
v = E[idx["king"]] - E[idx["man"]] + E[idx["woman"]]
print(cercanas(v, 3))
print(cercanas(v, 3, excluir=["king", "man", "woman"]))
# [('cat', 0.88), ('dogs', 0.83), ('pet', 0.74), ('puppy', 0.72), ('horse', 0.71)]
# [('king', 0.84), ('queen', 0.77), ('monarch', 0.68)]
# [('queen', 0.77), ('monarch', 0.68), ('throne', 0.68)]
De dónde salen los datos de esta lección
Vectores: GloVe 6B de 100 dimensiones (Wikipedia 2014 y Gigaword 5, 6 mil millones de palabras, 400 000 de vocabulario, solo inglés), publicado por Stanford bajo la licencia Public Domain Dedication and License v1.0, que permite redistribuir. Se normalizan a longitud 1 y se guardan en 8 bits (error de coseno máximo 0.0095). El mapa es t-SNE (van der Maaten y Hinton, 2008) con perplejidad 20, métrica coseno y semilla 0: Wattenberg et al. (2016) advierten que en un t-SNE el tamaño de los grupos y la distancia entre ellos pueden no significar nada. Las 10 frases de soporte y las 36 preguntas de prueba las escribió el autor de la lección: son ilustrativas. Todo se regenera con los scripts de la carpeta de la lección (build-vectors.py, eval-search.py, eval-analogies.py, measure-data.py).
Lo que viene
Los vectores de esta lección son estáticos: una palabra, un vector. La atención (lección 21) y el transformer (lección 22) producen un vector distinto para cada palabra según la frase. La lección 15 pregunta si, además de representar lo que existe, se puede generar algo nuevo; la 18 une vectores de imágenes y de texto en un mismo espacio, y la 31 usa la búsqueda semántica para dar conocimiento propio a un modelo.
Lente de decisión
Qué significa esta idea si tu trabajo es decidir, no programar.
- Búsqueda semántica y bases vectoriales: cada documento se convierte en vector una vez y cada pregunta, al momento. Pregunta qué modelo de embeddings usan, cuántas dimensiones, en qué idiomas y con qué licencia: si cambia el modelo, hay que recalcular todo el índice.
- Mide la calidad con tus propios casos: unas decenas de preguntas reales, cada una con su documento correcto, y cuenta cuántas veces sale primero o entre los cinco primeros. Con treinta y seis casos el margen es de unos quince puntos; con más, la comparación se afina.
- Los embeddings heredan los sesgos del texto. Si ordenan personas (currículos, candidatos, clientes), pide cómo se midió el sesgo con datos de ese uso; «lo corregimos» no basta, porque quitar una dirección suele esconderlo, no eliminarlo.
- Señales de alerta: un mapa 2D presentado como prueba de calidad, una demo con preguntas elegidas a mano, la frase «entiende el significado» sin resultados medidos, o un modelo en inglés aplicado a textos en español sin comprobarlo.
Términos de la lección
- Embedding Vector de números, aprendido de los datos, que representa algo (una palabra, una frase, una imagen) de modo que lo parecido quede cerca. Cada palabra tiene una fila en una tabla de embeddings.
- Similitud coseno Coseno del ángulo entre dos vectores: 1 si apuntan igual, 0 si son perpendiculares, −1 si se oponen. Ignora la longitud y mide solo la dirección.
- Espacio vectorial Espacio cuyos puntos son vectores. En un espacio de embeddings, la distancia o el ángulo entre dos puntos mide cuánto se parecen sus significados.
- Búsqueda semántica Búsqueda por significado: la consulta y los documentos se convierten en vectores y se devuelven los documentos más cercanos, aunque no compartan palabras.
- Vector Lista ordenada de números. En aprendizaje automático, cada ejemplo llega al modelo como un vector.
- Característica (feature) Una medida de un ejemplo expresada como número: el número de enlaces de un correo, el brillo de un píxel. Las características de un ejemplo forman su vector.
- Capa Grupo de neuronas que reciben las mismas entradas y calculan a la vez. Una red es una cadena de capas: entrada, una o más ocultas, y salida.
- Peso (w) En un modelo lineal, el número que multiplica a la entrada: la pendiente de la recta. Indica cuánto sube la predicción por cada unidad que aumenta la entrada.
- Parámetro Cada uno de los números que un modelo ajusta al entrenarse y en los que guarda lo aprendido.
- Descenso del gradiente Método que ajusta los pesos paso a paso, siempre en contra de la pendiente del error (el gradiente), hasta llegar a un fondo.
- Datos de entrenamiento Ejemplos, cada uno con su respuesta correcta, con los que un modelo ajusta sus parámetros.
Transcripción completa
Fuentes
- Mikolov, T., Chen, K., Corrado, G., Dean, J. (2013). Efficient Estimation of Word Representations in Vector Space
- Mikolov, T., Sutskever, I., Chen, K., Corrado, G., Dean, J. (2013). Distributed Representations of Words and Phrases and their Compositionality
- Mikolov, T., Yih, W., Zweig, G. (2013). Linguistic Regularities in Continuous Space Word Representations
- Pennington, J., Socher, R., Manning, C. D. (2014). GloVe: Global Vectors for Word Representation (artículo y datos, licencia PDDL v1.0)
- van der Maaten, L., Hinton, G. (2008). Visualizing Data using t-SNE
- Wattenberg, M., Viégas, F., Johnson, I. (2016). How to Use t-SNE Effectively
- Linzen, T. (2016). Issues in evaluating semantic spaces using word analogies
- Bolukbasi, T., Chang, K.-W., Zou, J., Saligrama, V., Kalai, A. (2016). Man is to Computer Programmer as Woman is to Homemaker? Debiasing Word Embeddings
- Caliskan, A., Bryson, J. J., Narayanan, A. (2017). Semantics derived automatically from language corpora contain human-like biases
- Gonen, H., Goldberg, Y. (2019). Lipstick on a Pig: Debiasing Methods Cover up Systematic Gender Biases in Word Embeddings But do not Remove Them
- Reimers, N., Gurevych, I. (2019). Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks
- Reimers, N., Gurevych, I. (2020). Making Monolingual Sentence Embeddings Multilingual using Knowledge Distillation
ComentariosConversación pública de esta lección: dudas, datos por revisar, ideas.
Los comentarios viven en GitHub Discussions, en el repositorio público del curso; para escribir se necesita una cuenta de GitHub. Se cargan desde giscus.app al abrir esta sección. Las personas que revisan el curso los leen, y si un cambio se acepta, se aplica en los dos idiomas. Abrir el hilo en GitHub