我想用scikitlearn来评估一个回归模型的构建,使用交叉验证和混淆,我应该使用cross_val_score
和cross_val_predict
这两个函数中的哪一个。
一种选择是:
cvs = DecisionTreeRegressor(max_depth = depth)
scores = cross_val_score(cvs, predictors, target, cv=cvfolds, scoring='r2')
print("R2-Score: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))
另一种方法是,将cv预测与标准的r2_score
一起使用:
cvp = DecisionTreeRegressor(max_depth = depth)
predictions = cross_val_predict(cvp, predictors, target, cv=cvfolds)
print ("CV R^2-Score: {}".format(r2_score(df[target], predictions_cv)))
我认为这两种方法都是有效的,并给出了类似的结果。但只有小的k折叠才是这样。虽然10倍cv的r^2大致相同,但在使用“cross-vall”评分的第一个版本中,k值越高,r^2就越低。第二个版本基本上不受折叠次数变化的影响。
这种行为是意料之中的吗?我是否对SKLearn的简历缺乏了解?
所以这个问题也困扰着我,虽然另一个提出了很好的观点,但他们没有回答OP问题的所有方面。
真正的答案是:增加k的分数差异是由于选择了度量R2(决定系数)。例如,对于MSE、MSLE或MAE,使用
cross_val_score
或cross_val_predict
没有任何区别。请参见definition of R2:
R^2=1-(MSE(基本真实,预测)/MSE(基本真实,平均值(基本真实))
粗体部分解释了为什么随着k值的增加,分数开始出现差异:分割越多,测试折叠中的样本就越少,测试折叠平均值的差异就越大。 相反,对于小k,测试折叠的平均值与全地面真值平均值相差不大,因为样本量仍然大到足以产生小的方差。
证明:
输出为:
当然,还有另一个效果没有在这里显示,这是其他人提到的。 随着k值的增加,有更多的模型在更多的样本上进行训练,而在更少的样本上进行验证,这将影响最终的得分,但这不是由
cross_val_score
和cross_val_predict
之间的选择引起的。我认为可以通过检查它们的输出来明确区别。请考虑以下片段:
注意形状:为什么是这样?
scores.shape
的长度为5,因为它是通过5倍以上的交叉验证计算得出的分数(请参见参数cv=5
)。因此,为每个折叠计算一个实际值。该值是分类器的分数:在这种情况下,输入中给定的y标签被使用两次:从数据中学习和评估分类器的性能。
另一方面,
y_pred.shape
的长度为7040,这是数据集的形状。这是输入数据集的长度。这意味着每个值不是基于多个值计算的分数,而是单个值:分类器的预测:请注意,您不知道使用了什么fold:每个输出都是根据某个fold的测试数据计算的,但是您无法区分哪个(至少从这个输出)。
在这种情况下,标签只使用一次:训练分类器。你的工作是比较这些输出和真正的输出来计算分数。如果你只是平均他们,正如你所做的,产出不是分数,只是平均预测。
cross_val_score
返回测试折叠的分数,其中cross_val_predict
返回测试折叠的预测y值。对于
cross_val_score()
,您使用的是输出的平均值,这将受折叠次数的影响,因为它可能有一些折叠,这些折叠可能具有较高的错误(不正确地拟合)。然而,
cross_val_predict()
对于输入中的每个元素,返回该元素在测试集中时获得的预测。[请注意,只有将所有元素精确分配给一个测试集一次的交叉验证策略才能使用]。因此,增加折叠次数,只会增加测试元素的训练数据,因此其结果可能不会受到太大的影响。希望这有帮助。请随便提出任何疑问。
编辑:在评论中回答问题
请看下面关于
cross_val_predict
如何工作的答案:我认为
cross_val_predict
将是过度拟合,因为随着折叠的增加,更多的数据将用于训练,更少的数据将用于测试。因此,结果标签更依赖于训练数据。同样如上所述,对一个样本的预测只进行一次,因此可能更容易受到数据分割的影响。 这就是为什么大多数地方或教程建议使用cross_val_score
进行分析。相关问题 更多 >
编程相关推荐