scikit learn - sklearn - ¿Cómo se determina feature_importances en RandomForestClassifier?
random forest sklearn tutorial (6)
Tengo una tarea de clasificación con una serie de tiempo como entrada de datos, donde cada atributo (n = 23) representa un punto específico en el tiempo. Además del resultado de la clasificación absoluta, me gustaría saber qué atributos / fechas contribuyen al resultado en qué medida. Por lo tanto, solo estoy usando feature_importances_
, que funciona bien para mí.
Sin embargo, me gustaría saber cómo se están calculando y qué medida / algoritmo se utiliza. Lamentablemente no pude encontrar ninguna documentación sobre este tema.
Como @GillesLouppe señaló anteriormente, scikit-learn actualmente implementa la métrica de "disminución de la impureza media" para la importancia de las características. Personalmente, encuentro que la segunda métrica es un poco más interesante, ya que permutar los valores de cada una de sus funciones de forma aleatoria uno por uno y ver cuánto peor es el rendimiento de su fuera de bolsa.
Ya que lo que está buscando es lo importante que cada característica contribuye al rendimiento predictivo de su modelo en general, la segunda métrica le da una medida directa de esto, mientras que la "impureza de disminución media" es solo un buen proxy.
Si está interesado, escribí un pequeño paquete que implementa la métrica de importancia de permutación y se puede usar para calcular los valores de una instancia de una clase de bosque aleatorio scikit-learn:
https://github.com/pjh2011/rf_perm_feat_import
Edición: Esto funciona para Python 2.7, no 3
Déjame intentar responder la pregunta. código:
iris = datasets.load_iris()
X = iris.data
y = iris.target
clf = DecisionTreeClassifier()
clf.fit(X, y)
parcela de decision_tree
introduzca la descripción de la imagen aquí
Podemos obtener compute_feature_importance: [0. , 0.01333333,0.06405596,0.92261071]
Compruebe el código fuente:
cpdef compute_feature_importances(self, normalize=True):
"""Computes the importance of each feature (aka variable)."""
cdef Node* left
cdef Node* right
cdef Node* nodes = self.nodes
cdef Node* node = nodes
cdef Node* end_node = node + self.node_count
cdef double normalizer = 0.
cdef np.ndarray[np.float64_t, ndim=1] importances
importances = np.zeros((self.n_features,))
cdef DOUBLE_t* importance_data = <DOUBLE_t*>importances.data
with nogil:
while node != end_node:
if node.left_child != _TREE_LEAF:
# ... and node.right_child != _TREE_LEAF:
left = &nodes[node.left_child]
right = &nodes[node.right_child]
importance_data[node.feature] += (
node.weighted_n_node_samples * node.impurity -
left.weighted_n_node_samples * left.impurity -
right.weighted_n_node_samples * right.impurity)
node += 1
importances /= nodes[0].weighted_n_node_samples
if normalize:
normalizer = np.sum(importances)
if normalizer > 0.0:
# Avoid dividing by zero (e.g., when root is pure)
importances /= normalizer
return importances
Intenta calcular la importancia de la característica:
print("sepal length (cm)",0)
print("sepal width (cm)",(3*0.444-(0+0)))
print("petal length (cm)",(54* 0.168 - (48*0.041+6*0.444)) +(46*0.043 -(0+3*0.444)) + (3*0.444-(0+0)))
print("petal width (cm)",(150* 0.667 - (0+100*0.5)) +(100*0.5-(54*0.168+46*0.043))+(6*0.444 -(0+3*0.444)) + (48*0.041-(0+0)))
Obtenemos feature_importance: np.array ([0,1.332,6.418,92.30]).
Después de normalizado, podemos obtener array ([0., 0.01331334, 0.06414793, 0.92253873]), esto es lo mismo que clf.feature_importances_
.
Tenga cuidado de que todas las clases se supone que tienen un peso uno.
De hecho, hay varias maneras de obtener características "importancias". Como a menudo, no hay un consenso estricto sobre lo que significa esta palabra.
En scikit-learn, implementamos la importancia como se describe en [1] (a menudo citado, pero lamentablemente rara vez se lee ...). A veces se denomina "importancia de gini" o "impureza de disminución media" y se define como la disminución total de la impureza del nodo (ponderada por la probabilidad de alcanzar ese nodo (que se aproxima por la proporción de muestras que llegan a ese nodo) promediada en todos Árboles del conjunto.
En la literatura o en algunos otros paquetes, también puede encontrar importantes funciones implementadas como la "disminución media de la precisión". Básicamente, la idea es medir la disminución de la precisión en los datos OOB cuando permutar aleatoriamente los valores para esa característica. Si la disminución es baja, entonces la característica no es importante, y viceversa.
(Tenga en cuenta que ambos algoritmos están disponibles en el paquete randomForest R).
[1]: Breiman, Friedman, "Clasificación y árboles de regresión", 1984.
Es la relación entre el número de muestras enrutadas a un nodo de decisión que involucra esa característica en cualquiera de los árboles del conjunto sobre el número total de muestras en el conjunto de entrenamiento.
Las características que están involucradas en los nodos de nivel superior de los árboles de decisión tienden a ver más muestras, por lo que es probable que tengan más importancia.
Edición : esta descripción solo es parcialmente correcta: las respuestas de Gilles y Peter son la respuesta correcta.
La forma habitual de calcular los valores de importancia de la característica de un solo árbol es la siguiente:
inicializa una matriz
feature_importances
de todos los ceros con tamañon_features
.atraviesa el árbol: para cada nodo interno que se divide en la función
i
se calcula la reducción de errores de ese nodo multiplicada por la cantidad de muestras que se enrutaron al nodo y se agrega esta cantidad afeature_importances[i]
.
La reducción de errores depende del criterio de impureza que utilice (por ejemplo, Gini, Entropy, MSE, ...). Es la impureza del conjunto de ejemplos que se enruta al nodo interno menos la suma de las impurezas de las dos particiones creadas por la división.
Es importante que estos valores sean relativos a un conjunto de datos específico (tanto la reducción de errores como el número de muestras son específicos del conjunto de datos), por lo que estos valores no se pueden comparar entre diferentes conjuntos de datos.
Por lo que sé, hay formas alternativas de calcular los valores de importancia de las características en los árboles de decisión. Una breve descripción del método anterior se puede encontrar en "Elementos del aprendizaje estadístico" por Trevor Hastie, Robert Tibshirani y Jerome Friedman.
Para aquellos que buscan una referencia a la documentación de scikit-learn sobre este tema o una referencia a la respuesta de @GillesLouppe:
En RandomForestClassifier, el atributo estimators_
es una lista de DecisionTreeClassifier (como se menciona en la documentation ). Para calcular el feature_importances_
para el RandomForestClassifier, en el código fuente de scikit-learn , promedia todos los atributos feature_importances_
del conjunto estimador (todos DecisionTreeClassifer) en el conjunto.
En la documentation de DecisionTreeClassifer, se menciona que "La importancia de una característica se calcula como la reducción total (normalizada) del criterio que ofrece esa característica. También se conoce como la importancia de Gini [1]".
Here hay un enlace directo para obtener más información sobre la variable y la importancia de Gini, como se indica en la referencia de scikit-learn a continuación.
[1] L. Breiman y A. Cutler, “Random Forests”, http://www.stat.berkeley.edu/~breiman/RandomForests/cc_home.htm