2

Вот простой пример моей проблемы, используя набор данных Iris. Я озадачен, когда пытаюсь понять, как вычисляется значение важности и как это видно при визуализации леса оценок с использованием export_graphviz. Вот мой код:Как значение важности и структуры леса связаны в scikit-learn RandomForestClassifier?

import pandas as pd 
import numpy as np 
from sklearn.datasets import load_iris 
import matplotlib.pyplot as plt 

data = load_iris() 
X = pd.DataFrame(data=data.data,columns=['sepallength', 'sepalwidth', 'petallength','petalwidth']) 
y = pd.DataFrame(data=data.target) 

from sklearn.cross_validation import train_test_split 
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42) 

from sklearn.ensemble import RandomForestClassifier 
rf = RandomForestClassifier(n_estimators=2,max_depth=1) 
rf.fit(X_train,y_train.iloc[:,0]) 

Классификатор работает плохо (оценка 0,68), так как лес содержит 2 дерева с глубиной 1. В любом случае это не имеет значения здесь.

Функция значение извлекается следующим образом:

importances = rf.feature_importances_ 
std = np.std([rf.feature_importances_ for tree in rf.estimators_],axis=0) 
indices = np.argsort(importances)[::-1] 

print("Feature ranking:") 
for f in range(X.shape[1]): 
    print("%d. feature %s (%f)" % (f + 1, X.columns.tolist()[f], importances[indices[f]])) 

и выход:

Feature ranking: 
1. feature sepallength (1.000000) 
2. feature sepalwidth (0.000000) 
3. feature petallength (0.000000) 
4. feature petalwidth (0.000000) 

Теперь, когда показывающий структуру деревьев, которые построены, используя следующий код:

from sklearn.tree import export_graphviz 
export_graphviz(rf.estimators_[0], 
       feature_names=X.columns, 
       filled=True, 
       rounded=True) 
!dot -Tpng tree.dot -o tree0.png 
from IPython.display import Image 
Image('tree0.png') 

Я получаю эти 2 цифры

  • экспорт дерева # 0:

enter image description here

  • экспорт дерева # 1:

enter image description here

Я не могу понять, как sepallength может иметь значение = 1, но не u sed для разделения узлов в обоих деревьях (используется только petallength), как показано на рисунке.

ответ

2

У Вас есть ошибка в

for f in range(X.shape[1]): 
    print("%d. feature %s (%f)" % (f + 1, X.columns.tolist()[f], importances[indices[f]])) 

Если вы переставить с indices = np.argsort(importances)[::-1], то вам нужно переставить все - не держать этикетки в соответствии с одним заказа, и важности в соответствии с другим порядком.

Если заменить выше по

for f in range(X.shape[1]): 
    print("%d. feature %s (%f)" % (f + 1, X.columns.tolist()[f], importances[f])) 

тогда лес и его деревья все согласны, что функция с индексом 2 является единственным с любой важности.