¿Cómo puedo agrupar cadenas por temas comunes?

10

Estoy tratando de agrupar, por ejemplo, cadenas sobre programación con otras cadenas sobre programación, cadenas sobre física con otras cadenas sobre física, etc., para una amplia gama de temas. A pesar del aspecto lingüístico teórico deslumbrante del problema, estoy tratando de hacer esto realmente usando programación / software.

El resumen: Dada una gran cantidad de cadenas, ¿cómo haría para agruparlas por tema semántico?

La aplicación particular: tengo ~ 200k preguntas de trivia que me gustaría clasificar en grupos comunes (automóviles, computadoras, política, Canadá, comida, Barack Obama, etc.).

Lo que he examinado: Wikipedia tiene una lista de kits de herramientas de procesamiento de lenguaje natural (suponiendo que lo que estoy tratando de hacer en realidad se llama PNL), así que he analizado algunos, pero ninguno parece hacer algo similar a mis necesidades.

Notas: Se ha señalado que hacer esto requiere conocimientos adicionales (por ejemplo, un Porsche es un automóvil, C ++ es un lenguaje de programación). Supongo que se necesitan datos de capacitación, pero si solo tengo la lista de preguntas y respuestas, ¿cómo puedo generar datos de capacitación? ¿Y luego cómo uso los datos de entrenamiento?

Más notas: Si el formato actual de mi Q & As ayuda (aunque parece JSON, es básicamente un archivo de texto sin formato):

// row 1: is metadata
// row 2: is a very specific kind of "category"
// row 3: is the question
// row 4: is the answer
{
  15343
  A MUSICAL PASTICHE
  Of classical music's "three B's", he was the one born in Hamburg in 1833
  Johannes Brahms
}

Pero antes de que alguien señale que ya existe una categoría, tenga en cuenta que hay ~ 200k preguntas y respuestas como esta, y básicamente tantas "categorías". Estoy tratando de agruparlos en grupos más amplios como los mencionados anteriormente. Además, este formato se puede cambiar para todas las preguntas muy fácilmente, lo hago mediante programación.

Y más notas: en realidad no sé cuántas categorías necesitaré (al menos 10-20), porque no he leído todas las preguntas yo mismo. En parte esperaba tener el número finito determinado de alguna manera durante la categorización. En cualquier caso, siempre puedo crear manualmente una serie de categorías.

Whymarrh
fuente
¿Cómo estabas usando zanahoria? De mi breve lectura al respecto, parece que debería manejar fácilmente 200k registros.
Solo tardó mucho más de lo que pensaba, y me obligó a aumentar la asignación de memoria inicial de la JVM a 1024 my la memoria máxima a 2048 m. No fue tan malo como pude haber hecho ese sonido.
Solo necesita suficientes datos de capacitación y luego debería poder clasificar las preguntas en estas categorías. Es probable que un enfoque totalmente automático termine agrupándolos por otros medios, por ejemplo, preguntas que contengan la palabra "automóvil". No puede aprender sinónimos al mismo tiempo que crea una agrupación.
HA SALIDO - Anony-Mousse
Eh, estás haciendo un procesamiento masivo; dar la JVM no es realmente un problema. ¿Cuánto tiempo tomó? ¿Desde dónde cargabas los documentos? ¿Una fuente personalizada?
Tomé tal vez 10 minutos, pero estoy de acuerdo, el procesamiento masivo es, por definición, lento y requiere mucha memoria. A pesar de que todo el asunto sobre la asfixia no fue el problema, más que una nota al margen.

Respuestas:

4

Este es un problema bastante estándar en PNL, y las palabras mágicas de Google que está buscando son "modelado de temas". Aunque sus cadenas son bastante cortas, puede tener cierto éxito con la asignación de Dirichlet latente o un método similar. Hay una buena entrada en el blog de Edwin Chen aquí , que establece la idea general detrás del algoritmo. Los detalles de la implementación están cubiertos en esta nota por Yi Wang.

Si está buscando una solución estándar, le recomiendo probar el topicmodelspaquete para R, ya que proporciona una interfaz razonablemente agradable tanto para LDA como para un Modelo de tema correlacionado más sofisticado. También hay una buena lista de implementaciones mantenidas por David Mimno aquí .

Martin O'Leary
fuente
Gracias, la publicación del blog de Chen parece estar en lo que estoy tratando de hacer. ¿Hay alguna posibilidad de que hayas usado algo de lo que has enumerado / hecho antes? Estoy en terrenos completamente nuevos aquí y agradecería un recorrido de lo que tendría que hacer (usando una de las soluciones disponibles). ¿Cómo debo formatear mis "documentos"? ¿Debo aplicar ID a cada Q&A para permitirme identificar qué documento está en qué grupo? ¿Cómo uso los datos de salida? Como dije, no entiendo muchos detalles.
Whymarrh
He usado bastante el paquete R topicmodels. Ciertamente lo recomendaría antes de lanzar su propio código: hay algo de documentación con un ejemplo trabajado en cran.r-project.org/web/packages/topicmodels/vignettes/… . El formato específico de cada documento realmente no importa, ya que todo se reducirá a una representación de "bolsa de palabras" de todos modos. Simplemente arroje todo el texto asociado en una cadena.
Martin O'Leary
4

Estás tratando de resolver dos problemas aquí.

Problema 1: categorizar cadenas de preguntas en la categoría adecuada.

Problema 2: crear categorías adecuadas.

El primer problema podría resolverse mediante los llamados algoritmos supervisados, muchos clasificadores pueden ofrecer una precisión y un rendimiento muy buenos. Sin embargo, el problema 2, crear categorías de la nada (toneladas de datos), es mucho más complicado. Este es un problema no supervisado, dada la gran cantidad de datos que la computadora decide de forma autónoma por categorías según algunos criterios. Idealmente, estos criterios y el algoritmo deberían organizar perfectamente sus datos en grupos. Estos podrían ser etiquetados. Sin embargo, como esta es una tarea mucho más difícil, diría que aquí no hay una solución aceptable que permita un buen resultado sin un gran esfuerzo de ajuste que probablemente requerirá expertos.

Entonces, me temo que todavía no hay un botón mágico aquí. Sin embargo, lo que puede hacer es ayudar un poco a la máquina. Por ejemplo, puede decidir sobre el conjunto de categorías. Cuando haya decidido las categorías, puede crear datos de capacitación. En esta configuración, los datos de entrenamiento son solo preguntas y pares de categorías correctas.

Cuantos más datos de entrenamiento, mejor. Sin embargo, como la tarea sigue siendo hacer algo automáticamente, no tiene sentido al principio comenzar a hacer las cosas manualmente. Ahora, ¿por qué querrías tener datos de entrenamiento? Evaluación de precisión. Si desea buenos resultados, es vital que pueda realizar algún tipo de evaluación sobre qué tan bien está funcionando una configuración. Y la única manera de hacerlo de manera sistemática es etiquetar manualmente algunas preguntas usted mismo. De lo contrario, estás en la ciega.

Entonces, surgen algunas preguntas nuevas. Primero: ¿Cuántos datos de entrenamiento necesito? "Depende". Sin haber visto sus datos o categorías, no estoy seguro de adivinar; pero puedo tomar una "estimación aproximada" y decir unas 500 preguntas. Tenga en cuenta que podría estar fuera por un orden de magnitud.

¿Esto realmente significa que tendrías que etiquetar 500 preguntas a mano? Si y no. Es posible utilizar resultados intermedios y cierta inteligencia para "arrancar" clasificadores. Sin embargo, todavía es un trabajo manual, y cuando lo piensas, 500 preguntas no tardarán en etiquetarse. Ser inteligente aquí puede dar rápidamente peores resultados que ser trabajador.

Cuando tenga datos de entrenamiento en una cantidad suficiente, tome el 75% de ellos y cree un clasificador utilizando su herramienta favorita (por ejemplo, los mencionados aquí o no). Ahora, deje que el clasificador intente etiquetar el 25% de los datos retenidos y mida la precisión resultante. Si el resultado es bueno, entonces toma champán. Si no es así, haga más datos de entrenamiento o pruebe con otro clasificador.

TL; DR

En resumen, así es como lo habría hecho.

0) Use a supervised learner.
1) Create a category set yourself. 
2) Label manually about 500 questions
3) Use 75% of those to train a classifier.
4) Check performance.
5) If good then cheers else goto 2.

fuente
Una pequeña pregunta: dices "alrededor de 500 preguntas" para los datos de entrenamiento y para etiquetarlas manualmente, pero también "podría estar fuera de lugar por un orden de magnitud", así que si tuviera que usar 5k o 50k preguntas, ¿todavía etiquetar manualmente tantos?
La cosa es; sin haber visto sus datos ni tener una idea muy clara de todos los detalles minuciosos de su proyecto, es difícil dar una buena estimación. Sin embargo, y es importante recordarlo, si el 500 es demasiado bajo, el esfuerzo de marcado no se desperdicia. Aún necesita preguntas etiquetadas manualmente para la evaluación. Cuantos más datos de evaluación tenga, mejores evaluaciones podrá hacer.
Por un orden de magnitud quise decir 50-500-5000. No creo que necesites clasificar 50k. ¡Eso es 1/4 de tu corpus entero! Si 500 preguntas son demasiado bajas, es posible arrancar clasificadores. La idea aquí es entrenar al clasificador en un pequeño corpus inicial (por ejemplo, su 500) y luego etiquetar el resto. Ahora, puede usar algunos de los casos en los que el clasificador tenía mucha confianza para volver a capacitar un clasificador nuevo y más grande.
Otra cosa importante a tener en cuenta; El rendimiento de muchos clasificadores no es lineal en la cantidad de datos de entrenamiento, pero generalmente será una curva sigmoidea. Eso significa que 500 preguntas más etiquetadas podrían ser casi tan beneficiosas como 5000. Mi consejo es trabajar en pequeños pasos.
¿Qué detalles proporcionarían información adicional sobre mi proyecto? Puedo compartir algunas preguntas de ejemplo para mostrar mi formato, pero estoy dispuesto a adaptar el formato de mis preguntas y respuestas para que se ajuste al proceso de categorización. Agradezco la ayuda.