我从scikit-learn文档中查看此示例:http://scikit-learn.org/0.18/auto_examples/model_selection/plot_nested_cross_validation_iris.html
在我看来,交叉验证不是以无偏见的方式执行的。 GridSearchCV
(假设是内部CV循环)和cross_val_score
(假设是外部CV循环)都使用相同的数据和相同的折叠。因此,分类器训练和评估的数据之间存在重叠。我错了什么?
答案 0 :(得分:2)
@ Gael - 由于我无法添加评论,我将在答案部分发布此内容。我不确定Gael的含义是什么?"第一次拆分是在cross_val_score中完成的,第二次拆分是在GridSearchCV内完成的(GridSearchCV对象的整个点)" 。您是否试图暗示cross_val_score函数将(k-1) - 折叠数据(用于外循环训练)传递给clf对象?这似乎并非如此,因为我可以注释掉cross_val_score函数并将nested_score [i]设置为虚拟变量,并且仍然获得完全相同的clf.best_score_。这意味着GridSearchCV是单独评估的,并且确实使用所有可用数据,而不是训练数据的子集。
在嵌套CV中,据我所知,内部循环将对较小的训练数据子集进行超参数搜索,然后外部循环将使用这些参数进行交叉验证。在内循环中使用较小训练数据的原因之一是避免信息泄漏。它并没有出现在这里发生的事情。内循环首先使用所有数据来搜索超参数,然后将其用于外循环中的交叉验证。因此,内环已经看到所有数据,并且在外环中进行的任何测试都将遭受信息泄漏。如果我弄错了,你能否指点我在你的答案中提到的代码部分?
答案 1 :(得分:0)
他们没有使用相同的数据。当然,示例的代码并没有明显,因为拆分是不可见的:第一个拆分在cross_val_score内完成,第二个拆分在GridSearchCV内完成(GridSearchCV对象的整个点)。使用函数和对象而不是手写的for循环可能会使事情变得不那么透明,但是:
如果您不相信,请查看cross_val_score和GridSearchCV的代码。
最近改进了示例以在评论中指定: http://scikit-learn.org/dev/auto_examples/model_selection/plot_nested_cross_validation_iris.html
(在https://github.com/scikit-learn/scikit-learn/pull/7949上提取请求)
答案 2 :(得分:0)
完全同意,嵌套cv过程是错误的,cross_val_score被认为是GridSearchCV计算的最佳超参数,并使用此类超参数计算cv得分。在nested-cv中,您需要用于评估模型性能的外环和用于模型选择的内环,这样,内环中用于模型选择的数据部分必须与用于评估模型性能的部分不相同。一个示例是用于评估性能的LOOCV外循环(或者是5cv,10cv或您喜欢的任何值),以及用于在内部循环中使用网格搜索进行模型选择的10cv折叠。这意味着,如果您有N个观测值,则将在N-1个观测值的内部循环中(例如,使用网格搜索和10-CV)执行模型选择,然后评估LOO观测值的模型性能(或在保留数据样本中(如果您选择其他方法)。 (请注意,您正在内部估计超参数的N个最佳模型)。 访问cross_val_score和GridSearchCV的代码链接将很有帮助。 嵌套CV的一些参考是:
注意: 我在cross_val_score的文档中没有找到任何表明内部使用参数搜索,网格搜索+交叉验证对超参数进行了优化的示例,例如在k-1折数据上,并对保留数据使用了这些优化的参数示例(我的意思与http://scikit-learn.org/dev/auto_examples/model_selection/plot_nested_cross_validation_iris.html中的代码不同)