Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clasificar textos en categorías (topic classification) #12

Open
dcabo opened this issue Mar 1, 2019 · 10 comments
Open

Clasificar textos en categorías (topic classification) #12

dcabo opened this issue Mar 1, 2019 · 10 comments
Assignees
Labels

Comments

@dcabo
Copy link
Member

dcabo commented Mar 1, 2019

Queremos clasificar cada bloque de texto en categorías, en función de su contenido.

En este punto no tenemos del todo claro la granularidad de la clasificación: es decir, ¿queremos decir simplemente "política" y "deporte", o queremos/podemos decir "caso Gürtel" y "Champions League"/"fútbol"? En teoría parecería que cuanto más detalle mejor, pero es posible que llegar a ese nivel requiera hacer cosas más elaboradas, como sacar la lista de etiquetas de la web de RTVE. Para empezar, lo mejor parece hacer unas primeras pruebas clasificando por áreas generales y luego vamos viendo.

Hay una cierta inter-dependencia entre esto y lo de la segmentación de la transcripción (#7): para que el topic modelling funcione bien es posible que haga falta tener bloques medianamente extensos, pero a la vez es posible que la segmentación funcione mejor si podemos clasificar los fragmentos (si dos fragmentos hablan del mismo tema los podemos unir). No sabemos aún cual es la mejor forma de organizar esto, hay que hacer pruebas.

Algunos enlaces sobre creación de modelos de clasificación en Flair:

@dcabo dcabo changed the title Probar topic modelling Probar el _topic modelling_ Mar 1, 2019
@dcabo dcabo changed the title Probar el _topic modelling_ Probar el topic modelling Mar 1, 2019
@dcabo
Copy link
Member Author

dcabo commented Oct 3, 2019

Como comento en #23, lo que hace gente como Vox es usar bloques fijos de 15 segundos. Podemos empezar por ahí para probar cómo de bien funciona la categorización (porque está claro que a nivel de sentencia va a ser imposible que acierte), y según lo que salga vemos.

@dcabo dcabo added the nlp label Oct 3, 2019
@dcabo
Copy link
Member Author

dcabo commented Nov 4, 2019

Tengo una primera versión de un modelo de clasificación en el repo telelediario. He hecho unas primeras pruebas con un corpus pequeño (2000 noticias) y a veces funciona:

$ python3 test.py "Las encuestas dan 178 escaños a Pedro Sánchez"
[Elecciones (0.37633806467056274)]

$ python3 test.py "MasterChef sigue siendo lider de audiencia todas las noches"
[Comunicación-RTVE (0.261417418718338)]

$ python3 test.py 'El Real Madrid, nuevo campeón de Europa gracias a Zidane.'
[Fútbol (0.7414063215255737)]

He hecho unas primeras pruebas usando el ejemplo de entrenamiento básico de Flair con los embeddings de BERT:

EPOCH	TIMESTAMP	BAD_EPOCHS	LEARNING_RATE	TRAIN_LOSS	DEV_LOSS	DEV_PRECISION	DEV_RECALL	DEV_F1
1	18:14:12	0	0.1000	3.4310358875202684	2.7845988273620605	0.2193	0.2203	0.2198
2	18:17:08	0	0.1000	2.589394747086291	2.1581220626831055	0.4123	0.4141	0.4132
3	18:20:10	1	0.1000	2.132350602239933	3.4886841773986816	0.1974	0.1982	0.1978
4	18:23:01	0	0.1000	1.8675508319206957	2.0329349040985107	0.4825	0.4846	0.4835
5	18:26:06	0	0.1000	1.6731717181655597	1.6564441919326782	0.5307	0.533	0.5318
6	18:29:02	1	0.1000	1.5272935763844904	1.6470911502838135	0.5088	0.511	0.5099
7	18:32:11	0	0.1000	1.334731230195963	1.340096116065979	0.5921	0.5947	0.5934
8	18:35:16	1	0.1000	1.2472548541033044	1.6981245279312134	0.5044	0.5066	0.5055
9	18:38:15	0	0.1000	1.2092748481147695	1.5045700073242188	0.6009	0.6035	0.6022
10	18:41:18	1	0.1000	1.078577993051061	1.8205885887145996	0.4825	0.4846	0.4835

Y BERT + Flair:

EPOCH	TIMESTAMP	BAD_EPOCHS	LEARNING_RATE	TRAIN_LOSS	DEV_LOSS	DEV_PRECISION	DEV_RECALL	DEV_F1
1	18:49:23	0	0.1000	3.4596951435197076	3.9939112663269043	0.0658	0.0661	0.0659
2	18:53:19	0	0.1000	2.6823639577289797	2.7456209659576416	0.25	0.2511	0.2505
3	18:57:16	0	0.1000	2.2574026022317275	2.417908191680908	0.3114	0.3128	0.3121
4	19:01:30	0	0.1000	1.9070523572417926	1.9924359321594238	0.4781	0.4802	0.4791
5	19:05:42	0	0.1000	1.7100887388553259	1.5674718618392944	0.5132	0.5154	0.5143
6	19:09:55	0	0.1000	1.5516143452446416	1.6284558773040771	0.5219	0.5242	0.523
7	19:14:01	1	0.1000	1.3996716704008714	1.721571922302246	0.5088	0.511	0.5099
8	19:18:02	2	0.1000	1.281477393406742	2.301140546798706	0.4254	0.4273	0.4263
9	19:22:12	3	0.1000	1.2047091103949636	1.7832567691802979	0.5132	0.5154	0.5143
10	19:26:10	4	0.1000	1.0799569363863963	1.7839747667312622	0.4868	0.489	0.4879

Es poco entrenamiento, 10 epochs, menos de una hora en mi portátil, y llegamos a F1=0.6, que no es la hostia, pero bueno, es el principio. Aún hay muchas cosas que decidir de cara a optimizar esto:

  • ¿Qué campo usamos para entrenar? He empezado con el título (longTitle), pero tenemos también un resumen (summary), una especie de entradilla, que supongo es opcional (essentialInfo) y el texto completo, que supongo será lo mejor (text).
  • ¿Queremos entrenar con todos los artículos o solo los que están clasificados como "Noticias"? Hay muchas cosas internas de RTVE y de otros programas suyos.
  • ¿Qué parte de la categoría usamos? Usar la categoría completa, con todo el árbol, no va a funcionar, son demasiadas opciones. ¿El primer nivel para empezar? ¿Tiene sentido añadir una línea al corpus por cada nivel del árbol? Me inclino por empezar con el primer nivel y luego aumentar el detalle en las partes del árbol que nos interesan, como "Noticias" o "Especiales".
  • Estamos intentando adivinar la categoría, única. ¿Qué tal funciona generar una lista de keywords, que es algo que ofrecen aparte?
  • ¿Cómo generamos el embedding del documento completo? Ahora mismo usamos una RNN, pero hay otras opciones, empezando por lo más sencillo, la media de las palabras. Por no hablar de los distintos parámetros de la red en sí.
  • ¿Qué embeddings usamos? Empecé con Glove, que era el ejemplo, pero se me olvidó cambiar a español, así que esa prueba no vale. La comparativa de arriba sirve para ver que con el stacking BERT+Flair va un poco más lento (8/seg vs ~11/seg) y que parece avanzar de forma más estable, pero es un ejemplo demasiado pequeño para sacar conclusiones. Ambos llegan a 0.5-0.6 y tontean por ahí.
  • Todo el tema de hiperparámetros, que no controlo.

La idea ahora sería:

  • Probar distintas opciones con unas pocas epochs (~10-15) y tener una estimación a grandes rasgos de lo que funciona y lo que no.
  • Tener un corpus más grande, de unas ~40K noticias, que se está descargando ahora.
  • Quitar noticias en catalán del corpus ("language": "ca").

@dcabo dcabo self-assigned this Nov 5, 2019
@dcabo
Copy link
Member Author

dcabo commented Nov 5, 2019

Tenemos 40K artículos descargados de RTVE. Quitando los que no son en castellano y algunas categorías que no tienen sentido ("PLAYZ") o que son confusas ("Radio", "Televisión"), tenemos un corpus ahora de 31 276 artículos.

Por empezar con lo más sencillo, vamos a entrenar al modelo para reconocer solo Noticias, Deportes y RTVE (novedades sobre RTVE en sí). Usando solo BERT, y una sola epoch, que ahora tarda casi una hora, alcanzamos ahora un F1 de 0.95, porque es mucho más sencillo:

MICRO_AVG: acc 0.8967 - f1-score 0.9455
MACRO_AVG: acc 0.8796 - f1-score 0.9355666666666668
Deportes   tp: 658 - fp: 23 - fn: 61 - tn: 2269 - precision: 0.9662 - recall: 0.9152 - accuracy: 0.8868 - f1-score: 0.9400
Noticias   tp: 1743 - fp: 69 - fn: 86 - tn: 1113 - precision: 0.9619 - recall: 0.9530 - accuracy: 0.9183 - f1-score: 0.9574
RTVE       tp: 446 - fp: 72 - fn: 17 - tn: 2476 - precision: 0.8610 - recall: 0.9633 - accuracy: 0.8336 - f1-score: 0.9093

Esto es "demasiado fácil", hay que añadir más detalle a las categorías, pero es suficientemente interesante como para probarlo con los datos reales, las transcripciones de los Telediarios.

@dcabo
Copy link
Member Author

dcabo commented Nov 11, 2019

Hemos estado un par de días haciendo pruebas varias para ver el rendimiento del entrenamiento de modelos en distintos entornos. Ahora que tenemos unas ideas básicas del coste de todo esto y de distintas opciones, la idea es seguir mejorando el modelo y aplicándolo a lo que realmente queremos clasificar: los subtítulos.

@rafaharo
Copy link

Buenas @dcabo . Veo que lo que habéis llamado en esta issue "Topic Modelling" es más bien una clasificación por categorías. Sin embargo, creo que en lo que consiste formalmente el Topic Modelling también podría ser de interés en este proyecto. De hecho se suele usar cuando no tienes un conjunto de categorías predefinidas para la clasificación o cuando quieres ver como se agrupan semánticamente los términos en tu corpus de texto.

En python hay una librería clásica que se llama gensim con la que se puede experimentar de forma relativamente sencilla. Os dejo un enlace a un post en el que lo usan para que tengáis un ejemplo de lo que se puede obtener a partir de un proceso de Topic Modelling:

https://medium.com/@armandj.olivares/topic-modeling-on-spanish-text-f7a5e998fb90

Si lo veis de interés os podría ayudar a montar esto.

@dcabo
Copy link
Member Author

dcabo commented Feb 18, 2020

@rafaharo en efecto, inicialmente yo -novato en PLN- lo llamaba a todo "topic modelling", así en general. Luego, pensando, y viendo que iba a ser más útil clasificar en función de categorías pre-existentes (las que usan los periodistas en general, y los que publican en la web de RTVE en particular), vi que era más correcto decir "topic classification".

Yo estoy de viaje el resto de la semana, pero en cuanto tenga un momento publico los datos originales en crudo para que haya un corpus sobre el que trabajar, y me leo el artículo que enlazas. Mi miedo -sin haberlo leido- es que salgan clusters que no sean fácilmente "entendibles". Cuando lo lea te digo.

@dcabo dcabo changed the title Probar el topic modelling Probar el topic classification Feb 18, 2020
@dcabo dcabo changed the title Probar el topic classification Clasificar textos en categorías (topic classification) Feb 18, 2020
@anavaldi
Copy link
Collaborator

Tu miedo (@dcabo ) es totalmente cierto. No he conocido a nadie que utilice LDA y le salgan unos temas (listas de palabras) intuitivos de agrupar...

@davidhguerrero
Copy link

davidhguerrero commented Feb 18, 2020

Hace casi tres años trabaje con LDA estos temas, percisamente con gensim. Se crearon modelos y con los que se consiguieron tasas entorno 60% para un conjuntos de textos cientificos.

El ajuste de los parámetros de LDA se hizo por tanteo con el conjunto de muestras que se disponia =)

@rafaharo
Copy link

Es un experimento relativamente sencillo de llevar a cabo en plan baseline y puede dar resultados interesantes. Igualmente aunque no sea para clasificar te puede servir para otras tareas como agrupación.

@dcabo
Copy link
Member Author

dcabo commented Feb 27, 2020

Comentar aquí (porque es el issue más popular y le llega a distinta gente) que he publicado una primera versión del corpus con todo el contenido en #96. (Tengo pendiente además abrir el código que descargar y parte los subtítulos, en #95.) En unos días haremos esto más oficial, subiremos los datos a la web de Datos Civio y tal, pero quería avisaros aquí por si alguno tenéis comentarios para que sea más útil. Si tenéis sugerencias / peticiones / dudas, hacedlas en #96 please, y veo si son factibles.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants