【问题标题】:Sklearn SelectFromModel with L1 regularized Logistic Regression具有 L1 正则化逻辑回归的 Sklearn SelectFromModel
【发布时间】:2020-09-23 10:41:54
【问题描述】:

作为我管道的一部分,我想结合使用LogisticRegression(penalty='l1')SelectFromModel 进行特征选择。为了选择合适的正则化量,我用GridSearchCV优化了正则化参数C

from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression, LassoCV
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import StandardScaler
from sklearn.feature_selection import SelectFromModel
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import GridSearchCV, RepeatedStratifiedKFold
import numpy as np

seed = 111
breast = load_breast_cancer()
X = breast.data
y = breast.target
LR_L1 = LogisticRegression(penalty='l1', random_state=seed, solver='saga', max_iter=1e5)
pipeline = Pipeline([('scale', StandardScaler()),
                     ('SelectFromModel', SelectFromModel(LR_L1)),
                     ('classifier', RandomForestClassifier(n_estimators=500, random_state=seed))])
Lambda = np.array([])
for i in [1e-1, 1, 1e-2, 1e-3]:
    Lambda = np.append(Lambda, i * np.arange(2, 11, 2))
param_grid = {'SelectFromModel__estimator__C': Lambda,
              'classifier_max_features': np.arange(10,100, 10)}
clf = GridSearchCV(pipeline, param_grid, scoring='roc_auc', n_jobs=7, cv=RepeatedStratifiedKFold(random_state=seed),
                   verbose=1)
clf.fit(X, y)

对于C 的某些值,我收到以下警告:

UserWarning: No features were selected: either the data is too noisy or the selection test too strict.

这是可以理解的。 但是,当将相同的LogisticRegression 拟合为分类器而不是特征选择时,我没有遇到任何问题,而用于拟合算法的训练集和超参数是相同的。看结果,不可能有0个特征的系数不等于0。

pipeline2 = Pipeline([('scale', StandardScaler()),
                     ('classifier', LR_L1)])
param_grid2 = {'classifier__C': Lambda}
clf2 = GridSearchCV(pipeline2, param_grid2, scoring='roc_auc', n_jobs=7, cv=RepeatedStratifiedKFold(random_state=seed),
                    verbose=1)
clf2.fit(X, y)

这是一个错误还是我误解了什么?

【问题讨论】:

  • 不是您问题的真正答案,但这对您有用吗? scikit-learn.org/stable/modules/generated/…
  • 我只是提供一个简单的例子来说明我的问题。我使用嵌套交叉验证来通过内部循环来优化超参数来获得我的模型性能。我想在同一级别优化正则化,即在内部循环中,而不是其他参数(例如 max_features 用于我的 RF 在示例中),并且不进行另一个级别的交叉验证,其中会有更少样本。
  • 请不要在之后编辑问题,因为提供的答案会导致答案无效(在之前的版本中回滚)。
  • 你说的“看结果,不可能有0个系数不等于0的特征”是什么意思? cv_results_?
  • @BenReiniger 是的,这就是我在看的东西,但我不应该。在下面的答案中查看我的 cmets

标签: python machine-learning scikit-learn feature-selection


【解决方案1】:

由于 LogisticRegression 的正则化太强,您发现了一个错误。 param_grid 中的参数 classifier_max_features 也有一个错字 - 它应该是 classifier__max_features(两个下划线)。

使用正则化值C >= 1e-2,代码有效。在这里,您可以找到带有您的示例的 google colab notebook

还有一点需要注意 - 数据集太小,无法进行如此复杂的操作。

【讨论】:

  • 事实上,问题附加了非常小的 C 值(如果我是正确的,则为 2e-3 和 4e-3),但您将超参数网格限制为更大的值。同样,这只是重现我遇到的问题的一个例子,测试的参数不是最优的。无论如何,我觉得它不应该像它那样表现,即在SelectFromModel 中返回 0 个非零系数,但在此对象之外时成功拟合
  • 经过一番调查,我发现两种情况下的系数是相同的。当所有系数都为 0 时,我被 Logistic 回归的结果所吸引。它等于 0.5,我不知道为什么我会期望像 NaN 这样的东西。因此,除了您建议的过于强大的正则化之外,别无他法。
猜你喜欢
  • 2021-04-10
  • 1970-01-01
  • 2023-03-21
  • 2021-02-07
  • 1970-01-01
  • 2018-04-14
  • 1970-01-01
  • 2020-10-11
  • 2020-09-16
相关资源
最近更新 更多