Large Language Model (LLM) from scratch. Neural Networks: Ejemplo práctico.

En la entrega pasada explicamos algunos conceptos clave para entender redes neuronales. Dada su importancia, en la presente veremos si una red neuronal puede distinguir entre fragmentos de castellano medieval y de español moderno. Además, con este ejemplo en mente, compararemos la performance entre una red neuronal y una regresión logística.

Para esto, construiremos un pequeño dataset que consistirá en textos escritos en castellano contemporáneo y medieval. Luego, con esos datos, estimaremos una regresión logística cuyo objetivo principal será clasificar si un texto es medieval o no. Finalmente, emplearemos una red neuronal para llevar a cabo la misma tarea, y compararemos cuál de los dos hace un mejor trabajo de clasificación.

Construyendo el dataset

Para estimar ambos modelos es necesario contar con textos escritos en castellano medieval y contemporáneo. Los textos contemporáneos serán 498 cuentos pertenecientes a la iniciativa “Santiago en 100 Palabras”, y se pueden encontrar en la siguiente página web. Cada uno está compuesto por aproximadamente 100 palabras, y son escritos por personas que describen la vida en la ciudad. En algunas ocasiones el tono es formal, y en otras relativamente más coloquial, no obstante, siempre están escritos en castellano contemporáneo.

Para las observaciones de castellano medieval, tomaremos textos desde la siguiente página web, y extraeremos 500 fragmentos de 100 palabras. Uno de ellos, es el siguiente:

que dizen acuzant e es que sea lo que tuellen mucho e uerde Estas son las sennales de la cançre que seles faze en los quexares e es que seles camia lo que tuellen de manera que lo que tuellen una uegada no es atal como lo que tuellen otra e es buelto de blanco e de uermeio Estas son las sennales del mal del yesso e de la uentosidad que seles faze en los cuerpos e es que lo quetuellen es taiado e a en ello amarellura e lo que se quaia dello fazesse duro e aspero de manera

Como podemos ver en el fragmento de ejemplo, no hay signos de puntuación. Aunque en los textos originales sí aparecen, en este ejercicio los hemos eliminado para reducir la complejidad. No obstante, en el futuro los tendremos en cuenta.

Regresión Logística

Dado el dataset que tenemos, el siguiente paso es definir las variables independientes. En este punto hay varias alternativas. La primera sería seguir la estrategia que empleamos en una publicación anterior, es decir, usar como regresores palabras típicas del castellano medieval y del castellano contemporáneo. No obstante, como ya vimos, esta no es una buena idea: se trata de casos específicos que no siempre estarán presentes en los fragmentos y que, además, no resultan suficientemente informativos sobre la morfología del castellano medieval ni del contemporáneo.

En esta publicación intentaremos con otra estrategia. En lugar de definir regresores manualmente, construiremos automáticamente los rasgos a partir de trigramas de caracteres y los ponderaremos mediante TF-IDF (term frequency–inverse document frequency). Para ello, tomamos todos los textos del conjunto de entrenamiento —tanto medievales como no medievales—, extraemos sus trigramas y calculamos, para cada documento dd y cada trigrama gg, el peso

tfidf(g,d)=tf(g,d)idf(g)tfidf(g,d) = tf(g,d)\cdot idf(g)
idf(g)=log(N+1df(g)+1)+1idf(g) = \log\bigg(\frac{N+1}{df(g) + 1}\bigg) +1

Aquí, gg representa un trigrama, dd un documento del corpus de entrenamiento, NN el número total de documentos y df(g)df(g) la cantidad de documentos en que aparece ese trigrama. La intuición es simple: si un trigrama aparece muchas veces en un texto, su peso aumenta; si además aparece en pocos documentos del corpus, su peso aumenta todavía más. En cambio, si aparece en casi todos los documentos, su peso disminuye, porque aporta poca información distintiva. En nuestra implementación, una vez calculados estos pesos, el vector resultante se normaliza con norma L2L_2, de modo que los documentos puedan compararse en una misma escala.

Entonces, el número total de regresores será el total de n-gramas que fueron obtenidos desde los textos de entrenamiento, y el valor de los regresores vendrá dado por tfidf(g,d)tfidf(g,d). A modo de ejemplo, supongamos que nuestro corpus de entrenamiento consta de un texto medieval y otro no medieval. El medieval viene dado por:

E los demas de los sabios de los turcos otro si se trabaiaron dend. e el mas nombrado Rey.

y el no medieval por:

Nunca me dejó. Decía que no podía respirar
con ellos cerca. Un día desapareció. Ya no volvió.

Luego, al calcular los trigramas de ambos textos, tenemos:

trigramafrecuencia
Elo1
los4
osd2
sde3
dem1
ema1
..
..
..

Esto implica que la regresión logística viene dada por:

σ(z)=w1Elo+w2los+w3osd+w4sde+w5dem+...+\sigma(z) = w_{1}\cdot Elo + w_{2}\cdot los + w_{3}\cdot osd + w_{4}\cdot sde + w_{5}\cdot dem + … +

donde cada regresor es la función tfidf(g,d)tfidf(g,d), para ese trigrama gg. En la siguiente sección calcularemos los trigramas para el corpus de entrenamiento real, y su respectivo tfidf(g,d)tfidf(g,d).

Calculando trigramas

La estrategia que emplearemos será computar los trigramas para cada observación. En otras palabras, para cada texto medieval y no medieval, calcularemos trigramas. Al hacer esto, obtenemos lo siguiente:

Número total de documentos998
Documentos medievales500
Documentos modernos498
Número de trigramas distintos7.396

Lo anterior implica que tendremos 7.396 regresores. Respecto a aquellos, los 9 que tienen mayor TF-IDF promedio (1Nd=1Ntfidf(g,d)\frac{1}{N} \sum_{d=1}^{N} tfidf(g,d)) son:

TrigramasTF-IDF promedio
‘as ‘0.095239
‘ de’0.090066
‘ e ‘0.085153
‘os ‘0.073972
‘ qu’0.069798
‘en ‘0.068841
‘es ‘0.068074
‘ la’0.065219
‘que’0.062593

En este sentido, vale la pena destacar que el valor del regresor para esa estimación es tfidf(g,d)tfidf(g,d), no el promedio que presentamos en la tabla. Con tfidf(g,d)tfidf(g,d) calculado, estamos en condiciones de estimar los parámetros de la regresión logística.

Regresión Logística

Una vez estimada la regresión logística, un ejercicio útil es identificar qué trigramas tienen coeficientes positivos, y cuales tienen negativos. Esto nos permite determinar aquellos trigramas que empujan un texto a ser medieval (coeficientes positivos) o a ser no medieval (coeficientes negativos). En este sentido, los top 9 positivos vienen dados por:

TrigramaCoeficiente
‘ e ‘4.525484
‘as ‘2.379491
‘es ‘2.010735
‘ qu’1.767268
‘en ‘1.765731
‘s e’1.726395
‘las’1.568585
‘que’1.291647
‘ de’1.291306

y los top 9 negativos por:

TrigramaCoeficiente
‘ y ‘-1.373146
‘me ‘-1.094712
‘a, ‘-0.959669
‘o, ‘-0.955032
‘ía ‘-0.931607
‘ ve’-0.860371
‘s, ‘-0.849333
‘a. ‘-0.823249
‘ ha’-0.808638

como podemos ver a simple vista, al parecer, la regresión logística no ha sido particularmente buena en detectar combinaciones de caracteres propias del castellano medieval, puesto que las combinaciones que más empujan a medieval, son muy similares a las que podríamos ver en textos no medievales. En la siguiente sección, testearemos esta intuición de una forma más rigurosa.

Testeando rendimiento

Para testear el rendimiento de la estimación emplearemos 200 textos medievales que no están en el training set, y luego veremos qué porcentaje es correctamente clasificado como medieval (desde aquí en adelante,recall medieval).

Número de textos medievales en test200
Textos medievales predichos correctamente como medievales150
Porcentaje de acierto sobre textos medievales75%
Recall medieval0.75

La tabla anterior muestra que de 200 textos medievales, el modelo acierta correctamente a 150. Para poder analizar el rendimiento en términos relativos, tenemos que hacer el mismo ejercicio usando redes neuronales. En la siguiente sección llevaremos a cabo esto.

Redes Neuronales

La arquitectura que emplearemos será una red neuronal feedforward con dos capas ocultas. La primera tendrá 128 neuronas, y la segunda 64. Además, la función de activación será ReLU. Al estimarla, obtenemos los siguientes resultados:

Número de textos medievales en test200
Textos medievales predichos correctamente como medievales200
Porcentaje de acierto sobre textos medievales100%
Recall medieval1

Como podemos ver en nuestro experimento, la red neuronal superó a la regresión logística al clasificar correctamente todos los textos medievales del conjunto de prueba, mientras que la regresión logística identificó solo el 75%. Una explicación plausible es que la regresión logística combina los trigramas de manera lineal: cada rasgo aporta de forma independiente a la decisión final. La red neuronal, en cambio, puede aprender combinaciones no lineales entre rasgos ortográficos, morfológicos y gráficos del castellano medieval. Eso le permite captar patrones más complejos, como interacciones entre secuencias de caracteres, que un modelo lineal no representa bien. En esta tarea, esa flexibilidad parece haber marcado la diferencia.

Debido a que el modelo es relativamente exitoso, sería interesante explorar si es capaz de detectar peculiaridades del castellano medieval. Una manera de hacerlo es identificar qué trigramas son los que empujan un texto a ser medieval o no. A pesar de que no podemos obtener este número de forma directa (como en el caso de la regresión logística), es posible llevar a cabo una aproximación, que implica multiplicar las matrices de los pesos para obtener una especie de efecto agregado desde la entrada hasta la salida. Al hacer esto, podemos ver que los trigramas que parecen empujar más hacia medieval son:

TrigramaCoeficiente
‘tvl’0.255863
‘ças’0.253850
‘sel’0.250878
‘rau’0.248537
‘sea’0.244449
‘hd ‘0.241685
‘çer’0.235730
‘son’0.234452
‘xii’0.233908

y los que empujan más hacia moderno son:

TrigramaCoeficiente
‘ón ‘-0.245191
‘, p’-0.220347
‘mis’-0.220332
‘ ve’-0.218641
‘, s’-0.216067
‘ja ‘-0.216041
‘adr’-0.215468
‘tió’-0.214826
‘ame’-0.213638

Estos resultados muestran una foto distinta a la obtenida con la regresión logística. En particular, podemos ver que el carácter ‘ç‘, que se usó en el español medieval, pero luego fue abandonado tras el reajuste de las sibilantes durante los siglos XVI y XVII, aparece de forma más frecuente en los trigramas que empujan un texto a ser medieval, lo que claramente es una buena señal, puesto que es una peculiaridad que pertenece exclusivamente al castellano medieval, cuando es comparado con el moderno.

Notas finales, y próxima entrada…

En el siguiente ejercicio ponemos a prueba la capacidad de la regresión logística y de una red neuronal feedforward para clasificar textos medievales. Los resultados muestran que la red neuronal fue relativamente más eficaz. En particular, logró clasificar correctamente todos los textos medievales del conjunto de prueba, mientras que la regresión logística solo identificó correctamente el 75% de ellos.

En la próxima entrega, introduciremos los Large Language Models. Stay tuned!

José Miguel Muñoz Urra – jmunozu@pulki.es