martes, 16 de octubre de 2012

Modelos de Lenguaje: Bigramas


La probabilidad de que la palabra wi venga después de la palabra wi-1 en una oración viene dada por la cantidad de veces que aparece la dupla: "wi-1 wi" en un corpus, dividida por el total de veces que aparece la palabra wi-1.

                P(wi | wi-1) = count (wi-1,wi)
                                        count (wi-1)

Veamos un ejemplo esclarecedor:

Supongamos que este es nuestro corpus:

<s>En un plato de trigo</s>
<s>tres tristes tigres</s>
<s>comen trigo</s>



Los símbolos <s> y </s> son caracteres metalingüísticos que indican comienzo y fin de oración respectivamente, de esta forma podemos evaluar la probabilidad de una palabra de estar al principio o al fin de una sentencia.

P(en | <s>) = 1 / 3 = 0,33
P(un | en) = 1 / 1 = 1
P(plato | un) = 1 / 1 = 1
P( trigo | de ) = 1/1 = 1
P( </s> | trigo) = 2/2 = 1
P( </s> | tigres) = 1/1 = 1
P(tres | <s>) = 1 / 3 = 0,33
P(en | <s>) = 1 / 3 = 0,33
P( de| plato ) = 1/1 = 1

¿ Cuál es la probabilidad de la sentencia: "P(<s>En un plato de trigo</s>)"?

P(<s>En un plato de trigo</s>) = P(en | <s>)  x P(un | en) x  P(plato | un) x   P( de| plato ) x  P( trigo | de ) x  P( </s> | trigo)  = 0,33 x  1 x  1 x  1 x  1 x 1 = 0,33

Cuando se trabaja con un corpus mucho más grande las probabilidades son más chicas y corremos riesgo de que se produzca undeflow, por lo cual es siempre recomendable trabajar en el espacio logarítmico.

= Log(P(en | <s>))  + Log(P(un | en)) + Log(P(plato | un)) +Log(P( de| plato )) + Log(P( trigo | de )) + Log(P( </s> | trigo))
= Log(0,33) + Log(1) + Log(1) + Log(1)  + Log(1) + Log(1)
= -0,481      +    0       +      0    +  0          +   0       +   0   =   -0,481

  => 10 ^ -0,481 = 0,33 (en caso de que necesitemos recuperar el valor de la probabilidad)


¿Qué tan bueno es el modelo?

Una forma de probar nuestro modelo, es utilizando un conjunto de prueba distinto al conjunto de entrenamiento o corpus utilizado para calcular la probabilidad de cada bigrama. Sobre este nuevo conjunto calcularemos la perplejidad (Perplexity en ingles), la perplejidad es una medida utilizada en la teoría de la información para saber "cuanto se sorprende" nuestro modelo en otro conjunto de textos (en este caso).

Se calcula con la siguiente formula:









NOTA: si en vez de bigramas usamos trigramas el denominador será P(wi | wi-2, wi-1), en términos generales para N-Gramas:  P(wi | w1....wi-1).

Es la probabilidad que tiene el conjunto de prueba, normalizada por la cantidad de palabras.
Disminuir la perplejidad de un modelo es igual a maximizar su probabilidad total.

Menor perplejidad  = Mejor modelo

Un corpus de entrenamiento de 38 millones de palabras, con un conjunto de prueba de 1.5 millones dio los siguientes valores de perplejidad para los siguientes modelos:

orden de N-gramaUnigramaBigramaTrigrama
Perplejidad962170109

De todas formas no siempre es una buena forma de medir un modelo, es más acertada cuando el conjunto de entrenamiento y el conjunto de prueba se parecen.


Problemas con este modelo

¿ Cuál es la probabilidad de la sentencia: "P(<s>En un plato de tigres</s>)"? Teniendo en cuenta el corpus anterior:

P(<s>En un plato de tigres</s>) = P(en | <s>)  x P(un | en) x P(plato | un) P( de| plato ) P( tigres| de ) P( </s> | tigres)  = 0,33 x 1 x 1 x 1 x 0 x 1 = 0

Como no existe el bigrama: "de tigres" en el corpus, su probabilidad de ocurrencia es cero y por lo tanto es una sentencia imposible. Obviamente si utilizamos un corpus más grande vamos a reducir la cantidad de "sentencias imposibles", pero aún así siempre podremos encontrar oraciones perfectamente validas cuya probabilidad (según este modelo) sea cero.

Este problema lo solucionaremos utilizando la estimación Add-One también llamada: Laplace smoothing. El concepto es muy sencillo: a cada bigrama que no aparece nunca, le ponemos uno (como si hubiese aparecido al menos una vez) y a todos los demás le sumamos uno.

La probabilidad ahora de un bigrama se calcula con la siguiente formula:


    P(wi | wi-1) = count (wi-1,wi) +1
                            count (wi-1) +|V|

donde |V| es el tamaño del vocabulario, es decir la cantidad de palabras distintas (incluyendo los símbolos <s> y </s>) ya que sumaremos tantos unos como palabras distintas haya (por cada palabra wi-1)

Pongamos el corpus anterior como tabla, en donde cada palabra la comienzo de la fila es la primera del bigrama y la palabra en cada columna es la segunda:

wi-1\ wi <s> en un plato de trigo tres tristes tigres comen </s>
<s> 1+1 1+1 0+1 0+1 0+1 0+1 1+1 0+1 0+1 1+1 0+1
en 0+1 0+1 1+1 0+1 0+1 0+1 0+1 0+1 0+1 0+1 0+1
un 0+1 0+1 0+1 1+1 0+1 0+1 0+1 0+1 0+1 0+1 0+1
plato 0+1 0+1 0+1 0+1 1+1 0+1 0+1 0+1 0+1 0+1 0+1
de 0+1 0+1 0+1 0+1 0+1 1+1 0+1 0+1 0+1 0+1 0+1
trigo 0+1 0+1 0+1 0+1 0+1 0+1 0+1 0+1 0+1 0+1 2+1
tres 0+1 0+1 0+1 0+1 0+1 0+1 0+1 1+1 0+1 0+1 0+1
tristes 0+1 0+1 0+1 0+1 0+1 0+1 0+1 0+1 1+1 0+1 0+1
tigres 0+1 0+1 0+1 0+1 0+1 0+1 0+1 0+1 0+1 0+1 1+1
comen 0+1 0+1 0+1 0+1 0+1 1+1 0+1 0+1 0+1 0+1 0+1
 </s> 0+1 0+1 0+1 0+1 0+1 0+1 0+1 0+1 0+1 0+1 1+1

acá se ve claramente la cantidad de bigramas posibles que tenían 0 apariciones y ahora tendrán 1.En total son: 121 bigramas posibles (en verdad <s><s> y </s></s> no son posibles pero los dejamos por simplificación).
El tamaño del vocabulario: |V| es 11

Calculemos la nueva probabilidad para la frase: "En un plato de trigo".

= P(<s>En un plato de trigo</s>)
= P(en | <s>) x P(un | en) x P(plato | un) x P( trigo | de ) P( </s> | trigo)

Donde las nuevas probabilidades serán:

P(en | <s>)       = 1+1 / 3+11 = 2/14 = 0,143
P(un | en)         = 1+1 / 1+11 = 2/12 = 0,167
P(plato | un)     = 1+1 / 1+11 = 2/12 = 0,167
P( de | plato )   = 1+1 / 1+11 = 2/12 = 0,167
P( trigo | de )    = 1+1 / 1+11 = 2/12 = 0,167
P( </s> | trigo)  = 2+1 / 2+11 = 3/13 = 0,231

= 0,143  x  0,167 x 0,167 x 0,167 x 0,167 x 0,231 = 0,0000257

Ahora calculemos la probabilidad de la frase: "En un plato de tigres" (la cual antes era de cero.)


P(en | <s>)        = 1+1 / 3+11 = 2/14 = 0,143
P(un | en)           = 1+1 / 1+11 = 2/12 = 0,167
P(plato | un)       = 1+1 / 1+11 = 2/12 = 0,167
P( de | plato )     = 1+1 / 1+11 = 2/12 = 0,167
P( tigres | de )     = 0+1 / 0+11 = 1/11 = 0,091
P( </s> | tigres )  = 1+1 / 1+11 = 2/12 = 0,167


= 0,143  x  0,167 x 0,167 x 0,167 x 0,091 x 0,167 = 0,00001012

Lo que podemos ver es que la probabilidad que antes era  0,33 pasó a ser: 0,0000257, y en general cada uno de los bigramas diluyó su probabilidad para que podamos calcular la probabilidad de una frase que no existía antes en el corpus.



4 comentarios:

  1. Por qué resulta: P( trigo | de ) = 1/2 = 0,5 ?
    Yo creo que lo correcto es =1/1. Pues P(de trigo) =1 y P(de) =1 ...

    Creo que hay un confusion con P( de | trigo ) = 1/2 = 0,5 pero este no es el caso.

    Por lo demás, todo esta muy claro. Excelente trabajo!

    Raul.

    rchavez@pucp.pe

    ResponderEliminar
    Respuestas
    1. Hola, muchas gracias por tu corrección y tu interés en el blog. Ya corregí el post, tu observación era correcta.

      Eliminar
  2. ¡Fantástica explicación!

    Tan solo hay algo que no comprendo. ¿En la tabla de probabilidades no faltarían P( tristes | tres ) y P( tristes | tigres )?

    ResponderEliminar