Mejora la clasificación con muchas variables categóricas

37

Estoy trabajando en un conjunto de datos con más de 200,000 muestras y aproximadamente 50 características por muestra: 10 variables continuas y las otras ~ 40 son variables categóricas (países, idiomas, campos científicos, etc.). Para estas variables categóricas, tiene por ejemplo 150 países diferentes, 50 idiomas, 50 campos científicos, etc.

Hasta ahora mi enfoque es:

  1. Para cada variable categórica con muchos valores posibles, tome solo la que tenga más de 10000 muestras que tome este valor. Esto se reduce a 5-10 categorías en lugar de 150.

  2. Cree una variable ficticia para cada una categórica (si hay 10 países, agregue para cada muestra un vector binario de tamaño 10).

  3. Alimente un clasificador de bosque aleatorio (validación cruzada de los parámetros, etc.) con estos datos.

Actualmente con este enfoque, solo logro obtener un 65% de precisión y siento que se puede hacer más. Especialmente no estoy satisfecho con mi 1) ya que siento que no debería eliminar arbitrariamente los "valores menos relevantes" de acuerdo con el número de muestra que tienen, porque estos valores menos representados podrían ser más discriminatorios. Por otro lado, mi RAM no puede permitirse agregar 500 columnas * 200000 filas a los datos manteniendo todos los valores posibles.

¿Tendrías alguna sugerencia para hacer frente a tantas variables categóricas?

Bertrand R
fuente
2
Si todavía está interesado, puede consultar mi respuesta sobre reducción de dimensionalidad y mi respuesta sobre clasificación jerárquica .
Aleksandr Blekh
1
Cuando dice "construir variable ficticia para cada una categórica" , ¿parece que está utilizando Python no R? R randomforest puede manejar categóricamente, también la reducción de memoria consecuente. Prueba R.
smci
Ver también stats.stackexchange.com/questions/146907/…
kjetil b halvorsen

Respuestas:

20

1) Los bosques aleatorios deberían poder manejar los valores categóricos de forma nativa, así que busque una implementación diferente para que no tenga que codificar todas esas características y usar toda su memoria.

2) El problema con las características categóricas de alta cardinalidad es que es fácil ajustarlas en exceso. Es posible que tenga suficientes datos para que esto no sea un problema, pero tenga cuidado.

3) Sugiero buscar en una selección aleatoria de características basadas en el bosque usando el método propuesto por Brieman o contrastes artificiales . El método de contrastes artificiales (ACE) es interesante porque compara la importancia de la característica con la importancia de una versión aleatoria de sí mismo que combate algunos de los problemas de alta cardinalidad. Hay un nuevo documento "Bosques aleatorios guiados por módulos" que podría ser interesante si tuviera muchas más características, ya que utiliza un método de selección de características que conoce grupos de características altamente correlacionadas.

4) Otra opción que alguna vez se usa es ajustar el algoritmo para que use las cajas sin bolsa para hacer la selección final de características después de ajustar las divisiones en las cajas en bolsa, lo que a veces ayuda a combatir el sobreajuste.

Hay una aplicación ace casi completa aquí y tengo un effichent más memoria aplicación / rf rápido que maneja las variables categóricas de forma nativa aquí ... la opción apoya la opción -evaloob 4 Yo estoy trabajando para añadir soporte para ACE y un par de otros rf basados ​​en métodos de selección de funciones pero aún no se ha hecho

Ryan Bressler
fuente
44
Todas estas sugerencias son interesantes, estoy de acuerdo en que el bosque aleatorio debe manejar variables categóricas nativas, pero scikit-learn no ... Creo que ese es uno de los principales defectos de scikit por cierto. ¡Probaré su código en mis datos para ver qué sucede y veré sus otras sugerencias!
Bertrand R
1
Pruebe la implementación de R. Ejecutarlo es un trazador de líneas. Leer los datos es extremadamente fácil y hay una nueva implementación paralela que es increíblemente rápida y eficiente en memoria: r-bloggers.com/… Por otro lado. ¿Están tus clases desequilibradas? en la implementación r puede hacer crecer cada árbol a partir de una muestra de bootstrap equilibrada sampsize = c (x, x). Esto ha producido mejores clasificaciones binarias para mí. Puede jugar con los tamaños y ajustar la clasificación muy fácilmente utilizando las salidas R de matriz de confusión OOB.
JEquihua
2
La implementación randomForest de R permite factores con un máximo de 32 niveles. scikit-learn es menos restrictivo, ya que primero crea variables ficticias (consulte la pandas.get_dummiesfunción). La implementación de H2O del bosque aleatorio me ha funcionado muy bien (ver 0xdata.com/docs/master/model/rf ).
Alex Woolford
1
hay una implementación más nueva y más rápida de bosque aleatorio, el paquete se llama ranger. Grandes cosas realmente. Órdenes de magnitud más rápido y no tiene el límite de 32 niveles.
marbel
6

En lugar de dummificar sus categorías, ¿por qué no usaría una sola variable numérica para cada una? En el contexto de los bosques aleatorios, a menudo me he estado preguntando sobre la consecuencia de hacerlo (porque estoy de acuerdo en que suena sospechoso introducir la ordinalidad en datos categóricos con los que, si no tiene sentido), pero en la práctica (al menos con la implementación scikit-learn de los RF que he estado usando), a menudo he observado que no hace una diferencia en los resultados (aunque no estoy seguro de por qué).

cjauvin
fuente
1
Esto está bien para las características categóricas con n <= 3, ya que puede generar las mismas divisiones que lo haría al considerar la característica de forma nativa como categórica. Para n más grande es posible lograr conjuntos de divisiones que son equivalentes a la división categórica, pero el algoritmo puede o no encontrarlos de manera tan eficiente ... sin embargo, si divide la función en n funciones numéricas, también está reduciendo la eficiencia con la cual El algoritmo puede encontrar divisiones. Alguien necesita agregar soporte de variables categóricas a la implementación de scikit-learn ya que de lo contrario es excelente.
Ryan Bressler
Estoy de acuerdo con usted cuando dice que suena sospechoso introducir ordinalidad en datos categóricos ... ¡Prefiero no tener que hacerlo, pero al menos puedo intentarlo y ver qué sucede!
Bertrand R
44
Tuve una larga discusión sobre esta pregunta en la lista de correo de sklearn (puede leer partes de ella aquí: mail-archive.com/[email protected]/… ). La opinión de uno de los implementadores fue que con árboles suficientemente profundos, las características categóricas codificadas ordinales podrían funcionar razonablemente bien (además de ser más eficientes computacionalmente). De todos modos, si lo intentas, estaría muy interesado en escuchar tus resultados / conclusión, ya que este es un problema con el que me encuentro constantemente.
cjauvin
1
Así que traté de mantener una única variable numérica para las categóricas, y en realidad funciona sorprendentemente bien, y mucho mejor que agregar una gran cantidad de entradas binarias ... También intenté ordenar los valores de acuerdo con su wrt media al objetivo . Y también funciona bien
Bertrand R
Eso no me sorprende en realidad ... está en línea con lo que he observado en un par de configuraciones diferentes, aunque a juzgar por el número de votos a favor, esta es una idea bastante intuitiva.
cjauvin
5

Creo que debería considerar una o más técnicas de reducción variable . Se deshace de los predictores no tan influyentes.

He estado leyendo mucho sobre el procesamiento previo de datos y es una excelente solución para reducir el n ° de sus variables.

Mis sugerencias son las siguientes:

  • para variables cualitativas , reemplace los valores faltantes con la categoría "faltante". Puede introducir sesgo si los datos no faltan al azar, pero al menos tendrá todas sus observaciones intactas y la falta podría revelar un comportamiento diferente.
  • elimine los predictores de variación cero o los predictores de variación cercana a cero (tenga cuidado de no eliminar las variables ficticias con categorías desequilibradas altas que pueden separar su Y de manera eficiente. Haga algunos gráficos para las variables que considere importantes). En R, puede usar la 'nzv'función del 'caret'paquete. Esto reducirá en gran medida su dimensión de datos.
  • Eliminar predictores correlacionados . Utilice la matriz de correlación de Kendall porque es más adecuado construir en presencia de variables categóricas. La desventaja es que tiene que transformar todos sus valores nominales en categóricos.
  • existen métodos de selección de características que reducirán su número aún más (agrupamiento: usted elige un solo representante de cada grupo, la regresión LASSO, etc.). Todavía no he tenido la oportunidad de probarlos porque los otros pasos redujeron mis variables a menos de 100.

Además, sugeriría usar el algoritmo AdaBoost en lugar de RF. Personalmente, las investigaciones que he realizado me dieron coeficientes de Gini muy similares para ambos métodos. Lo bueno de AdaBoost es que en R maneja las observaciones que faltan. Entonces puede omitir el primer paso de esta lista

Espero que haya ayudado un poco. Buena suerte

lorelai
fuente
4

Es posible que desee considerar modelos de efectos mixtos. Son populares en las ciencias sociales debido a su rendimiento en datos categóricos de alta cardinalidad, y los he usado para crear excelentes modelos predictivos que superan los enfoques populares de aprendizaje automático, como árboles impulsados ​​por gradientes, bosques aleatorios y regresión logística regularizada de red elástica. La implementación más conocida es el paquete lme4 de R; la función que usaría para la clasificación es glmer, que implementa la regresión logística de efectos mixtos. Es posible que tenga problemas para escalar su conjunto de datos, pero he realizado 80k filas con 15 características sin demasiada dificultad.

Paul
fuente
2
  1. Cuando dice "construir variable ficticia para cada una categórica" , ¿parece que está utilizando Python no R? R randomforest puede manejar categóricamente, también la reducción de memoria consecuente. Intenta con R.

  2. A continuación, no necesita podar / fusionar manualmente los niveles categóricos, eso suena como un gran dolor. E incluso si lo hiciera, no está garantizado que las categorías más pobladas sean las más predictivas. Controle la complejidad del bosque aleatorio con el tamaño de los nodos de parámetros : comience con un tamaño de nodos grande y reduzca progresivamente (esto es una búsqueda de hiperparámetros).

  3. La selección de variables será útil. @lorelai da buenas recomendaciones. Intente eliminar las características inútiles (de baja importancia o altamente correlacionadas). La construcción del árbol es cuadrática para la cantidad de características, por lo que si incluso elimina un tercio, pagará dividendos.

smci
fuente
0

Deberías mirar el paquete H2O.ai. Maneja las variables categóricas fuera de la caja sin tener que hacer ninguna codificación (asegúrese de que las variables sean factores).

Particularmente me gusta su implementación de Gradient Boosted Machine (GBM) porque puedes ver la importancia variable después de construir el modelo. Los GBM también tienen la buena característica de ser resistentes al sobreajuste.

Si desea explorar otros modelos, tienen: GLM, Random Forest, Naive Bayes, Deep Learning, etc.

Ver: http://docs.h2o.ai/h2o/latest-stable/h2o-docs/data-science/gbm.html

También es fácil de instalar (Windows, Linux, Mac) y fácil de ejecutar con API que usan R, Python, Java y Scala.

Puede usar múltiples núcleos para acelerar las cosas.

En un futuro cercano, admitirán GPU.

También es de código abierto y gratuito (hay soporte de Enterprise).

Clem Wang
fuente