我正在使用python中的套索,但是有一个让我困惑的问题。 在以下example中,我的代码如下:
kf = KFold(10,random_state=0,shuffle=False)
model_lassocv = LassoCV(cv=kf).fit(X, y)
model_lassocv.mse_path_给出数组([[5747.95194531,4590.75732123,...]])。
我手动计算了mse:
from sklearn import linear_model
from sklearn.model_selection import cross_val_predict, cross_val_score
lasso = linear_model.Lasso(alpha = model_lassocv.alphas_[0])
predict = cross_val_predict(lasso, X, y, cv=kf)
metrics.mean_squared_error(y_pred=predict[0:44],y_true=y[0:44])
# 0:44 is the first test set according to KFold function
# and result here gives 5625 instead of 5747.95
然而,
cross_val_score(lasso,X,y, cv=kf, scoring="neg_mean_squared_error")
给出与model_lassocv.mse_path_相同的否定结果。
对不起我的误导性问题。我想知道为什么metrics.mean_squared_error
会从mse_path_
返回不同的结果。如果我没有误解KFold
的分区,那么10倍CV中的第一个测试集是0:44。并且,由metrics.mean_squared_error
计算的第一个alpha(在我的情况下为2.14804358)的第一个测试集中的交叉验证预测和真值的MSE返回5625,而LassoCV的mse_path_
返回5747。
答案 0 :(得分:0)
原因在于您手动实施拟合模型。 mse_path_
属性中的MSE是KFold对象生成的每个折叠的MSE。但是,在您的手动实现中,当您使用cross_val_predict
时,您要求sklearn训练具有所有可用折叠的模型,而不是LassoCv实现中使用的特定折叠。我将使用sklearn提供的boston数据集提供正确的解决方案。
from sklearn.model_selection import cross_val_predict, cross_val_score, KFold
from sklearn.linear_model import LassoCV, Lasso
from sklearn.metrics import mean_squared_error
from sklearn.datasets import load_boston
X, y = load_boston(return_X_y=True)
kf = KFold(10, random_state=0, shuffle=False)
现在让我们看看折叠是什么样的:
for train_i, test_i in kf.split(X):
print(train_i, test_i)
(array([ 51, 52, 53, ... , 505], dtype=int64), array([ 0, 1, 2, ... , 50], dtype=int64)) ... (array([ ... ]))
为简洁起见,我只显示第一个折叠,其中训练集由51到505的索引组成,对于此折叠中的测试集,索引从0到50。
现在让我们使用您的LassoCV方法:
model_lassocv = LassoCV(cv=kf).fit(X, y)
model_lassocv.mse_path_
MSE路径的结果:
array([[ 41.74173819, 29.78409579, 32.00672122, 191.68560655,
103.46618603, 172.62108062, 16.92365434, 181.06822315,
116.83656233, 35.92813347], [ ... ], ... ])
同样,为简洁起见,我只显示第一个alpha的所有10个折叠的MSE。根据您的示例,您希望匹配LassoCV中使用的第一个alpha的第一个折叠的MSE,因此在我的情况下,我想手动获得结果= 41.74173819。
现在,我将采用手动实现方式:
lasso = Lasso(alpha = model_lassocv.alphas_[0])
lasso.fit(X[51:506], y[51:506])
predict = lasso.predict(X[0:51])
mean_squared_error(y_pred=predict, y_true=y[0:51])
主要差异:
我手动计算的结果?
41.741738189299873
因此,我们有一场比赛。