Pregunta

Me quedan unos 300k documentos almacenados en una base de datos PostgreSQL que están etiquetadas con categorías de temas (hay cerca de 150 categorías en total). Tengo otro 150k documentos que aún no tienen categorías. Estoy tratando de encontrar la mejor manera de categorizar programmaticly ellos.

he estado explorando NLTK y su Naive Bayes clasificador. Parece un buen punto de partida (si se puede sugerir una mejor algoritmo de clasificación para esta tarea, soy todo oídos).

Mi problema es que no tengo suficiente memoria RAM para entrenar al NaiveBayesClassifier en todos los 150 categoies / 300k documentos a la vez (formación en 5 categorías usa 8 GB). Además, la precisión del clasificador parece caer como entreno en más categorías (90% de precisión con las 2 categorías, 81% con 5, el 61% con 10).

¿Debo entrenar a un clasificador en 5 categorías a la vez, y ejecutar todos los documentos 150k a través del clasificador para ver si hay coincidencias? Parece que esto funciona, excepto que no habría una gran cantidad de falsos positivos en los documentos que en realidad no coinciden con ninguna de las categorías reciben zapato cuernos en el por el clasificador sólo porque es la mejor opción disponible ... ¿Hay una manera de tener una "ninguna de las anteriores" opción por el clasificador por si acaso el documento no se ajusta a ninguna de las categorías?

Esta es mi clase de prueba http://gist.github.com/451880

¿Fue útil?

Solución

Se debe comenzar mediante la conversión de sus documentos en TF-log (1 + IDF) vectores : frecuencias plazo son escasos por lo que debe utilizar dict pitón con mandato como llaves y contar como valores y luego dividir por recuento total para obtener las frecuencias globales.

Otra solución es utilizar los ABS (almohadilla (plazo)), por ejemplo como teclas de número entero positivo. Entonces usted un uso scipy.sparse vectores que son más práctico y más eficiente para llevar a cabo la operación de álgebra lineal dict pitón.

construir También las 150 frecuencias vectores promediando las frecuencias de todos los documentos marcados pertenecientes a la misma categoría. Luego de nuevo documento de etiqueta, se puede calcular el coseno similitud entre el vector documento y cada categoría de vectores y elegir la categoría más similar a la etiqueta para su documento.

Si esto no es lo suficientemente bueno, entonces usted debe tratar de entrenar un modelo de regresión logística utilizando una penalización L1 como se explica en este ejemplo de scikit-learn (esto es un contenedor para LIBLINEAR como se explica por @ephes). Los vectores utilizados para entrenar a su modelo de regresión logística debe ser el TD-registro previamente introducida (1 + FDI) vectores para obtener un buen rendimiento (precisión). El scikit aprender ofertas lib módulo A sklearn.metrics con rutinas para calcular los puntuación para un modelo dado y determinado conjunto de datos.

Para grandes conjuntos de datos: usted debe tratar el vowpal wabbit que es probablemente el conejo más rápido en la tierra para los grandes problemas de clasificación de documentos de escala (pero no es fácil de usar envolturas de pitón que yo sepa).

Otros consejos

¿De qué tamaño (número de palabras) son sus documentos? El consumo de memoria a 150K trainingdocs no debería ser un problema.

Naive Bayes es una buena opción, especialmente cuando se tiene muchas categorías con sólo unos pocos ejemplos de entrenamiento o trainingdata muy ruidoso. Pero, en general, lineal Support Vector Machines se desempeñan mucho mejor.

Es el problema de multiclase (un documento pertenece sólo a una categoría exclusivly) o multietiqueta (un documento pertenece a una o más categorías)?

La precisión es una mala elección para juzgar el desempeño del clasificador. Usted no debe usar la precisión vs recuerdo, remitieron al punto de precisión el punto de equilibrio (PRBP), f1, AUC y tener que mirar a la precisión frente a la curva recuerdo donde recuerdo (x) se representa frente a la precisión (y) en función del valor de su confianza umbral (wether un documento pertenece a una categoría o no). Por lo general, se podía construir un clasificador binario por categoría (ejemplos de entrenamiento positivos de una categoría frente a todos los demás trainingexamples que no pertenecen a la categoría actual). Usted tendrá que elegir un umbral de confianza óptima por categoría. Si desea combinar las medidas individuales por categoría en una medida de rendimiento global, que tendrá que micro (sumar todos los verdaderos positivos, falsos positivos, falsos negativos y verdaderos negativos y Calc combinado partituras) o macro (puntuación por categoría y Calc a continuación, un promedio de esos resultados sobre todas las categorías) promedio.

Tenemos un corpus de decenas de millones de documentos, millones de ejemplos de entrenamiento y miles de categorías (Multilabel). Como nos enfrentamos a serios problemas de tiempo de entrenamiento (el número de documentos son nuevos, actualizados o eliminados por día es bastante alto), se utiliza una versión modificada de LIBLINEAR . Pero para los problemas más pequeños usando uno de los envoltorios pitón alrededor LIBLINEAR ( liblinear2scipy o scikit-learn ) debería funcionar bien.

  

¿Hay una manera de tener una "ninguna de las   por encima de" opción por el clasificador solo   en caso de que el documento no se ajusta a   ninguna de las categorías?

Se puede conseguir este efecto simplemente por tener una "ninguna de las anteriores" pseudo-categoría entrenados cada vez. Si el máximo se puede entrenar es 5 categorías (aunque no sé por qué se está comiendo bastante tanto RAM soy), entrenar las 4 categorías reales de sus reales 2K documentos de cada uno, y una "ninguna de las anteriores" uno con sus 2K documentos tomada al azar de todas las otras categorías 146 (alrededor de 13-14 de cada uno si desea que el enfoque de "muestreo estratificado", que puede ser más sólida).

Todavía se siente como un poco de una chapuza y que podría ser mejor con un enfoque completamente diferente - encontrar una medida doc multidimensional que define sus 300K documentos pre-etiquetado en 150 racimos razonablemente separables, a continuación, sólo asignar cada una de los otros docs todavía-sin etiquetar al clúster apropiado como así determinados. No creo NLTK tiene nada directamente disponibles para apoyar este tipo de cosas, pero, bueno, NLTK del estado creciendo tan rápido que puede muy bien haber perdido algo ...; -)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top