La importancia de la característica con el bosque aleatorio scikit-learn muestra una desviación estándar muy alta

13

Estoy usando el clasificador de bosque aleatorio scikit-learn y quiero trazar la importancia de la característica, como en este ejemplo .

Sin embargo, mi resultado es completamente diferente, en el sentido de que la desviación estándar de la importancia de la característica es casi siempre mayor que la importancia de la característica misma (ver imagen adjunta).

importancia de la característica

¿Es posible tener este tipo de comportamiento, o estoy cometiendo algunos errores al trazarlo?

Mi código es el siguiente:

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestClassifier

clf = RandomForestClassifier()
clf.fit(predictors.values, outcome.values.ravel())

importance = clf.feature_importances_
importance = pd.DataFrame(importance, index=predictors.columns, 
                          columns=["Importance"])

importance["Std"] = np.std([tree.feature_importances_
                            for tree in clf.estimators_], axis=0)

x = range(importance.shape[0])
y = importance.ix[:, 0]
yerr = importance.ix[:, 1]

plt.bar(x, y, yerr=yerr, align="center")

plt.show()
gc5
fuente
IIUC, predictorsdevuelve un objeto al que hace numpy arrayreferencia a un pandas Dataframeobjeto por sus columnas que es incorrecto ya numpy arraysque no tiene el atributo columns.
Nickil Maveli
Lo sentimos, fue un error tipográfico en el código. Los predictores y el resultado son dos pandas DataFramecon forma m x ny m x 1. Debería estar claro ahora.
gc5
2
Me he encontrado con los mismos hallazgos hace un tiempo. Podría ser que esto se deba al hecho de que una serie de características son importantes, pero como las características pueden ser altas o bajas en el árbol de decisión (ya que solo se ofrece un subconjunto aleatorio al hacer una división), su importancia varía mucho de un árbol a otro. árbol, lo que resulta en una desviación estándar alta.
Archie
Gran publicación, me he encontrado con un problema idéntico como puedes ver en la imagen. ¡Hay un paquete tsfreshque me ayudó a identificar características relevantes y reducir mis características de 600+ a alrededor de 400. ! [Mis 35 características principales ] ( i.stack.imgur.com/0MROZ.png ) Incluso con esto, el algoritmo está funcionando bien para mi. Tengo una clasificación binaria, éxito / fracaso. Prácticamente no obtengo falsos éxitos, pero extraño un porcentaje considerable de éxitos. Todas las conjeturas anteriores parecen razonables. Podría ser el caso de que deba haber un conjunto de capacitación y pruebas más amplio. Tengo menos
superhéroe el

Respuestas:

3

Está utilizando RandomForest con el número predeterminado de árboles, que es 10. Para alrededor de 30 funciones, esto es muy poco. Por lo tanto, la desviación estándar es grande. Pruebe al menos 100 o incluso 1000 árboles, como

clf = RandomForestClassifier(n_estimators=1000)

Para un análisis más refinado, también puede verificar qué tan grande es la correlación entre sus características.

Lanenek
fuente
Lo sentimos, Lane, la cantidad de árboles no es la predeterminada. Puse un código de ejemplo (y esto es cierto para todos los parámetros, por ejemplo min_samples_split) porque no puedo revelar los datos en los que estoy trabajando. Sin embargo, ¿se debe a la cantidad de árboles, más otros parámetros, o estoy cometiendo algunos errores aquí?
gc5
2

Tu resultado no es tan raro. Como dice lanenok , en un primer paso debe aumentar el número de árboles para asegurarse de obtener un resultado 'estadístico' con respecto a las características importantes.

Sin embargo, como este artículo de Genuer et al. (2010) muestra que, en realidad, puede usar las desviaciones estándar para eliminar funciones. Para citar: " Podemos ver que las desviaciones estándar de las variables verdaderas son grandes en comparación con las variables ruidosas, que está cerca de cero " .

Archie
fuente
El uso de la desviación estándar en este ejemplo para eliminar características eliminaría todas las características. xD
Jorge Leitao
Jaja, no estoy del todo seguro, creo que podrías descartar las características en el extremo derecho. De todos modos, el punto principal que estoy tratando de hacer es que las desviaciones de alto estándar no son tan extrañas, y que en realidad puedes usarlas en tu estrategia para eliminar características.
Archie
1

Tratar clf = RandomForestClassifier(max_features=None). El max_featuresparámetro predeterminado 'auto'es el equivalente a sqrt(n_features). max_featuresse describe como "El número de características a tener en cuenta al buscar la mejor división". Solo mirar una pequeña cantidad de características en cualquier punto del árbol de decisiones significa que la importancia de una sola característica puede variar ampliamente en muchos árboles. Por lo tanto, no mire un subconjunto aleatorio, solo mire todas las características en cada nivel del árbol.

jamis
fuente
1
Tenga en cuenta que este es el equivalente a los árboles en bolsas simples. El "aleatorio" en bosques aleatorios significa considerar un subconjunto aleatorio de características en cada división, generalmente sqrt(n_features)o log2(n_features). max_features=Noneya no considera un subconjunto aleatorio de características. No estoy seguro de si esto afecta la solución propuesta anteriormente. Una posibilidad es que muchas características simplemente tienen una gran importancia y, por lo tanto, varían ampliamente en el conjunto de árboles. O tal vez no hay suficientes muestras y, por lo tanto, no se consideran todas las características cuando se toca una hoja.
jamis
1

Una razón común para esto es que los parámetros que proporcionó (o los valores predeterminados) RandomForestClassifierno son adecuados para su conjunto de datos.

Una forma común de abordar este problema es buscar en el espacio del hiperparámetro usando, por ejemplo GridSearchCV:

from sklearn.model_selection import GridSearchCV
from sklearn.metrics import accuracy_score, make_scorer

param_grid = {'n_estimators': [10, 100, 1000], 'max_features': [5, 10, 20, 30]}
clf = GridSearchCV(RandomForestClassifier(), param_grid, cv=5, scoring=make_scorer(accuracy_score))

param_gridAquí están las permutaciones de los parámetros en los que desea buscar y make_scorer(accuracy_score)la medida que desea optimizar.

Tenga en cuenta que accuracy_scorees adecuado para conjuntos equilibrados, pero no para conjuntos no equilibrados. Elija una métrica adecuada para su objetivo particular.

Jorge Leitao
fuente
0

Podría haber múltiples razones. La cantidad de árboles y la profundidad pueden cambiar sus resultados. Si su modelo no funciona bien después de seleccionar los parámetros (validación cruzada, etc.), probablemente sea porque sus características no son muy predictivas, por lo que se seleccionan casi "al azar", lo que conduce a desviaciones estándar altas de un árbol a otro. Pero hay otras posibilidades, por ejemplo, también podría ser que sus características estén altamente correlacionadas. Un poco más de información sería útil.

oW_
fuente