scikit-learn RandomForestClassifier 中的特征重要性和森林结构如何相关?
How feature importance and forest structures are related in scikit-learn RandomForestClassifier?
这是我的问题的一个简单示例,使用 Iris 数据集。
当我试图理解特征重要性是如何计算的,以及在使用 export_graphviz
可视化估计器森林时它是如何可见的时,我感到很困惑。
这是我的代码:
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:
- 导出树 #1:
我无法理解 sepallength
如何具有 importance=1 但不用于 两棵树中的节点拆分(仅使用 petallength
)作为如图所示
你在
中有一个错误
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 处的特征是唯一具有重要性的特征。
这是我的问题的一个简单示例,使用 Iris 数据集。
当我试图理解特征重要性是如何计算的,以及在使用 export_graphviz
可视化估计器森林时它是如何可见的时,我感到很困惑。
这是我的代码:
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:
- 导出树 #1:
我无法理解 sepallength
如何具有 importance=1 但不用于 两棵树中的节点拆分(仅使用 petallength
)作为如图所示
你在
中有一个错误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 处的特征是唯一具有重要性的特征。