Saltar a contenido

Incrustaciones de Palabras (Word Embeddings)

Navegación en esta sección

Capítulos anteriores: - Redes Neuronales Recurrentes (RNN) — arquitectura RNN, GRU, LSTM, BRNN y Deep RNN.

Estás en Incrustaciones de Palabras (Word Embeddings) (representación semántica de palabras, transferencia en NLP y razonamiento por analogía).

1 El problema de la representación one-hot

Hemos visto que las RNN procesan secuencias de palabras, pero no hemos explicado cómo se representan esas palabras numéricamente. La representación más simple es el vector one-hot: un vector de ceros con un único \(1\) en la posición correspondiente al índice de la palabra en el vocabulario.

Por ejemplo, con un vocabulario de 10.000 palabras, “hombre” (índice 5391) y “mujer” (índice 9853) se representan como:

\[ e_{\text{hombre}} = \begin{bmatrix} 0 \\ 0 \\ \vdots \\ 1 \\ \vdots \\ 0 \end{bmatrix} \leftarrow \text{pos. 5391}, \qquad e_{\text{mujer}} = \begin{bmatrix} 0 \\ 0 \\ \vdots \\ 1 \\ \vdots \\ 0 \end{bmatrix} \leftarrow \text{pos. 9853} \]

El problema fundamental: el producto escalar entre dos vectores one-hot distintos siempre es cero, y la distancia euclídea entre ellos siempre es la misma. Para el modelo, “hombre” y “mujer” son tan diferentes como “hombre” y “naranja”. No hay forma de que el modelo generalice el conocimiento entre palabras similares.

Si el modelo aprende que “jugo de naranja” es una bebida plausible, no tiene forma de saber que “jugo de manzana” también lo es, porque “naranja” y “manzana” son vectores ortogonales sin relación alguna.

2 Incrustaciones de palabras (Word Embeddings)

La solución es representar cada palabra con un vector denso de características (típicamente 100 a 300 dimensiones) que capture su significado semántico. A este vector se le llama incrustación de palabra (word embedding).

Por ejemplo, con vectores de 4 dimensiones simplificadas para animales:

Palabra Mamífero Tamaño Doméstico Terrestre
perro \(+1\) \(-0.3\) \(+1\) \(+1\)
gato \(+1\) \(-0.5\) \(+1\) \(+1\)
león \(+1\) \(+0.8\) \(-1\) \(+1\)
elefante \(+1\) \(+1.0\) \(-1\) \(+1\)
ballena \(+1\) \(+1.0\) \(-1\) \(-1\)
pez \(-1\) \(-0.4\) \(-1\) \(-1\)

Observa cómo los valores capturan relaciones semánticas reales: perro y gato son casi idénticos (ambos mamíferos pequeños y domésticos), león y elefante comparten tamaño grande y vida salvaje, y ballena y pez comparten el hábitat acuático aunque una es mamífera y el otro no.

En un espacio de 300 dimensiones reales, estas capturan relaciones mucho más ricas: sinonimia, contexto gramatical, categoría semántica, etc.

Los vectores de 300 dimensiones se pueden proyectar a 2D mediante algoritmos como t-SNE (t-distributed Stochastic Neighbor Embedding). En estas visualizaciones, las palabras con significados similares se agrupan naturalmente:

  • Los animales domésticos (“perro”, “gato”) forman un clúster.
  • Los grandes mamíferos salvajes (“león”, “elefante”) forman otro.
  • Los animales acuáticos (“ballena”, “pez”) forman otro.

Esto demuestra que el modelo captura relaciones semánticas de forma automática, sin programación manual.

3 Aprendizaje por transferencia en NLP

Las incrustaciones de palabras son una de las aplicaciones más exitosas del aprendizaje por transferencia en procesamiento de lenguaje natural.

3.1 El problema de la generalización

Supongamos que queremos construir un clasificador de sentimientos para reseñas de restaurantes. Entrenamos el modelo con miles de reseñas que contienen palabras como “delicioso”, “excelente”, “malo”, “terrible”. El modelo aprende que “delicioso” y “excelente” indican sentimiento positivo.

Pero si en una reseña nueva aparece “el tartare de caballo estuvo exquisito”, el modelo tiene un problema: nunca vio “caballo” ni “tartare” en su conjunto de entrenamiento. Para el modelo, “caballo” es una palabra desconocida sin relación con “delicioso” o “malo”.

3.2 La solución: transferencia de incrustaciones

  1. Pre-entrenamiento masivo: Se entrena un algoritmo de incrustaciones en miles de millones de palabras de texto sin etiquetar (Wikipedia, Internet). El algoritmo descubre que “caballo” es semánticamente similar a “ternera” y “cerdo” (animales/comida), y que “tartare” se parece a “carpaccio” y ” filete” (preparaciones de carne).

  2. Transferencia a la tarea específica: En lugar de representar cada palabra como un vector one-hot (donde “caballo” y “ternera” son ortogonales), usamos las incrustaciones pre-entrenadas como entrada de la red neuronal. Ahora el modelo puede generalizar: si aprendió que “ternera deliciosa” es positivo, inferirá que “caballo delicioso” también lo es.

  3. Ajuste fino opcional (Fine-tuning): Si el conjunto de datos etiquetado es grande, se pueden seguir entrenando las incrustaciones para adaptarlas a la tarea. Si es pequeño, se mantienen fijas para evitar sobreajuste.

Incrustaciones vs. codificaciones faciales

En reconocimiento facial, la red genera una codificación para cualquier imagen de rostro nueva. En NLP tradicional, las incrustaciones son vectores fijos para cada palabra del vocabulario. Sin embargo, los modelos modernos (como BERT o GPT) generan incrustaciones contextuales que varían según la frase, similar al reconocimiento facial.

4 Razonamiento por analogía

Una de las propiedades más sorprendentes de las incrustaciones de palabras es su capacidad para resolver analogías mediante operaciones vectoriales simples.

4.1 La analogía de género

La analogía “hombre es a mujer como rey es a ¿qué?” se resuelve con aritmética de vectores:

\[ E_{\text{hombre}} - E_{\text{mujer}} \approx E_{\text{rey}} - E_{\text{reina}} \]

El vector \(E_{\text{hombre}} - E_{\text{mujer}}\) representa la dirección de “género” en el espacio de incrustaciones. Esta misma dirección diferencia “rey” de “reina”.

Para encontrar la palabra que falta:

\[ E_w \approx E_{\text{rey}} - E_{\text{hombre}} + E_{\text{mujer}} \]

El algoritmo busca la palabra cuya incrustación esté más cerca de este vector resultado. Sorprendentemente, la palabra más cercana suele ser “reina”.

4.2 Otras relaciones que se aprenden automáticamente

Este método no se limita al género. Las incrustaciones capturan múltiples relaciones:

Relación Ejemplo
Capital → País Ottawa : Canadá :: Nairobi : Kenia
Moneda → País Yen : Japón :: Rublo : Rusia
Grados de adjetivos grande : el más grande :: alto : el más alto
Verbos conjugados caminar : caminó :: correr : corrió

Estos patrones se descubren de forma autónoma al procesar grandes cantidades de texto, sin ninguna supervisión.

5 Similitud de coseno

Para medir qué tan similares son dos palabras en el espacio de incrustaciones, se utiliza la similitud de coseno (cosine similarity):

\[ \text{similitud}(u, v) = \frac{u^T v}{\|u\| \cdot \|v\|} = \frac{\sum_{i=1}^{d} u_i \cdot v_i}{\sqrt{\sum_{i=1}^{d} u_i^2} \cdot \sqrt{\sum_{i=1}^{d} v_i^2}} \]
Valor Interpretación
\(\approx 1\) Vectores casi idénticos (palabras muy similares)
\(\approx 0\) Vectores ortogonales (sin relación)
\(\approx -1\) Vectores opuestos (significados contrarios)

La similitud de coseno mide la dirección de los vectores, ignorando su magnitud. Esto es importante porque dos palabras pueden tener vectores de distinta longitud pero apuntar en la misma dirección semántica.

5.1 Cuándo falla la distancia euclídea: el tamaño del documento

La distancia euclídea mide la longitud del segmento recto entre dos vectores. Con vectores de conteo, eso puede engañar: un documento largo puede quedar lejos de otro corto aunque hablen del mismo tema. Mini-ejemplo con dos palabras, enfermedad y huevos:

\[ v_{\text{alimentos}}=[2,6], \quad v_{\text{agricultura}}=[20,60], \quad v_{\text{historia}}=[25,35] \]

En distancia euclídea, \(d(\text{agricultura}, \text{historia}) \approx 25.5\) es menor que \(d(\text{alimentos}, \text{agricultura}) \approx 56.9\), así que diría que agricultura se parece más a historia. Pero alimentos y agricultura tienen la misma proporción (\(1\):\(3\)): mismo tema con distinta longitud. En coseno, \(\text{similitud}(\text{alimentos}, \text{agricultura})=1\) y \(\text{similitud}(\text{agricultura}, \text{historia}) \approx 0.956\). El coseno acierta porque compara dirección y proporción, no magnitud. Por eso, cuando la norma arrastra frecuencia o longitud de documento, el coseno suele ser mejor primera opción.

==================================================
ANALOGÍA: hombre - mujer + rey ≈ ?
==================================================
Vector objetivo: [ 1.    0.96 -0.01  0.  ]
  similitud con 'reina': 0.9997
  similitud con 'naranja': 0.0053
  similitud con 'manzana': 0.0001

==================================================
SIMILITUD ENTRE PARES
==================================================
  similitud('hombre', 'mujer'): -0.9983
  similitud('rey', 'reina'): -0.0407
  similitud('manzana', 'naranja'): 0.9998
  similitud('hombre', 'manzana'): 0.0354

6 La matriz de incrustación (\(E\))

Todas las incrustaciones de palabras del vocabulario se almacenan en una única matriz de incrustación \(E\) de dimensiones \(d \times |V|\), donde \(d\) es la dimensión de los vectores (típicamente 300) y \(|V|\) es el tamaño del vocabulario (típicamente 10.000 a 100.000 palabras).

Cada columna de \(E\) es el vector de incrustación de una palabra. Para obtener la incrustación de la palabra con índice \(k\), se multiplica \(E\) por su vector one-hot \(o_k\):

\[ e_k = E \cdot o_k \]

Esta multiplicación simplemente selecciona la columna \(k\) de la matriz \(E\), ya que \(o_k\) tiene un \(1\) en la posición \(k\) y ceros en el resto.

6.1 Ejemplo concreto

Para visualizarlo, supongamos un vocabulario reducido de 5 palabras con vectores de \(d=3\) dimensiones:

\[ E = \begin{bmatrix} | & | & | & | & | \\ e_{\text{gato}} & e_{\text{perro}} & e_{\text{manzana}} & e_{\text{naranja}} & e_{\text{casa}} \\ | & | & | & | & | \end{bmatrix} = \begin{bmatrix} 0.2 & 0.3 & -0.1 & -0.2 & 0.8 \\ 0.1 & 0.2 & 0.9 & 0.8 & -0.5 \\ -0.3 & -0.4 & 0.1 & 0.2 & 0.6 \end{bmatrix} \]

Cada columna es el vector de una palabra:

  • \(e_{\text{gato}} = [0.2,\; 0.1,\; -0.3]^T\)
  • \(e_{\text{perro}} = [0.3,\; 0.2,\; -0.4]^T\)
  • \(e_{\text{manzana}} = [-0.1,\; 0.9,\; 0.1]^T\)

Para obtener el vector de “gato”, su representación one-hot es \(o_{\text{gato}} = [1,\; 0,\; 0,\; 0,\; 0]^T\) (solo un \(1\) en la posición 1):

\[ E \cdot o_{\text{gato}} = \begin{bmatrix} 0.2 & 0.3 & -0.1 & -0.2 & 0.8 \\ 0.1 & 0.2 & 0.9 & 0.8 & -0.5 \\ -0.3 & -0.4 & 0.1 & 0.2 & 0.6 \end{bmatrix} \begin{bmatrix} 1 \\ 0 \\ 0 \\ 0 \\ 0 \end{bmatrix} = \begin{bmatrix} 0.2 \\ 0.1 \\ -0.3 \end{bmatrix} \]

La multiplicación simplemente selecciona la columna 1. El vector one-hot actúa como un puntero: “dame la columna \(k\)”. No hay cálculo real, solo extracción.

7 Cómo se aprenden las incrustaciones

La matriz \(E\) no se programa manualmente: se aprende junto con los demás pesos de la red neuronal mediante retropropagación. El proceso es:

  1. Inicialización aleatoria: \(E\) se inicializa con valores aleatorios pequeños. Al inicio, los vectores no significan nada.
  2. Forward pass: Las palabras del contexto se convierten en one-hot, se multiplican por \(E\) para obtener sus incrustaciones, y se pasan por la red.
  3. Cálculo del error: Se compara la predicción con la palabra real usando entropía cruzada.
  4. Backpropagation: El gradiente se propaga hacia atrás a través de la matriz \(E\), ajustando los vectores de incrustación.
  5. Resultado: Palabras que aparecen en contextos similares (como “naranja” y “manzana”) terminan con vectores cercanos en el espacio de incrustaciones.

7.1 Word2Vec: Skip-gram

El modelo Word2Vec (Mikolov et al., 2013) en su variante Skip-gram simplifica el problema: dada una palabra de contexto \(C\), predice una palabra objetivo \(T\) que aparece cerca en el texto.

7.1.1 Generación de pares de entrenamiento

En la frase “el gato negro persigue rápidamente al ratón pequeño”, con una ventana de contexto de 2 palabras, la palabra central “persigue” ve sus 2 vecinos a la izquierda y 2 a la derecha:

  el   gato   negro   persigue   rápidamente   al   ratón   pequeño
            ← 2  ─  persigue  ─ 2 →
Palabra central (\(C\)) Palabra del contexto (\(T\))
persigue gato
persigue negro
persigue rápidamente
persigue al

“el” y “ratón” quedan fuera de la ventana — el modelo no los usa para entrenar con “persigue”. Si ampliamos la ventana a 3 palabras:

  el   gato   negro   persigue   rápidamente   al   ratón   pequeño
         ← 3  ─  persigue  ─ 3 →
Palabra central (\(C\)) Palabra del contexto (\(T\))
persigue el
persigue gato
persigue negro
persigue rápidamente
persigue al
persigue ratón

Ahora incluye “el” y “ratón”, pero sigue sin ver “pequeño”. Con ventanas más grandes (5-10 palabras), el modelo capta relaciones más lejanas, pero el coste computacional crece.

7.1.2 Paso 1: Inicialización de la matriz \(E\)

Antes de entrenar, necesitamos una matriz \(E\) donde guardar los vectores. Se inicializa con valores aleatorios — al principio no significan nada:

Vocabulario (|V| = 8 palabras): [el, gato, negro, persigue, rápidamente, al, ratón, pequeño]

Matriz E (d=3 × |V|=8), valores aleatorios:

         el    gato   negro  persigue  rápid.   al   ratón  pequeño
       ┌──────┬──────┬──────┬────────┬───────┬──────┬──────┬───────┐
       │ 0.02 │-0.15 │ 0.08 │  0.12  │-0.03  │ 0.11 │-0.07 │ 0.05  │
       │-0.09 │ 0.04 │-0.11 │  0.06  │ 0.09  │-0.02 │ 0.14 │-0.08  │
       │ 0.07 │ 0.10 │-0.05 │ -0.08  │ 0.02  │ 0.06 │-0.09 │ 0.11  │
       └──────┴──────┴──────┴────────┴───────┴──────┴──────┴───────┘

Cada columna es el vector de una palabra. Al inicio son números sin sentido. El entrenamiento los ajustará hasta que capturen significado.

7.1.3 Paso 2: Arquitectura de la red

La red tiene solo dos operaciones — multiplicar por \(E\) y luego por una capa Softmax:

                        ┌─────────────────────────────────────────────────────────┐
                        │  Matriz E (lo que aprendemos)                           │
                        │  Cada columna = vector de una palabra                   │
                        │                                                         │
                        │       gato   negro   persigue   rápidamente   al  ...   │
                        │     ┌─────┬───────┬──────────┬────────────┬────┐       │
                        │     │ 0.2 │  0.1  │   0.2    │    0.3     │ 0.1│       │
                        │     │ 0.3 │  0.4  │   0.8    │    0.2     │ 0.5│       │
                        │     │-0.1 │ -0.2  │  -0.1    │   -0.4     │ 0.3│       │
                        │     └─────┴───────┴──────────┴────────────┴────┘       │
                        └─────────────────────────────────────────────────────────┘
                                              │
                                              ▼
Entrada (one-hot)         Capa oculta (embedding)           Salida (softmax)

  persigue = [0,0,0,1,0,0,0,0]  ──→  e = [0.2, 0.8, -0.1]  ──→  negro: 0.35
                                                                   rápidamente: 0.30
                                                                   gato: 0.15
                                                                   al: 0.10
                                                                   ...

Paso a paso con el par (persigue, negro):

  1. Entrada: One-hot de “persigue” = \([0,0,0,1,0,0,0,0]\) (dimensión \(|V|=8\)).
  2. Capa oculta: \(E \cdot o_{\text{persigue}} = e_{\text{persigue}} = [0.2, 0.8, -0.1]\) (dimensión \(d=3\)). Esta es la incrustación que aprendemos.
  3. Salida: Otra matriz \(W\) (dimensión \(|V| \times d\)) multiplica \(e_{\text{persigue}}\) y aplica Softmax → probabilidades de cada palabra del vocabulario.
  4. Error: La palabra real del contexto es “negro”. Comparamos la predicción con la distribución objetivo (1 para “negro”, 0 para el resto).
  5. Backpropagation: Ajustamos \(W\) y también \(E\) para que la próxima vez “negro” tenga mayor probabilidad.

Clave: Entrenamos con un par a la vez. Primero (persigue, negro), luego (persigue, rápidamente), etc. Cada par ajusta \(E\) un poco. Después de millones de pares, las incrustaciones convergen.

7.1.4 ¿De dónde salen los valores de \(E\)?

Los valores de \(E\) no se programan — se aprenden automáticamente:

  1. Inicio: \(E\) se inicializa con valores aleatorios (distribución normal pequeña, por ejemplo \(\mathcal{N}(0, 0.1)\)). Al principio, los vectores no significan nada.

  2. Entrenamiento: Con cada par de entrenamiento, el error se propaga hacia atrás y ajusta \(E\) un poco. Palabras que aparecen en contextos similares reciben gradientes similares, así que sus vectores convergen a valores parecidos.

  3. Resultado: Después de millones de pares, \(E\) contiene vectores que capturan relaciones semánticas. “Gato” y “perro” terminan cerca porque ambos aparecen en contextos similares (“mi X duerme”, “el X ladra”).

Los valores del diagrama (0.2, 0.8, -0.1…) son ejemplos ilustrativos — los valores reales se determinan por el entrenamiento.

7.1.5 ¿Para qué sirve la ventana de contexto?

La ventana es lo que genera los pares de entrenamiento. Sin ella, no sabríamos qué palabras están “cerca” unas de otras. El proceso completo es:

  1. Tomamos un corpus grande (Wikipedia, libros, Internet).
  2. Para cada palabra del texto, miramos sus vecinos dentro de la ventana.
  3. Creamos un par \((C, T)\) por cada vecino.
  4. Entrenamos la red con esos pares.

Ejemplo: En “el gato negro persigue rápidamente al ratón pequeño”, con ventana de 2:

Palabra central Vecinos (contexto) Pares generados
gato el, negro, persigue (gato, el), (gato, negro), (gato, persigue)
negro el, gato, persigue, rápidamente (negro, el), (negro, gato), (negro, persigue), (negro, rápidamente)
persigue gato, negro, rápidamente, al (persigue, gato), (persigue, negro), (persigue, rápidamente), (persigue, al)
… … …

Con un corpus de miles de millones de palabras, generamos miles de millones de pares. Cada par ajusta \(E\) un poco. Al final, palabras que aparecen en contextos similares (como “gato” y “perro”) terminan con vectores cercanos.

Problema: El Softmax requiere sumar sobre todo el vocabulario en el denominador, lo que es costoso para vocabularios grandes.

7.2 Muestreo negativo (Negative Sampling)

Para evitar el costoso Softmax, el muestreo negativo convierte el problema en clasificación binaria:

  • Ejemplo positivo: El par \((C, T)\) real del texto → etiqueta \(y = 1\).
  • Ejemplos negativos: Se seleccionan \(k\) palabras aleatorias del vocabulario y se emparejan con \(C\) → etiqueta \(y = 0\).

El modelo entrena un clasificador logístico binario para cada par, lo que es mucho más rápido que calcular el Softmax completo.

Muestreo de palabras negativas: Las palabras no se eligen completamente al azar, sino de una distribución modificada \(P(w_i) = f(w_i)^{3/4}\), donde \(f(w_i)\) es la frecuencia de la palabra. Esto reduce la probabilidad de seleccionar palabras muy comunes (“el”, “de”) y aumenta la de palabras raras.

7.3 El antecedente por conteo: matriz de co-ocurrencia

Antes de Word2Vec y GloVe hubo una idea más directa: contar compañías. Es la intuición de Firth: “conocerás una palabra por la compañía que mantiene”. Fijada una ventana de tamaño \(k\), se construye una matriz \(X\) donde \(X_{ij}\) cuenta cuántas veces aparece \(w_j\) a distancia menor o igual que \(k\) de \(w_i\). La fila \(i\) ya es un vector para \(w_i\), aunque disperso y de dimensión \(|V|\).

Mini-ejemplo con \(k=2\) y vocabulario \([\text{datos}, \text{simples}, \text{crudos}, \text{gustan}, \text{me}]\):

  1. datos simples crudos
  2. me gustan los datos simples

Para “datos”: “simples” aparece dos veces a distancia \(1\); “crudos” una vez a distancia \(2\); “gustan” una vez a distancia \(2\); “me” queda a distancia \(3\) y no cuenta. Por tanto:

\[ v_{\text{datos}} = [2, 1, 1, 0] \]

Estos vectores funcionan en corpus pequeños, pero crecen con \(|V|\) y son casi todo ceros. GloVe conserva esta misma señal de conteo global, usando \(\log(X_{ij})\), pero aprende vectores densos \(e_i\) de dimensión \(d \ll |V|\).

7.4 GloVe (Global Vectors)

El algoritmo GloVe (Pennington et al., 2014) utiliza estadísticas globales de co-ocurrencia. Construye una matriz \(X\) donde \(X_{ij}\) es el número de veces que la palabra \(j\) aparece en el contexto de la palabra \(i\).

La función de costo busca que el producto escalar \(\theta_i^T e_j\) aproxime \(\log(X_{ij})\):

\[ J = \sum_{i=1}^{|V|} \sum_{j=1}^{|V|} f(X_{ij}) \left( \theta_i^T e_j - \log X_{ij} \right)^2 \]

donde \(f(X_{ij})\) es una función de ponderación que evita que las palabras muy comunes dominen el entrenamiento.

7.5 Word2Vec: CBOW (la dirección contraria)

Skip-gram predice el contexto desde la palabra central. CBOW (Continuous Bag-of-Words, la otra variante de Word2Vec) hace exactamente lo inverso: predice la palabra central desde su contexto. Si dos palabras distintas aparecen rodeadas de contextos parecidos, el modelo les asignará vectores parecidos: en “El pequeño [algo] ladra”, el hueco lo pueden ocupar “perro”, “cachorro” o “sabueso”, así que las tres terminarán cerca en el espacio.

7.5.1 Ejemplos de entrenamiento

Con la misma frase de antes (“el gato negro persigue rápidamente al ratón pequeño”) y \(C = 2\) (dos vecinos por lado), cada ventana genera un solo ejemplo: todo el contexto junto predice el centro.

Contexto (4 palabras) Palabra central a predecir
el, gato, persigue, rápidamente negro
gato, negro, rápidamente, al persigue
negro, persigue, al, ratón rápidamente

Compáralo con Skip-gram: allí la misma ventana generaba 4 pares (uno por vecino); aquí genera 1 ejemplo con el contexto completo. Por eso CBOW entrena más rápido, pero diluye a las palabras raras dentro del promedio.

7.5.2 Arquitectura

La red es casi la misma que en Skip-gram, con una operación añadida: promediar los vectores del contexto.

Contexto (4 one-hots)              Promedio                Salida (softmax)

  gato    = [0,1,0,0,0,0,0,0]  ──→  e_gato    ──┐
  negro   = [0,0,1,0,0,0,0,0]  ──→  e_negro   ──┤
  rápid.  = [0,0,0,0,1,0,0,0]  ──→  e_ráp     ──┼──→  ē  ──→  W  ──→  persigue: 0.40
  al      = [0,0,0,0,0,1,0,0]  ──→  e_al      ──┘                          negro: 0.15
                                                                             ...

Paso a paso con el ejemplo (contexto → “persigue”):

  1. Entrada: los 4 one-hots del contexto (dimensión \(|V| = 8\) cada uno).
  2. Incrustaciones: cada one-hot se multiplica por \(E\) → 4 vectores de dimensión \(d\).
  3. Promedio: \(\bar{e} = (e_{\text{gato}} + e_{\text{negro}} + e_{\text{ráp}} + e_{\text{al}})/4\). Este vector medio representa “el contexto”; el orden de las palabras se pierde (de ahí bag-of-words: bolsa, no secuencia).
  4. Salida: \(W\) (dimensión \(|V| \times d\)) multiplica \(\bar{e}\) y aplica Softmax → probabilidades sobre el vocabulario.
  5. Error y backpropagation: se compara con la palabra real (“persigue”) con entropía cruzada y se ajustan \(W\) y \(E\). Como el error fluye a través del promedio, las 4 palabras del contexto actualizan sus vectores a la vez.

7.5.3 Skip-gram frente a CBOW

Aspecto Skip-gram CBOW
Dirección centro → contexto contexto → centro
Ejemplos por ventana \(2C\) (uno por vecino) \(1\) (contexto conjunto)
Velocidad de entrenamiento Más lento Más rápido
Palabras raras Mejor (cada par las ajusta) Peor (se diluyen en el promedio)
Palabras frecuentes Bien Muy bien

Nota

Aprendizaje auto-supervisado. Ni Skip-gram ni CBOW necesitan etiquetas humanas: el corpus se supervisa a sí mismo (la palabra central es la etiqueta). Por eso se puede entrenar con miles de millones de palabras de Wikipedia o Internet: los datos de entrenamiento y su supervisión vienen juntos en el propio texto.

7.6 FastText: subpalabras contra palabras desconocidas

Word2Vec y GloVe comparten un punto débil: cada palabra es una entrada atómica del vocabulario. Si en producción aparece una palabra jamás vista (“gatito”, una errata como “beutiful”, una conjugación rara), no hay vector para ella. Es el mismo problema del <UNK> visto en los capítulos de HMM y n-gramas.

FastText (Facebook, 2016) lo resuelve rompiendo cada palabra en n-gramas de caracteres. Con \(n = 3\), “gato” se representa por sus fragmentos más la palabra completa:

<ga, gat, ato, to>, <gato>

(los símbolos < y > marcan inicio y fin para distinguir prefijos y sufijos). El vector de la palabra es la suma de los vectores de sus fragmentos, entrenada con el objetivo Skip-gram habitual.

La magia aparece con lo desconocido: “gatito” nunca visto se descompone en <ga, gat, ati, tit, ito, to>, y comparte <ga, gat y to> con “gato”. Aunque la palabra sea nueva, sus piezas no lo son, así que hereda un vector razonable por similitud de fragmentos. Lo mismo vale para erratas y, muy importante en español, para la morfología: “correr”, “corriendo” y “corredor” comparten subpalabras y nacen cerca sin necesidad de stemming previo.

7.7 De dónde se extraen los embeddings finales

Un detalle que suele confundir: tras entrenar Word2Vec hay dos matrices (\(E\) de entrada y \(W\) de salida), luego ¿cuál contiene “los” embeddings? Las tres prácticas habituales son:

  1. Columnas de \(E\) (matriz de entrada): la opción estándar; cada columna es el vector de una palabra.
  2. Filas de \(W\) (matriz de salida): también válidas, capturan la palabra “como contexto”.
  3. Promedio de ambas: combina las dos visiones y suele funcionar ligeramente mejor.

En la práctica casi todos los modelos publicados usan la opción 1 sin más ceremonia.

8 Clasificación de sentimientos con incrustaciones

Las incrustaciones de palabras pre-entrenadas son especialmente útiles para clasificación de sentimientos cuando el conjunto de datos etiquetado es pequeño.

8.1 Enfoque simple: promedio de vectores

  1. Para cada palabra de la reseña, buscar su vector de incrustación pre-entrenado.
  2. Calcular el promedio de todos los vectores para obtener un único vector que representa la oración.
  3. Pasar este vector a un clasificador Softmax.

Debilidad: Ignora el orden de las palabras. “Carece completamente de buen gusto” se clasificaría como positiva por la palabra “bueno”.

8.2 Enfoque con RNN

Para capturar el orden y el contexto: 1. Las incrustaciones de cada palabra se introducen secuencialmente en una RNN. 2. El último estado oculto de la RNN captura el significado completo de la reseña. 3. Este vector se pasa a un clasificador Softmax.

La RNN puede entender matices como “carece de buen gusto”, que tienen un significado opuesto a la palabra “bueno” por sí sola.

9 Sesgo en las incrustaciones de palabras

Las incrustaciones entrenadas en corpus de texto masivo pueden heredar sesgos sociales presentes en el lenguaje humano. Por ejemplo:

  • \(E_{\text{hombre}} - E_{\text{mujer}} \approx E_{\text{rey}} - E_{\text{reina}}\) ✓ (relación neutral)
  • \(E_{\text{hombre}} - E_{\text{mujer}} \approx E_{\text{programador}} - E_{\text{ama de casa}}\) ✗ (sesgo de género)

9.1 Mitigación del sesgo (Bolukbasi et al., 2016)

  1. Identificar la dirección del sesgo: Promediar diferencias de pares de palabras definidos por el sesgo (ej. “él” - “ella”, “hombre” - “mujer”).
  2. Neutralizar palabras no definicionales: Para palabras como “doctor” o “programador” (que no tienen género intrínseco), eliminar el componente de sesgo proyectando sobre el subespacio no sesgado.
  3. Ecualizar pares definicionales: Para palabras como “abuela” / “abuelo”, asegurar que la única diferencia entre ellas sea la dirección de sesgo.