繁体   English   中英

如何使用 scikit-learn 中的 SelectFromModel 正确进行特征选择?

[英]How to properly do feature selection with SelectFromModel from scikit-learn?

我正在使用一个非常简单的 kaggle 数据集来了解带有逻辑回归的 SelectFromModel 是如何工作的。 这个想法是创建一个非常简单的管道,带有一些基本的数据处理(删除列+缩放),将其传递给特征选择(logreg),然后拟合一个 xgboost 模型(未包含在代码中)。 通过阅读文档,我的理解是,给定我的 X_train 和 y_train,拟合了一个 logreg 模型,并选择了那些系数高于或等于阈值的特征。 就我而言,我将阈值设置为 mean*1.25。

我不明白为什么输出selector.threshold_selector.estimator_.coef_.mean()*1.25. 我期待获得相同的价值,为什么不是这样?

在此处输入图片说明

展望未来,我想做 GridSearchCV 来微调我的管道参数。 我通常这样做:

from sklearn.model_selection import GridSearchCV

params = {}
params['gradientboostingclassifier__learning_rate'] = [0.05, 0.1, 0.2]
params['selectfrommodel__estimator__C'] = [0.1, 1, 10]
params['selectfrommodel__estimator__penalty']= ['l1', 'l2']
params['selectfrommodel__estimator__threshold']=['median', 'mean', '1.25*mean', '0.75*mean']

grid = GridSearchCV(pipe, params, cv=5, scoring='recall')
%time grid.fit(X_train, y_train);

不幸的是,阈值似乎不在参数列表( pipe.named_steps.selectfrommodel.estimator.get_params().keys() )中,因此pipe.named_steps.selectfrommodel.estimator.get_params().keys() GridSearchCV 工作,需要对此行进行注释。

params['selectfrommodel__estimator__threshold']=['median', 'mean', '1.25*mean', '0.75*mean']

有没有办法微调阈值?

因为重要性是基于系数绝对值的平均值。 如果对相对值求平均值,平均重要性会降低

我已经构建了一个示例来演示该行为:

from sklearn.feature_selection import SelectFromModel
from sklearn.linear_model import LogisticRegression
X = [[ 0.87, -1.34,  0.31 ],
     [-2.79, -0.02, -0.85 ],
     [-1.34, -0.48, -2.55 ],
     [ 1.92,  1.48,  0.65 ]]
y = [0, 1, 0, 1]
selector = SelectFromModel(estimator=LogisticRegression(), threshold="1.25*mean").fit(X, y)
print(selector.estimator_.coef_)
print(selector.threshold_) # 0.6905659148858644
# note here the absolute transformation before the mean
print(abs(selector.estimator_.coef_).mean()*1.25) # 0.6905659148858644

另请注意,特征重要性是模型训练的结果,而不是您可以先验定义的。 这就是原因,因为您无法拟合阈值,该阈值仅在您训练后获得

@Nikaido问题在第一部分是完全正确的,缺少abs() 这意味着abs(selector.estimator_.coef_).mean()*1.25等于selector.threshold_

对于第二部分,确实有可能,正确的做法是改变这一行:

params['selectfrommodel__estimator__threshold']=['median', 'mean', '1.25*mean', '0.75*mean']

到另一行:

params['selectfrommodel__threshold']=['median', 'mean', '1.25*mean', '0.75*mean']

由于threshold是来自selectfrommodel而不是来自estimator的参数,请参阅下文如何获取两种情况的完整列表以进一步调整超参数,请使用这些:

pipe.named_steps.selectfrommodel.get_params().keys() 
pipe.named_steps.selectfrommodel.estimator.get_params().keys() 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM