¿Qué tan bien R escala las tareas de clasificación de texto? [cerrado]

30

Estoy tratando de ponerme al día con R. Finalmente, quiero usar las bibliotecas R para hacer la clasificación de texto. Me preguntaba cuáles son las experiencias de las personas con respecto a la escalabilidad de R cuando se trata de hacer una clasificación de texto.

Es probable que me encuentre con datos de altas dimensiones (~ 300k dimensiones). Estoy mirando el uso de SVM y Random Forest en particular como algoritmos de clasificación.

¿Las bibliotecas R se adaptarían al tamaño de mi problema?

Gracias.

EDITAR 1: Solo para aclarar, es probable que mi conjunto de datos tenga 1000-3000 filas (quizás un poco más) y 10 clases.

EDIT 2: como soy muy nuevo en R, solicitaré que los carteles sean más específicos siempre que sea posible. Por ejemplo, si está sugiriendo un flujo de trabajo / tubería, asegúrese de mencionar las bibliotecas R involucradas en cada paso si es posible. Algunos indicadores adicionales (a ejemplos, código de muestra, etc.) serían la guinda del pastel.

EDITAR 3: Primero, gracias a todos por sus comentarios. Y en segundo lugar, me disculpo, quizás debería haber dado más contexto para el problema. Soy nuevo en R pero no tanto en la clasificación de texto. Ya he realizado el preprocesamiento (derivación, eliminación de palabras vacías, conversión de tf-idf, etc.) en mi parte de mis datos usando el paquete tm , solo para tener una idea de las cosas. tm fue tan lento incluso con unos 200 documentos que me preocupaba la escalabilidad. Luego comencé a jugar con FSelector e incluso eso fue muy lento. Y ese es el punto en el que hice mi OP.

EDITAR 4: Se me ocurrió que tengo 10 clases y aproximadamente ~ 300 documentos de capacitación por clase, y de hecho estoy construyendo la matriz termXdoc a partir de todo el conjunto de capacitación, lo que resulta en una dimensionalidad muy alta. Pero, ¿qué hay de reducir cada problema de clasificación 1 fuera de k a una serie de problemas de clasificación binaria? Eso reduciría drásticamente la cantidad de documentos de capacitación (y por lo tanto la dimensionalidad) en cada uno de los pasos k-1 considerablemente, ¿no? Entonces, ¿este enfoque es bueno? ¿Cómo se compara en términos de precisión con la implementación habitual de varias clases?

Andy
fuente
1
300 mil dimensiones con cuántas filas? Desafortunadamente, los objetos R deben estar en la memoria (al menos a menos que consideres ajustes importantes, que básicamente requieren que reescribas estos algoritmos tú mismo). Eso significa que con, digamos, 8 gigas de ram, no creo que pueda almacenar más de unos cientos de filas con columnas de 300k.
crayola
@crayola: el número de filas puede variar de 1000-3000.
Andy
2
Los objetos R no necesitan estar en la memoria. El mapeo de memoria es muy fácil. Las dimensiones de 300k no son un problema. También supongo que sus datos son escasos, ya que ese es el caso con casi todos los problemas de texto.
Iterator
Acabo de notar el comentario anterior: ¿solo 1000-3000 filas? Eso es muy pequeño. ¿Puedes explicar cuál es tu corpus? ¿Un lote de correos electrónicos? Descripciones de paquetes en CRAN? Es posible que tenga más problemas estadísticos con P >> N que con cualquier problema de almacenamiento.
Iterator
1
@Iterator: Tenemos algunos recursos educativos (trabajos, ensayos, etc.) que queremos clasificar.
Andy

Respuestas:

17

Como se solicitó en un comentario, aquí hay algunos consejos para procesar los pasos. Se pueden encontrar varias herramientas en la vista de tareas CRAN para el procesamiento del lenguaje natural . También es posible que desee ver en este documento en el tmpaquete (minería de texto) para R .

  1. Antes del procesamiento, considere la normalización de los tokens de palabras. openNLP(para el que hay un paquete R) es una ruta.
  2. Para el procesamiento de texto, un paso común de preprocesamiento es normalizar los datos a través de tf.idf- frecuencia de término * frecuencia de documento inversa - vea la entrada de Wikipedia para más detalles. Hay otras normalizaciones más recientes, pero este es un método de pan y mantequilla, por lo que es importante saberlo. Puede implementarlo fácilmente en R: simplemente almacene (docID, wordID, freq1, freq2) donde freq1 es el recuento de veces que la palabra indexada por wordID ha aparecido en el documento dado y freq2 es el número de documentos en los que aparece. No es necesario almacenar este vector para palabras que no aparecen en un documento determinado. Luego, simplemente tome freq1 / freq2 y tendrá su valor tf.idf.
  3. Después de calcular los valores tf.idf, puede trabajar con la dimensionalidad completa de sus datos o filtrar aquellas palabras que esencialmente no son informativas. Por ejemplo, cualquier palabra que aparezca en solo 1 documento no dará mucha información. Esto puede reducir su dimensionalidad sustancialmente. Dado el pequeño número de documentos que se están examinando, es posible que sea apropiado reducir a solo 1K dimensiones.
  4. No volvería a centrar los datos (por ejemplo, para PCA), pero ahora puede almacenar los datos en una matriz de términos (donde las entradas ahora son valores tf.idf) con facilidad, utilizando las matrices dispersas, según lo admite el Matrixpaquete.

En este punto, tiene un conjunto de datos bien preprocesado. Recomendaría continuar con las herramientas citadas en la vista de tareas CRAN o el paquete de minería de texto. Agrupar los datos, por ejemplo proyectando en los primeros 4 o 6 componentes principales, podría ser muy interesante para su grupo cuando se grafican los datos.

Otra cosa: puede encontrar que la reducción de dimensionalidad en la línea de PCA (*) puede ser útil cuando se utilizan varios métodos de clasificación, ya que esencialmente está agregando las palabras relacionadas. Los primeros 10-50 componentes principales pueden ser todo lo que necesita para la clasificación de documentos, dado el tamaño de su muestra.

(*) Nota: PCA es solo un primer paso. Puede ser muy interesante para alguien que recién comienza con la minería de texto y PCA, pero eventualmente puede encontrar que es un poco molesto para los conjuntos de datos dispersos. Sin embargo, como primer paso, échale un vistazo, especialmente a través de las funciones prcompy princomp.

Actualización: no indiqué una preferencia en esta respuesta, lo recomiendo en prcomplugar de hacerlo princomp.

Iterador
fuente
+1 Buena respuesta; Solo tengo curiosidad por qué dices que un pequeño número de muelles implica un menor número de variables importantes: ¿no parece un poco excesivo?
No estoy seguro de entender lo que quieres decir. Mantenerlos es demasiado adecuado, por lo tanto, estas variables se eliminarían en cualquier regularización razonable. Además, el vocabulario (P) crece con el número de documentos o muestras (N), por lo que la primera vez que aparece un término no es indicativo de mucho. Siga agregando documentos y luego la recurrencia de un término en los documentos será informativa.
Iterator
@Iterator: Gracias por tu respuesta. Entonces, ¿ prcompy / o princompescalará a este tipo de datos que usted considera? También acabo de editar mi pregunta y agregué información adicional.
Andy
No, estos probablemente no se escalarán cuando llegue a 300K columnas. :) (Solo para señalar: X'X en ese caso tendrá entradas de 90B, un problema de almacenamiento). En su lugar, filtre primero por tf.idf. Si solo hay, por ejemplo, 10 clases distintas, entonces un pequeño múltiplo de 10 debería ser adecuado para una mayor dimensionalidad para separar las clases. Entonces, 1000 dimensiones deberían ser más que suficientes. Ambos métodos de PCA (por cierto, lo recomiendo prcomp) estarán bien.
Iterator
Una vez que limite a 1000 dimensiones o tal vez algunas más (por ejemplo, 2K), y haga PCA, puede tomar las proyecciones en unas 100 dimensiones (que pueden ser excesivas, pero hay poco daño en esto) y luego hacer la clasificación. En este punto, no está pasando nada demasiado emocionante.
Iterator
5

Primero, bienvenido! El procesamiento de texto es muy divertido, y hacerlo en R es cada vez más fácil.

La respuesta corta: sí, las herramientas en R ahora son bastante buenas para manejar este tipo de datos. De hecho, no hay nada especial sobre R, C ++, Groovy, Scala o cualquier otro idioma cuando se trata del almacenamiento de datos en RAM: cada idioma almacena un flotante doble de 8 bytes ... espere ... espere. .. 8 bytes!

Los algoritmos y su implementación son importantes, especialmente si se implementan muy mal con respecto a las estructuras de datos y la complejidad computacional. Si está implementando sus propios algoritmos, solo tenga cuidado. Si usa otro código, se aplica advertencia de advertencia, como lo hace en cualquier entorno.

Para R, deberá considerar:

  1. Su representación de datos (observe las matrices dispersas, especialmente en el Matrixpaquete)
  2. Almacenamiento de datos (quizás memoria mapeada, usando bigmemoryo ff; o distribuida, usando Hadoop)
  3. Su partición de datos (cuánto puede caber en la RAM depende de la cantidad de RAM que tenga)

El último punto está realmente bajo tu control.

Cuando se trata de esta dimensionalidad, ya no es particularmente grande. El número de observaciones tendrá un mayor impacto, pero puede dividir sus datos para ajustar el uso de RAM, por lo que no hay mucho de qué preocuparse.

Iterador
fuente
3

Estoy de acuerdo con crayola en que el número de filas es crucial aquí. Para RF, necesitará al menos 3 veces más RAM que los pesos de su conjunto de datos y probablemente mucho tiempo (tal cantidad de atributos generalmente requiere muchos árboles en el bosque, y tenga en cuenta que no hay una implementación paralela de RF en R).

Sobre SVM, dudo que sea una buena idea luchar con dimensiones de 300k, mientras que probablemente puedas desarrollar una función de kernel que sea equivalente a tus descriptores de texto.

EDITAR: la matriz de 3k x 30k (real) ocuparía algo así como 7Gb, por lo que todo lo que necesita hacer RF (usando randomForest) en estos datos es una computadora con 16GB de RAM, algo de suerte y bastante tiempo o simplemente una computadora con 24GB RAM y bastante tiempo.


fuente
Bueno, ciertamente iba a hacer una selección de características (chi cuadrado, basado en entropía), pero nuevamente no pude encontrar ninguna biblioteca R que escalara para esta tarea tampoco. Teniendo todo esto en cuenta, ¿es correcto decir que tal vez debería comenzar a buscar soluciones que no sean R?
Andy
1
"tenga en cuenta que no hay implementación paralela de RF en R". Eso es solo parcialmente correcto, ya que el foreachpaquete juega muy bien con el randomForestpaquete. Creo que hay un ejemplo en la viñeta foreach. (O tal vez doMC.)
crayola
@Andy La cuestión es que, a menos que reescriba los algoritmos en un lenguaje de programación de bajo nivel, no estoy seguro de qué software podrá aplicar estos algoritmos a sus datos. Si estuviera en su situación, supongo que me quedaría con R y volvería a escribir partes de randomForesttal manera que consultara las columnas elegidas al azar de, por ejemplo, una base de datos SQL en cada iteración (de modo que las dimensiones completas de 300k nunca tendrían estar en ram). Pero eso es probablemente principalmente porque sé más sobre R que sobre las otras opciones posibles.
crayola
¿Qué quiere decir exactamente al afirmar que no pudo encontrar una biblioteca que se adaptara a eso? Los filtros como este son álgebra básica y deberían funcionar sin problemas (siempre que tenga suficiente RAM).
@crayola Es cierto, pero la parte de fusión es horrible. Además, no es paralelismo mem compartido, por lo que probablemente sería doloroso (si no imposible) en este contexto.