Scikit-Узнайте, как получить ненормализованную оценку важности от RandomForestRegressor

#python #scikit-learn #random-forest

Вопрос:

Я хотел бы получить ненормализованную оценку важности от RandomForestRegressor.

После установки регрессора я могу получить доступ к feature_importances_ тому, что содержит нормализованную оценку важности.

Чтобы получить ненормализованный балл, я попробовал это, но это не сработало. Я не могу получить правильные значения:

 arr = []
for i in range(0,len(clf.feature_importances_)):
  arr.append(np.array(clf.feature_importances_)[0:i].sum())

non_normalized = clf.feature_importances_*arr
 

Есть ли возможность отключить нормализацию?

Ответ №1:

Важность всегда нормализуется до 1, даже если вы переходите к каждому регрессору дерева решений, например:

 import numpy as np
import pandas as pd
from sklearn.datasets import load_boston
from sklearn.ensemble import RandomForestRegressor

boston = load_boston()

X = pd.DataFrame(boston.data, columns=boston.feature_names)
y = boston.target

X_train, X_test,y_train, y_test = train_test_split(X,y,test_size=0.3)

rf = RandomForestRegressor(n_estimators=100)
rf.fit(X_train, y_train)
 

Вы можете видеть, что в каждом дереве значения важности уже нормализованы:

 [x.feature_importances_.sum() for x in rf.estimators_]
 
[1.0,
0.9999999999999999,
 1.0,
 1.0,
 0.9999999999999999,
 1.0,
 0.9999999999999998,...
 

Не так уж тривиально вытащить уменьшение mse для дерева и пересчитать. Одним из альтернативных решений было бы использовать permutation_importance r в квадрате или rmse в качестве меры, чтобы получить оценку того, насколько важной будет каждая функция, эти значения не нормализуются:

 from sklearn.inspection import permutation_importance
importance_r2 = permutation_importance(rf, X_test, y_test,scoring="r2")
importance_rmse = permutation_importance(rf, X_test,
 y_test,scoring="neg_root_mean_squared_error")
 

И составление графика результатов:

 fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6))
ax1.boxplot(importance_r2.importances.T, vert=False,labels=X_test.columns)
ax1.set_xlabel('Decrease in R2')
ax2.boxplot(importance_rmse.importances.T, vert=False,labels=X_test.columns)
ax2.set_xlabel('Decrease in RMSE')
fig.tight_layout()
 

введите описание изображения здесь

Ответ №2:

Поскольку случайный лес-это метод ансамбля, основанный на дереве решений, вы можете получить доступ к базовым деревьям решений с атрибутом clf.estimators_ RandomForestRegressor. С помощью списка деревьев вы можете получить доступ к важности функций каждого дерева решений :

 feat_imp = [tree.feature_importances_ for tree in clf.estimators_]
 

Комментарии:

1. Спасибо вам, но мне также нужен OOB, когда начальная загрузка в TRUE и, похоже, OOB для каждого дерева недоступна ?

Ответ №3:

По умолчанию значения нормализуются до 1. Однако это можно изменить, обратившись к деревьям случайного леса или модели дерева решений и вызвав функцию для вычисления значений normalize=False .

Во-первых, вот пример регрессии с одним деревом решений:

 from sklearn.datasets import load_diabetes
from sklearn import tree

X, y = load_diabetes(return_X_y=True)
model = tree.DecisionTreeRegressor(random_state=0)
model.fit(X,y)
model.tree_.compute_feature_importances(normalize=False)
 
 array([ 273.29445957,   55.8130721 , 1383.95383906,  447.64458872,
        414.2412427 ,  412.20392795,  423.76003212,   77.75521807,
       2063.37527614,  377.84324049])
 

Для случайного леса есть дополнительный шаг. Сначала нам нужно получить доступ к каждому дереву, вычислить значения функций для каждого дерева, а затем выполнить среднее значение по деревьям:

 import numpy as np
from sklearn.datasets import load_diabetes
from sklearn.ensemble import RandomForestRegressor

X, y = load_diabetes(return_X_y=True)
model = RandomForestRegressor(random_state=0)
model.fit(X,y)

importances = np.zeros((model.n_estimators, model.n_features_))
for i,tree in enumerate(model.estimators_):
    importances[i] = tree.tree_.compute_feature_importances(normalize=False)
np.mean(importances, axis=0)
 
 array([ 363.40653952,   78.42318883, 1767.47349563,  564.32760593,
        275.84188613,  318.61079764,  310.57670354,  160.56454205,
       1655.62870107,  424.28382897])