如何在执行 10 倍交叉验证时在每次拆分时获得 Lasso Regression 中的系数?
Posted
技术标签:
【中文标题】如何在执行 10 倍交叉验证时在每次拆分时获得 Lasso Regression 中的系数?【英文标题】:How to get the coefficients in Lasso Regression at every split while performing 10 fold cross validation? 【发布时间】:2021-08-31 03:24:08 【问题描述】:我正在执行随机搜索 cv 以在 Lasso 回归中查找 alpha 值,并且我正在执行 10 折交叉验证。有没有办法获取每个拆分的系数值,就像我们使用 cv_results 函数获取分数一样?
【问题讨论】:
@MustafaAydın 我相信 OP 想要在每次迭代中拟合Lasso
估计器的 coef_
。这无法从cv_results_
中检索到,因为并非所有拟合的估计器都被保存。在我的回答中提供了解决方法。
@afsharov 哦,谢谢,我现在明白了,感谢您的回答,+1。
【参考方案1】:
在我看来,将系数保存为附加分数比修改估计器本身(如@afsharov's answer)更巧妙。定义记分器并将其传递给搜索
def coefs_scorer(estimator, X, y):
return estimator.coef_
rs = RandomizedSearchCV(
...
scoring='r2': 'r2', 'coefs': coefs_scorer,
refit='r2',
)
失败,因为有记录员返回单个数字的检查。所以你需要解压缩系数,我最终得到了这个:
def coefs_scorer(estimator, X, y, i):
return estimator.coef_[i]
from functools import partial
scoring = 'r2': 'r2'
for i in range(X_train.shape[1]):
scoring[f'coefi'] = partial(coefs_scorer, i=i)
param_distributions = 'alpha': [0.01, 0.1, 1]
rs = RandomizedSearchCV(
Lasso(),
param_distributions=param_distributions,
cv=2,
n_iter=3,
random_state=42,
scoring=scoring,
refit='r2',
)
请注意,对于多个指标,您需要指定用于改装的指标。由于所有额外的工作,我不太确定这是否比自定义类更好。不过它确实有一些优点:
如果您想挑选最佳估算器,则无需打包自定义类。 分数以编程方式保存,而不仅仅是打印出来。 由于它们是分数,因此您可以获得存储在cv_results_
中的各个折叠系数的平均值和标准偏差(当然,自己计算它们并不困难)。
缺点:
我们必须为每个功能指定一个指标。这很丑陋,但更糟糕的是,它假设您事先知道特征的数量(如果您的估算器是具有特征选择或某些特征工程步骤的管道,它将失败)。 如果您返回火车分数,您将复制cv_results_
中的系数。
这些实际上不是分数,所以从语义上讲这是hacky。
记分员假定coef_
存在并且是一维的。
【讨论】:
【参考方案2】:没有直接的方法可以通过RandomizedSearchCV
执行此操作。但是您可以通过定义自己的类来解决这个问题,例如调用 predict 函数时将系数打印到控制台:
from sklearn.linear_model import Lasso
class MyLasso(Lasso):
def predict(self, X):
print(self.coef_)
return super().predict(X)
MyLasso
的行为与Lasso
相同,可以照常使用:
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split, RandomizedSearchCV
X, y = make_regression(n_features=5, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
param_distributions = 'alpha': [0.01, 0.1, 1]
rs = RandomizedSearchCV(
MyLasso(),
param_distributions=param_distributions,
cv=2,
n_iter=3,
random_state=42
)
rs.fit(X_train, y_train)
上述示例的输出(2 折交叉验证的三次迭代得到六个结果):
[64.57650818 98.64237403 57.07123743 60.56898095 35.59985227]
[64.57001187 98.63679695 57.06557977 60.56304163 35.59888746]
[64.43774582 98.55938568 57.01219706 60.49221968 35.51151313]
[64.37690435 98.49805298 56.95345309 60.43375789 35.5018112 ]
[63.05012223 97.72950224 56.42179336 59.72460697 34.62812171]
[62.44582912 97.11061327 55.83218634 59.14092054 34.53104869]
【讨论】:
以上是关于如何在执行 10 倍交叉验证时在每次拆分时获得 Lasso Regression 中的系数?的主要内容,如果未能解决你的问题,请参考以下文章
在 sklearn 中运行 10 倍交叉验证后如何运行 SVC 分类器?
如何在 Scikit-Learn 中绘制超过 10 倍交叉验证的 PR 曲线