使用 RFECV 和排列重要性的正确方法 - Sklearn

问题描述 投票:0回答:2

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_'

有几个问题:

  1. 我不确定我是否以正确的方式使用交叉验证。

    PermutationImportance
    正在使用
    cv
    来验证验证集的重要性,或者交叉验证应该只使用
    RFECV
    ? (在示例中,我在两种情况下都使用了
    cv=3
    ,但不确定这是否正确)

  2. 如果我取消注释最后一行,我会得到一个

    AttributeError: 'PermutationImportance' ...
    ,这是因为我适合使用
    RFECV
    吗?我正在做的事情与这里的最后一个片段类似:https://eli5.readthedocs.io/en/latest/blackbox/permutation_importance.html

  3. 作为一个不太重要的问题,当我在

    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
属性?

python scikit-learn cross-validation feature-selection eli5
2个回答
3
投票

由于目标是选择具有排列重要性和递归特征消除的最佳特征数量,因此我建议将

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_)

关于您的问题:

  1. PermutationImportance
    将根据
    RFECV
    提供的分割以相同的策略计算特征重要性和
    KFold
    r2评分。

  2. 您对未安装的

    show_weights
    对象调用了
    PermutationImportance
    。这就是你收到错误的原因。您应该使用
    estimator_
    属性访问拟合的对象。

  3. 可以忽略。


0
投票

您可以使用 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
执行以下操作:

  • 将收到的数据分为训练和验证
  • 训练用于拟合 SVR 回归器
  • 验证用于使用排列技术计算和存储特征重要性
  • 最后,使用收到的所有数据计算最终训练

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 或类似逻辑)来自定义此逻辑

© www.soinside.com 2019 - 2024. All rights reserved.