为了账号安全,请及时绑定邮箱和手机立即绑定

使用 cross_val_predict 与 cross_val_score 时

使用 cross_val_predict 与 cross_val_score 时

森栏 2022-12-27 15:25:03
我预计这两种方法都会返回相当相似的错误,有人可以指出我的错误吗?计算均方根误差...rf = RandomForestRegressor(random_state=555, n_estimators=100, max_depth=8)rf_preds = cross_val_predict(rf, train_, targets, cv=7, n_jobs=7) print("RMSE Score using cv preds: {:0.5f}".format(metrics.mean_squared_error(targets, rf_preds, squared=False)))scores = cross_val_score(rf, train_, targets, cv=7, scoring='neg_root_mean_squared_error', n_jobs=7)print("RMSE Score using cv_score: {:0.5f}".format(scores.mean() * -1))RMSE Score using cv preds: 0.01658RMSE Score using cv_score: 0.01073
查看完整描述

1 回答

?
交互式爱情

TA贡献1712条经验 获得超3个赞

这里有两个问题,在文档中都有提到cross_val_predict

结果可能与和 不同cross_validatecross_val_score除非所有测试集都具有相同的大小并且度量在样本上分解。

首先是使所有集合(训练和测试)在两种情况下都相同,这在您的示例中并非如此。为此,我们需要使用该kfold方法来定义我们的 CV 折叠,然后在两种情况下都使用这些相同的折叠。这是一个带有虚拟数据的示例:

from sklearn.datasets import make_regression

from sklearn.model_selection import KFold, cross_val_score, cross_val_predict

from sklearn.ensemble import RandomForestRegressor

from sklearn.metrics import mean_squared_error


X, y = make_regression(n_samples=2000, n_features=4, n_informative=2,

                      random_state=42, shuffle=False)


rf = RandomForestRegressor(max_depth=2, random_state=0)

kf = KFold(n_splits=5)


rf_preds = cross_val_predict(rf, X, y, cv=kf, n_jobs=5) 

print("RMSE Score using cv preds: {:0.5f}".format(mean_squared_error(y, rf_preds, squared=False)))


scores = cross_val_score(rf, X, y, cv=kf, scoring='neg_root_mean_squared_error', n_jobs=5)

print("RMSE Score using cv_score: {:0.5f}".format(scores.mean() * -1))

上面代码片段的结果(完全可重现,因为我们已经明确设置了所有必要的随机种子)是:


RMSE Score using cv preds: 15.16839

RMSE Score using cv_score: 15.16031

所以,我们可以看到这两个分数确实相似,但仍然不完全相同。


这是为什么?答案在于上面引用的句子中相当隐秘的第二部分,即 RMSE 分数不会分解样本(老实说,我不知道它分解的任何 ML 分数)。


简单来说,whilecross_val_predict严格按照其定义计算RMSE,即(伪代码):


RMSE = square_root([(y[1] - y_pred[1])^2 + (y[2] - y_pred[2])^2 + ... + (y[n] - y_pred[n])^2]/n)

样本数量在哪里n,该cross_val_score方法并没有完全做到这一点;它所做的是为每个kCV 折叠计算 RMSE,然后对这些k值进行平均,即(再次伪代码):


RMSE = (RMSE[1] + RMSE[2] + ... + RMSE[k])/k

正是因为 RMSE 不可分解样本,这两个值虽然接近,但并不相同。


我们实际上可以通过手动执行 CV 程序并模拟 RMSE 计算来证明确实如此,如上文cross_val_score所述,即:


import numpy as np

RMSE__cv_score = []


for train_index, val_index in kf.split(X):

    rf.fit(X[train_index], y[train_index])

    pred = rf.predict(X[val_index])

    err = mean_squared_error(y[val_index], pred, squared=False)

    RMSE__cv_score.append(err)


print("RMSE Score using manual cv_score: {:0.5f}".format(np.mean(RMSE__cv_score)))

结果是:


RMSE Score using manual cv_score: 15.16031

即与cross_val_score上面返回的相同。


所以,如果我们想要非常精确,事实是正确的 RMSE(即完全根据其定义计算)是cross_val_predict; cross_val_score返回它的近似值。但是在实践中,我们往往会发现区别并不那么显着,所以cross_val_score如果方便的话我们也可以使用。


查看完整回答
反对 回复 2022-12-27
  • 1 回答
  • 0 关注
  • 149 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信