Open dcabo opened 5 years ago
What's the right word for what I want to do in the NLP world? I believe it's "topic segmentation".
I've started to play with an alternative very conservative approach when splitting the RTVE data: if a sentence starts with a lowercase letter, it means we're still in the same block, everything else starts a new one. What's the next step? How can we compare the entities/topics to decide whether we're still talking about the same thing?
Some papers/approaches:
Some other, that look bad-ish or old:
Las pruebas de sincronizar audio y texto que comento en #8 no parecen ser una solución obvia al problema de la segmentación. ¿Cómo la mejoramos entonces? Porque hacer topic modelling de frases sueltas parece chungo. Debería posiblemente empezar leyendo lo que enlazo en el comentario anterior.
Una estrategia es aprovechar lo que sabemos de este caso concreto: la web de RTVE. Sabemos que hay noticias etiquetadas, y si algo sale en el telediario debería estar en la web también ese día. (Pero no es así, sigue leyendo.) Parece un problema más limitado el asignar cada fragmento a una noticia.
Otra cosa que hay en la web son clips de ciertas partes (y de hecho a veces solo hay eso, y no noticia escrita). He comprobado y de los clips no hay subtítulos. Bajarlos y transcribirlos para entonces matchear eso con la transcripción del programa entero suena bastante absurdo.
También tenemos los "cue points" (escaletas) de algún año, hasta que dejaron de publicarlos, por si hubiera que entrenar algo.
Algo que puede ser útil son las Named Entities (#10). ¿Empezamos por ahí? Se me ocurre un algoritmo que identifique las keywords o entidades relevantes de un día y que detecte cuando aparecen por primera y última vez. Del principio al final es un bloque. Bueno, con algo de cuidado porque al principio está el resumen del día que toca todos los palos. (¿Hacen resumen al final también? ¿Pueden retomar un tema varias veces?)
Esto que comento se parece a grandes rasgos al prototipo que hicieron algunas personas en el evento de TextAV de Londres al que acudí: identificaban entidades y/o temas (no lo tengo claro) y luego aplicaban clustering para partirlo en trozos, en plan "aquí se habla de muchas cosas que son equipos de fútbol, ergo...". No tengo notas ni código, pero puede que estén en su web.
Lo bueno de no depender de pausas y gaps es que vale para otras fuentes, pero esperaba no abrir ese melón hasta más adelante, la idea era empezar con algo sencillo.
Por cierto, la calidad de los subtítulos en las conexiones con corresponsales o declaraciones de gente es bastante mala. Sabemos por #9 que Amazon hace muy buen trabajo, pero en este momento no parece que merezca la pena entrar en ese jaleo.
He estado esta tarde pegándome un poco con este issue para ver si lograba algo. Sobre todo he probado un poco entre lo que comentabas al principio del issue y un poco intuición de que nos puede valer en el futuro:
Lo mejor que he encontrado para separarlos ha sido:
Mirar cuánto silencio hay antes de un subtítulo. Lo del segundo no me estaba yendo demasiado fino así que he probado a tener en cuenta el contexto previo: al final lo que mejor parecía ir era si marcar si el silencio antes de un subtítulo era mayor que el triple de la media de los silencios de los 5 subtítulos anteriores (sí, son medidas mayormente arbitrarias).
Mirar si el subtítulo anterior termina en punto. He probado a jugar con los guiones pero a veces los usan en reportajes también, así que no vale.
Si un subtítulo cumple las dos condiciones (o es el primero del telediario), lo marco como si fuese el inicio de la pieza del telediario. Solo con esto parece encontrar puntos de corte bastante buenos (esto lo digo evaluando a ojo, claro), y además parece que falla más separando bloques que mezclándolos entre sí, lo cual parece a priori más fácil de arreglar después. La primera condición es algo muy muy a ojo, y puede ser interesante generar varias características así para entrenar un modelo que detecte estos cortes mejor. Para ello, o incluso para ajustar mejor alguna forma programática, nos pueden ser super útiles las escaletas de las que hablabas.
Aparte de esto, también he visto que los subtítulos de las conexiones tienen más silencios entre sí que los de las piezas de telediario ya escritas: las conexiones suelen tener silencios internos "bastante" largos mientras que es raro que los de las las piezas tengan más de 100ms entre sí. Esto puede ser útil para descartar conexiones, porque la calidad de algunas es tan mala que puede venir bien directamente quitarlas dependiendo de para qué.
Esto lo he hecho en un notebook de Python, si queréis puedo abrirme una rama y subirlo ahí para que le echéis un vistazo (en principio GitHub los renderiza, así que los podríais leer ahí directamente).
Gracias, @DiegoVicen, muy interesante.
El punto 1 que comentas (lo de la media de los silencios anteriores) no lo tengo muy claro, porque va en la línea de "ojímetro" que inicié yo (y que reconozco que es un churro), pero el segundo punto suena bien, va en la línea de lo mirar las mayúsculas/minúsculas de la siguiente línea, que creo que en el caso de RTVE merece la pena. (En otras fuentes, como la transcripción automática de YouTube, no tenemos puntuación de calidad, pero intentemos arreglar el problema fácil primero.)
En cualquier caso, está claro que tenemos que pasar de mi primerísima versión inicial, que se pasa juntando cosas, a una versión que peque de conservadora, porque como dices eso es más fácil de corregir después, mirando el contenido en sí.
Parece claro también que tenemos que aprovechar las escaletas pasadas, bien para entrenar "algo", bien para intentar medir la corrección de nuestros algoritmos. Voy a descargar todas las que pueda y cuando las tenga las comento aquí.
Gracias!
@DiegoVicen, verás que he estado trabajando sobre todo en lo de reconocimiento de entidades, #10, que es más sólido para ir arrancando. Sobre la segmentación en bloques, como te comentaba, hay unos dos años con escaletas, he dejado toda la info aquí. He quitado las escaletas vacías, pero puede que haya alguna a medio hacer, no he limpiado ni verificado nada. Por si te sirve.
Muchas gracias @dcabo, le echo un vistazo y a ver si en estos días logro contaros algo mejor. He estado siguiendo también #10 y hay algunos que apuntan muy buenas maneras. Respecto a lo de la rama, os parece bien? En local me tengo creada una rama notebooks para ir metiendo todo, pero todas formas hasta que no tenga algo que realmente merezca la pena enseñar no planeo hacer push de nada.
Ah, sí, lo de la rama, perdona. Por mí puedes crear una carpeta en este repo y meterlo ahí, sin rama. No sé cómo llamar la carpeta: docs? data? research? Creo que tienes permisos, pero si no me dices. Gracias.
Como comento en #23, igual la solución es usar bloques fijos, y dejar opciones más avanzadas, como lo que teníamos originalmente en la cabeza de encontrar los límites exactos de la escaleta, para una futura versión.
El programa de carga de datos no está gestionando bien la lista de entidades detectadas cuando hay bloques: sobreescribe la lista con cada nueva frase, en vez de concatenarlas. No lo voy a arreglar ahora porque total no estamos usando los bloques.
Ahora mismo, como paso inicial, estamos usando un algoritmo muy básico: si hay menos de un segundo de pausa entre fragmentos, consideramos que van juntos en el mismo bloque. Además del hecho de que el márgen "1 segundo" lo he puesto a ojo, tendríamos que probar métodos más fiables. Posibles "señales" a utilizar, en plan brainstorming, no digo que sean buenas señales:
No descartemos la necesidad de hacer una pequeña limpieza manual a posteriori.
En cualquier caso, esto puede ser la semilla de un proceso inteligente (Machine Learning!) que decida cuándo cambia el tema en una transcripción.