特征重要性 - Bagging、scikit-learn
Feature importances - Bagging, scikit-learn
对于一个项目,我正在使用 scikit-learn 的回归算法(随机森林、额外树、Adaboost 和装袋)比较许多决策树。
为了比较和解释它们,我使用了特征 importance ,尽管对于装袋决策树这看起来不可用。
我的问题:有人知道如何获取 Bagging 的特征重要性列表吗?
你好,Kornee
你说的是 BaggingClassifier 吗?它可以与许多基本估计器一起使用,因此没有实现特征重要性。有一些独立于模型的方法来计算特征重要性(参见 https://github.com/scikit-learn/scikit-learn/issues/8898),scikit-learn 不使用它们。
如果决策树作为基础估计器,您可以自己计算特征重要性:它只是 bagging.estimators_
中所有树的 tree.feature_importances_
的平均值:
import numpy as np
from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
X, y = load_iris(return_X_y=True)
clf = BaggingClassifier(DecisionTreeClassifier())
clf.fit(X, y)
feature_importances = np.mean([
tree.feature_importances_ for tree in clf.estimators_
], axis=0)
RandomForestClassifer 在内部进行相同的计算。
我遇到了同样的问题,平均特征重要性是我感兴趣的。此外,我需要有一个 feature_importance_ 属性由装袋分类器对象公开(即可访问)。这对于在另一个 scikit-learn 算法中使用是必要的(即带有 ROC_AUC 记分员的 RFE)。
我选择重载 BaggingClassifier,以直接访问基本估计量的均值 feature_importance(或“coef_”参数)。
操作方法如下:
class BaggingClassifierCoefs(BaggingClassifier):
def __init__(self,**kwargs):
super().__init__(**kwargs)
# add attribute of interest
self.feature_importances_ = None
def fit(self, X, y, sample_weight=None):
# overload fit function to compute feature_importance
fitted = self._fit(X, y, self.max_samples, sample_weight=sample_weight) # hidden fit function
if hasattr(fitted.estimators_[0], 'feature_importances_'):
self.feature_importances_ = np.mean([tree.feature_importances_ for tree in fitted.estimators_], axis=0)
else:
self.feature_importances_ = np.mean([tree.coef_ for tree in fitted.estimators_], axis=0)
return(fitted)
扩展 CharlesG 发布的内容,这是我重载 BaggingRegressor 的解决方案(同样适用于 BaggingClassifier)。
class myBaggingRegressor(BaggingRegressor):
def fit(self, X, y):
fitd = super().fit(X, y)
# need to pad features?
if self.max_features == 1.0:
# compute feature importances or coefficients
if hasattr(fitd.estimators_[0], 'feature_importances_'):
self.feature_importances_ = np.mean([est.feature_importances_ for est in fitd.estimators_], axis=0)
else:
self.coef_ = np.mean([est.coef_ for est in fitd.estimators_], axis=0)
self.intercept_ = np.mean([est.intercept_ for est in fitd.estimators_], axis=0)
else:
# need to process results into the right shape
coefsImports = np.empty(shape=(self.n_features_, self.n_estimators), dtype=float)
coefsImports.fill(np.nan)
if hasattr(fitd.estimators_[0], 'feature_importances_'):
# store the feature importances
for idx, thisEstim in enumerate(fitd.estimators_):
coefsImports[fitd.estimators_features_[idx], idx] = thisEstim.feature_importances_
# compute average
self.feature_importances_ = np.nanmean(coefsImports, axis=1)
else:
# store the coefficients & intercepts
self.intercept_ = 0
for idx, thisEstim in enumerate(fitd.estimators_):
coefsImports[fitd.estimators_features_[idx], idx] = thisEstim.coefs_
self.intercept += thisEstim.intercept_
# compute
self.intercept /= self.n_estimators
# average
self.coefs_ = np.mean(coefsImports, axis=1)
return fitd
如果 max_features <> 1.0
这会正确处理,但我想如果 bootstrap_features=True
.
将无法正常工作
我想这是因为 sklearn 自 2017 年以来已经发展了很多,但无法让它与构造函数一起工作,而且它似乎并不是完全必要的——唯一的原因是预先指定feature_importances_ 属性为 None。但是,在调用 fit() 之前它甚至不应该存在。
对于一个项目,我正在使用 scikit-learn 的回归算法(随机森林、额外树、Adaboost 和装袋)比较许多决策树。 为了比较和解释它们,我使用了特征 importance ,尽管对于装袋决策树这看起来不可用。
我的问题:有人知道如何获取 Bagging 的特征重要性列表吗?
你好,Kornee
你说的是 BaggingClassifier 吗?它可以与许多基本估计器一起使用,因此没有实现特征重要性。有一些独立于模型的方法来计算特征重要性(参见 https://github.com/scikit-learn/scikit-learn/issues/8898),scikit-learn 不使用它们。
如果决策树作为基础估计器,您可以自己计算特征重要性:它只是 bagging.estimators_
中所有树的 tree.feature_importances_
的平均值:
import numpy as np
from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
X, y = load_iris(return_X_y=True)
clf = BaggingClassifier(DecisionTreeClassifier())
clf.fit(X, y)
feature_importances = np.mean([
tree.feature_importances_ for tree in clf.estimators_
], axis=0)
RandomForestClassifer 在内部进行相同的计算。
我遇到了同样的问题,平均特征重要性是我感兴趣的。此外,我需要有一个 feature_importance_ 属性由装袋分类器对象公开(即可访问)。这对于在另一个 scikit-learn 算法中使用是必要的(即带有 ROC_AUC 记分员的 RFE)。
我选择重载 BaggingClassifier,以直接访问基本估计量的均值 feature_importance(或“coef_”参数)。
操作方法如下:
class BaggingClassifierCoefs(BaggingClassifier):
def __init__(self,**kwargs):
super().__init__(**kwargs)
# add attribute of interest
self.feature_importances_ = None
def fit(self, X, y, sample_weight=None):
# overload fit function to compute feature_importance
fitted = self._fit(X, y, self.max_samples, sample_weight=sample_weight) # hidden fit function
if hasattr(fitted.estimators_[0], 'feature_importances_'):
self.feature_importances_ = np.mean([tree.feature_importances_ for tree in fitted.estimators_], axis=0)
else:
self.feature_importances_ = np.mean([tree.coef_ for tree in fitted.estimators_], axis=0)
return(fitted)
扩展 CharlesG 发布的内容,这是我重载 BaggingRegressor 的解决方案(同样适用于 BaggingClassifier)。
class myBaggingRegressor(BaggingRegressor):
def fit(self, X, y):
fitd = super().fit(X, y)
# need to pad features?
if self.max_features == 1.0:
# compute feature importances or coefficients
if hasattr(fitd.estimators_[0], 'feature_importances_'):
self.feature_importances_ = np.mean([est.feature_importances_ for est in fitd.estimators_], axis=0)
else:
self.coef_ = np.mean([est.coef_ for est in fitd.estimators_], axis=0)
self.intercept_ = np.mean([est.intercept_ for est in fitd.estimators_], axis=0)
else:
# need to process results into the right shape
coefsImports = np.empty(shape=(self.n_features_, self.n_estimators), dtype=float)
coefsImports.fill(np.nan)
if hasattr(fitd.estimators_[0], 'feature_importances_'):
# store the feature importances
for idx, thisEstim in enumerate(fitd.estimators_):
coefsImports[fitd.estimators_features_[idx], idx] = thisEstim.feature_importances_
# compute average
self.feature_importances_ = np.nanmean(coefsImports, axis=1)
else:
# store the coefficients & intercepts
self.intercept_ = 0
for idx, thisEstim in enumerate(fitd.estimators_):
coefsImports[fitd.estimators_features_[idx], idx] = thisEstim.coefs_
self.intercept += thisEstim.intercept_
# compute
self.intercept /= self.n_estimators
# average
self.coefs_ = np.mean(coefsImports, axis=1)
return fitd
如果 max_features <> 1.0
这会正确处理,但我想如果 bootstrap_features=True
.
我想这是因为 sklearn 自 2017 年以来已经发展了很多,但无法让它与构造函数一起工作,而且它似乎并不是完全必要的——唯一的原因是预先指定feature_importances_ 属性为 None。但是,在调用 fit() 之前它甚至不应该存在。