¡Esto es exactamente lo que hacen los Word Embeddings! 🎉
Bloque 2: La Hipótesis Distribucional
“You Shall Know a Word by the Company It Keeps”
J.R. Firth (1957):“You shall know a word by the company it keeps.”
La hipótesis distribucional establece que:
Las palabras que aparecen en contextos similares tienden a tener significados similares.
Ejemplo
“El gato se subió al árbol”
“El perro se subió al sofá”
“Mi gato come pescado”
“Mi perro come carne”
Observación
“gato” y “perro” aparecen en contextos muy similares:
Después de “El”, “Mi”
Antes de “se subió”, “come”
Con palabras como “come”, “duerme”
→ Deben tener significados relacionados 🐱🐶
De la Intuición a los Números
¿Cómo convertimos esta idea en vectores?
Enfoque clásico: Matriz de co-ocurrencia
Construir una matriz \(M\) donde \(M_{ij}\) = cuántas veces la palabra \(i\) aparece cerca de la palabra \(j\).
gato
perro
come
árbol
el
5
4
0
2
come
3
3
0
0
grande
1
2
0
1
Problema
La matriz sigue siendo enorme (\(|V| \times |V|\))
Muy dispersa
Necesitamos comprimir esta información
. . .
Solución: Aprender vectores densos
En vez de usar la matriz directamente, aprender vectores de baja dimensión que predigan los patrones de co-ocurrencia.
→ ¡Esto es Word2Vec! 🚀
Bloque 3: Word2Vec — La Idea Central
Word2Vec (Mikolov et al., 2013)
La idea clave
En vez de contar co-ocurrencias, entrenar una red neuronal para predecir palabras a partir de su contexto (o viceversa).
Los pesos aprendidos de la red neuronal son los word embeddings.
Dos arquitecturas
CBOW (Continuous Bag of Words)
Predice la palabra central a partir del contexto
Skip-gram
Predice el contexto a partir de la palabra central
Dato Histórico
Tomáš Mikolov publicó Word2Vec en 2013 mientras trabajaba en Google. El paper “Efficient Estimation of Word Representations in Vector Space” revolucionó el NLP y marcó el inicio de la era de los embeddings.
Ventana de Contexto
Antes de ver las arquitecturas, necesitamos definir la ventana de contexto\(c\):
Ejemplo con \(c = 2\):
“El gato come pescado fresco”
Rol
Palabras
Contexto izquierdo
“El”, “gato”
Palabra central
“come”
Contexto derecho
“pescado”, “fresco”
La ventana se desliza por todo el corpus generando pares de entrenamiento:
Palabra central
Contexto (\(c = 2\))
El
gato, come
gato
El, come, pescado
come
El, gato, pescado, fresco
pescado
gato, come, fresco
fresco
come, pescado
Bloque 4: CBOW — Continuous Bag of Words
Arquitectura CBOW
Objetivo: Predecir la palabra central dado su contexto.
Code
flowchart LR subgraph Entrada ["Contexto (c=2)"] w1["El"] w2["gato"] w3["pescado"] w4["fresco"] end subgraph Proyección ["Capa de Proyección"] avg["Promedio de<br>embeddings"] end subgraph Salida ["Capa de Salida"] pred["Softmax<br>P(w|contexto)"] end w1 --> avg w2 --> avg w3 --> avg w4 --> avg avg --> pred pred --> target["come ✓"]
flowchart LR
subgraph Entrada ["Contexto (c=2)"]
w1["El"]
w2["gato"]
w3["pescado"]
w4["fresco"]
end
subgraph Proyección ["Capa de Proyección"]
avg["Promedio de<br>embeddings"]
end
subgraph Salida ["Capa de Salida"]
pred["Softmax<br>P(w|contexto)"]
end
w1 --> avg
w2 --> avg
w3 --> avg
w4 --> avg
avg --> pred
pred --> target["come ✓"]
CBOW: Paso a Paso
1. Buscar embeddings
Cada palabra del contexto se convierte en un vector de dimensión \(d\):
La red tiene dos matrices de pesos: \(W \in \mathbb{R}^{|V| \times d}\) (embeddings de entrada) y \(W' \in \mathbb{R}^{d \times |V|}\) (embeddings de salida). Generalmente usamos \(W\) como nuestros word embeddings finales.
CBOW: Función de Pérdida
El objetivo es maximizar la probabilidad de predecir la palabra correcta:
La similitud coseno mide el ángulo entre vectores, ignorando la magnitud. Es más robusta porque vectores de palabras frecuentes tienden a tener mayor norma.
¿Qué Capturan las Dimensiones?
Cada dimensión del embedding captura un aspecto semántico latente:
Dimensiones interpretables (hipotéticas)
Dim.
Concepto
rey
reina
gato
23
Realeza
0.9
0.8
0.0
47
Género (M→F)
-0.7
0.6
0.1
89
Animal
0.1
0.1
0.9
112
Tamaño
0.5
0.3
-0.3
Realidad
Las dimensiones no son directamente interpretables
Son combinaciones complejas de muchos conceptos
Pero las relaciones entre vectores sí capturan semántica real
Esto es similar a los componentes principales en PCA (¡lo veremos en S3!)
Bloque 8: Hiperparámetros de Word2Vec
Hiperparámetros Clave
Dimensión del embedding (\(d\))
Valor
Uso
50-100
Tareas simples, corpus pequeños
200-300
Uso general ✅
500+
Corpus muy grandes
Tamaño de ventana (\(c\))
Valor
Captura
2-5
Relaciones sintácticas (similares en gramática)
5-10
Relaciones semánticas (similares en significado)
Negative samples (\(k\))
Valor
Uso
2-5
Corpus grandes
5-20
Corpus pequeños ✅
Otros
Parámetro
Típico
Learning rate (\(\alpha\))
0.025 → 0.0001
Épocas
5-15
Min count
5 (ignorar palabras con fewer occurrences)
Subsampling
\(t = 10^{-5}\)
Subsampling de palabras frecuentes
Palabras como “el”, “de”, “que” no aportan mucha información contextual. Word2Vec las descarta con probabilidad \(P_{\text{discard}}(w) = 1 - \sqrt{\frac{t}{f(w)}}\).
import numpy as np# Vector de una palabravec_gato = modelo.wv["gato"]print(f"Vector de 'gato' (primeros 10 dims):\n{vec_gato[:10].round(3)}")print(f"Norma: {np.linalg.norm(vec_gato):.3f}")
# Palabras más similaresprint("\nPalabras más similares a 'gato':")for palabra, sim in modelo.wv.most_similar("gato", topn=5):print(f" {palabra:15s}{sim:.4f}")
Palabras más similares a 'gato':
perro 0.9059
el 0.9030
juega 0.8972
la 0.8891
come 0.8813
Similitud entre Pares
# Pares de comparaciónpares = [ ("gato", "perro"), ("niño", "niña"), ("come", "bebe"), ("gato", "come"), ("grande", "pequeño"),]print("Similitud coseno entre pares:")print("-"*40)for w1, w2 in pares: sim = modelo.wv.similarity(w1, w2) barra ="█"*int(abs(sim) *20)print(f" ({w1:10s}, {w2:10s}): {sim:+.4f}{barra}")
Con un corpus tan pequeño los resultados no serán perfectos, pero ya se empiezan a ver patrones: “gato” y “perro” deberían tener similitud alta por sus contextos compartidos.
Aritmética de Vectores
# Analogía: niño - niña + gato ≈ ?try: resultado = modelo.wv.most_similar( positive=["niño", "gato"], negative=["niña"], topn=3 )print("niño - niña + gato ≈ ?")for palabra, sim in resultado:print(f" {palabra:15s}{sim:.4f}")exceptKeyErroras e:print(f"Palabra no encontrada: {e}")print()# Palabra que no encajatry: raro = modelo.wv.doesnt_match(["gato", "perro", "manzana"])print(f"¿Cuál no encaja en [gato, perro, manzana]? → '{raro}'")exceptException:print("Vocabulario insuficiente para doesnt_match")
niño - niña + gato ≈ ?
el 0.7896
la 0.7587
perro 0.7540
¿Cuál no encaja en [gato, perro, manzana]? → 'manzana'
Usando Embeddings Pre-entrenados
En la práctica, es común usar embeddings pre-entrenados en corpus muy grandes:
import gensim.downloader as api# Descargar Word2Vec pre-entrenado en Google News (1.5GB)# ¡Esto toma varios minutos y mucha RAM!modelo_google = api.load("word2vec-google-news-300")# Ahora sí vemos la magiaprint(modelo_google.most_similar("king"))# [('kings', 0.71), ('queen', 0.65), ('prince', 0.63), ...]# Analogía: king - man + woman ≈ queenresultado = modelo_google.most_similar( positive=["king", "woman"], negative=["man"], topn=1)print(resultado) # [('queen', 0.71)]
❌ Un vector por palabra: “banco” (financiero) = “banco” (mueble)
❌ No captura el orden de las palabras
❌ Ventana de contexto fija
❌ Palabras OOV (fuera del vocabulario)
❌ Puede codificar sesgos sociales
Sesgo en Word Embeddings
Word2Vec entrenado en texto de internet puede aprender: \(\vec{v}_{\text{doctor}} - \vec{v}_{\text{hombre}} + \vec{v}_{\text{mujer}} \approx \vec{v}_{\text{enfermera}}\). Esto refleja sesgos de los datos, no la realidad. Lo exploraremos en Semana 18 (Ética en NLP).
Lecturas Recomendadas
Papers originales
Mikolov et al. (2013). Efficient Estimation of Word Representations in Vector Space.arXiv:1301.3781
Mikolov et al. (2013). Distributed Representations of Words and Phrases and their Compositionality.NIPS 2013