Introducción a Word2vec (skip gram model)

Motivación de Word2vec

Los sistemas de procesamiento de imágenes o de audio trabajan con conjuntos de datos multidimensionales muy ricos en información que se codifican como vectores. Estos vectores tendrán, por ejemplo, las intensidades de los pixeles en los distintos colores, o coeficientes espectrales para audio. Sin embargo, cuando se trata de procesamiento de lenguaje natural, las palabras se tratan como símbolos individuales y discretos. Así por ejemplo, podríamos representar “sol” con id343 y “luna” con id432. Las codificaciones son arbitrarias y no proporcionan información sobre las relaciones que pueden existir en entre las distintas entidades. Peor aún, la representación como ids discretos tiene como consecuencia una dispersión de los datos importante por lo que implica que los entrenamientos necesitan más datos para ofrecer buenos modelos.

Una representación de las palabras alternativa son los Vector space models (VSMs). Los VSM pretenden representar las palabras como un vector en un espacio multidimensional de forma que las palabras similares o relacionadas se encuentren representadas por puntos cercanos. De esta forma capturamos información semántica, puesto que, por ejemplo, palabras como “rojo”, “negro” y “blanco” se encontrarán en una misma zona de ese espacio multidimensional y lo mismo pasaría con palabras como “leon”, “tigre”, “leopardo”.

Un modelo particularmente eficiente desde el punto de vista computacional es Word2vec. Es model se encuentra disponible de dos formas: Continuous Bag-of-Words (CBOW) o el modelo Skip-Gram. Skip-Gram suele funcionar mejor que CBOW.

En particular, con modelo “Skip-Gram” lo que se quiere decir es: dado un conjunto de frases (también llamado corpus) el modelo analiza las palabras de cada sentencia y trata de usar cada palabra para predecir que palabras serán vecinas. Por ejemplo, a la palabra “Caperucita” le seguirá “Roja” con más probabilidad que cualquier otra palabra.

El modelo

Para empezar, se utiliza el modelo más sencillo que te puedas imaginar: una red neuronal con una única capa oculta.

Dado el vocabulario generado con las palabras del corpus, el objetivo es entrenar la red neuronal con las sentencias del corpus para que, para una palabra dada, nos diga la probabilidad de que cada palabra del vocabulario sea vecina de la primera.

Una vez entrenada la red, nos quedaremos con los pesos de la capa oculta, ya que estos son los “word vectors” que estamos intentando aprender (de ahí el nombre “word 2 vector”, convertir una palabra en un vector).

Window size” o ventana es el parámetro que determina el número de palabras de cada contexto.

Para entrenar la red neuronal usaremos pares de palabras encontradas en los datos de entrenamiento. La selección de los pares de palabras dependerá del tamaño de la ventana. Por ejemplo, con un tamaño de dos sería como sigue:

La entrada de la red neuronal será una palabra representada como un one-hot vector, es decir, un vector con tantas posiciones como tamaño tenga el vocabulario. Por ejemplo, si queremos representar la palabra “sol” de un vocabulario 10.000 palabras, usaremos un vector de de esta dimensión con cero en todas las posiciones menos la correspondiente a la palabra “sol” que tendrá un uno.

La salida de la red neuronal será otro vector de las mismas 10.000 posiciones que representará las probabilidades de cada una de las palabras sean vecinas de la palabra representada en la entrada.

Representación de la arquitectura de la red neuronal

Como características reseñables, la capa oculta no tiene función de activación y en cambio la de salida aplica una función softmax. La justificación vendrá más adelante.

Aunque en el entrenamiento, tanto la entrada y como el valor esperado son one hot vectors, la salida es en realidad una distribución de probabilidades.

La capa oculta

En el diagrama anterior, se está entrenado vectores de palabras con 300 características. La matriz de representación tendrá por tanto 10.000 filas (una por palabra) y 300 columnas (una por neurona).

El objetivo de todo el ejercicio es aprender los pesos de esta capa oculta, ya que:

  1. La representación on-hot es un vector de 1x10.000.
  2. Si multiplicamos el vector (1x10.000) por la matriz (10.000x300), entonces:
  3. Acabamos con una representación de 1x300 que efectivamente consiste en la selección de la fila correspondiente al único uno presente en la representación one-hot

Igual esta ilustración lo aclara un poco más:

¿Por qué 300 características? Este número particular es el que Google uso en su modelo publicado basado en el data set de Google News (lo puedes encontrar aquí). El hiperparámetro del modelo, este número 300, puedes ajustarlo para tu aplicación para buscar optimizar los resultados.

La capa de salida

Para que la capa de salida cumpla con lo especificado anteriormente tenemos que usar un clasificador Softmax, que consigue que todos los valores estén entre 0 y 1 y que la suma de todos los valores sea 1, es decir, que sea una distribución de probabilidades.

Word2vec con TensorFlow

A continuación, encontrarás un planteamiento de alto nivel sobre como implementar Word2vec con TensorFlow.

Construir el grafo

Como de lo que se trata es de obtener los pesos de la capa oculta, los embeddings, los definimos:

Para la salida, definimos los pesos y bias:

Suponiendo que ya tenemos todas las palabras del texto representado con un entero que señalaría la posición del 1 en un vector one-hot de la explicación anterior. Este entero también es la posición de la palabra en el diccionario que se construye a partir del corpus.

Para entrenar, tenemos dos entradas, los enteros de la palabra origen y los enteros de las palabras objetivo, las que estarían cerca. Definimos los placeholders:

Ahora hay que seleccionar de los embeddings la fila correspondiente. TensorFlow proporciona una utilidad para ello por lo que resulta muy sencillo:

Una vez que tenemos la fila seleccionada, hay que intentar predecir la palabra objetivo. Para entrenar se podría utilizar la función de coste cross-entropy. El problema aquí es que la normalización de las probabilidades, que se hace con una función softmax, tiene un coste computacional cuando la capa de salida es muy grande, como es el caso.

Para lidiar con este problema, Word2vec usa una técnica llamada noise-contrastive estimation (NCE) que es computacionalmente más eficiente. Aquí puedes encontrar un paper que introduce el modelo.

TensorFlow vuelve a proporcionar utilidades para estas tareas:

Y configuramos el optimizador del Gradient Descent para el entrenamiento:

Entrenando el modelo

Para entrenar el modelo solo hay que usar feed_dic para meter los datos en los placeholder e invocar a tf.Session.run con los nuevos datos:

Puedes ver el ejemplo completo de TensorFlow aquí:

https://github.com/tensorflow/tensorflow/blob/r1.8/tensorflow/examples/tutorials/word2vec/word2vec_basic.py

Visualizando lo elementos

Si visualizamos los resultados usando t-SNE podemos ver como las palabras relacionadas aparecen cerca:

Referencias

Word2Vec Tutorial — The Skip-Gram Model [http://mccormickml.com/2016/04/19/word2vec-tutorial-the-skip-gram-model/]

Tutorial de Word2vec de TensorFlow [https://www.tensorflow.org/tutorials/word2vec]

Distributed Representations of Words and Phrases and their Compositionality [http://papers.nips.cc/paper/5021-distributed-representations-of-words-and-phrases-and-their-compositionality.pdf]

Gonzalo Ruiz de Villa

Written by

Ingeniero, Google Developer Expert y cofundador de Adesis Netlife y Kenobi Ventures. CTO en GFT España

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade