在
Sklearn
#15075 中提出了实现这一点的建议,但与此同时,建议将 eli5
作为解决方案。但是,我不确定我是否以正确的方式使用它。这是我的代码:
from sklearn.datasets import make_friedman1
from sklearn.feature_selection import RFECV
from sklearn.svm import SVR
import eli5
X, y = make_friedman1(n_samples=50, n_features=10, random_state=0)
estimator = SVR(kernel="linear")
perm = eli5.sklearn.PermutationImportance(estimator, scoring='r2', n_iter=10, random_state=42, cv=3)
selector = RFECV(perm, step=1, min_features_to_select=1, scoring='r2', cv=3)
selector = selector.fit(X, y)
selector.ranking_
#eli5.show_weights(perm) # fails: AttributeError: 'PermutationImportance' object has no attribute 'feature_importances_'
有几个问题:
我不确定我是否以正确的方式使用交叉验证。
PermutationImportance
正在使用cv
来验证验证集的重要性,或者交叉验证应该只使用RFECV
? (在示例中,我在两种情况下都使用了 cv=3
,但不确定这是否正确)
如果我取消注释最后一行,我会得到一个
AttributeError: 'PermutationImportance' ...
,这是因为我适合使用RFECV
吗?我正在做的事情与这里的最后一个片段类似:https://eli5.readthedocs.io/en/latest/blackbox/permutation_importance.html
作为一个不太重要的问题,当我在
cv
中设置 eli5.sklearn.PermutationImportance
时,这会给我一个警告:
.../lib/python3.8/site-packages/sklearn/utils/validation.py:68: FutureWarning: Pass classifier=False as keyword args. From version 0.25 passing these as positional arguments will result in an error warnings.warn("Pass {} as keyword args. From version 0.25 "
整个过程有点模糊。 有没有办法直接在
Sklearn
中进行?例如通过添加 feature_importances
属性?
由于目标是选择具有排列重要性和递归特征消除的最佳特征数量,因此我建议将
RFECV
和 PermutationImportance
与 CV 分割器(如 KFold
)结合使用。代码可能如下所示:
import warnings
from eli5 import show_weights
from eli5.sklearn import PermutationImportance
from sklearn.datasets import make_friedman1
from sklearn.feature_selection import RFECV
from sklearn.model_selection import KFold
from sklearn.svm import SVR
warnings.filterwarnings("ignore", category=FutureWarning)
X, y = make_friedman1(n_samples=50, n_features=10, random_state=0)
splitter = KFold(n_splits=3) # 3 folds as in the example
estimator = SVR(kernel="linear")
selector = RFECV(
PermutationImportance(estimator, scoring='r2', n_iter=10, random_state=42, cv=splitter),
cv=splitter,
scoring='r2',
step=1
)
selector = selector.fit(X, y)
selector.ranking_
show_weights(selector.estimator_)
关于您的问题:
PermutationImportance
将根据RFECV
提供的分割以相同的策略计算特征重要性和KFold
r2评分。
您对未安装的
show_weights
对象调用了 PermutationImportance
。这就是你收到错误的原因。您应该使用 estimator_
属性访问拟合的对象。
可以忽略。
您可以使用 sklearn 直接计算 RFECV,方法是构建计算特征重要性的估计器,在调用 fit 时使用您想要的任何逻辑。
如果您想使用 SVR 回归器基于排列来计算特征重要性,则必须实现的估计器是:
from sklearn.inspection import permutation_importance
from sklearn.model_selection import train_test_split
from sklearn.svm import SVR
class SVRExplainerRegressor(SVR):
def fit(self, X,y):
X_train, X_val, y_train, y_val = train_test_split(
X, y, test_size=0.25, random_state=42, shuffle=True
)
super().fit(X_train,y_train)
self.feature_importances_ = permutation_importance(
self, X_val, y_val,
n_repeats=5, random_state=42,
)['importances_mean']
return super().fit(X,y)
SVRExplainerRegressor
执行以下操作:
SVRExplainerRegressor
可以像任何 sklearn 模型一样用作 RFECV 的估计器,如下所示:
from sklearn.feature_selection import RFECV
from sklearn.datasets import make_friedman1
X, y = make_friedman1(n_samples=50, n_features=10, random_state=0)
model = SVRExplainerRegressor(kernel="linear")
selector = RFECV(model, step=1, min_features_to_select=1, scoring='r2', cv=3)
selector.fit(X, y)
可以使用任何估计器(回归器或分类器)和任何特征重要性逻辑(如 SHAP 或类似逻辑)来自定义此逻辑