我想出了我的理解在哪里,我想我应该回答我的问题,以防其他人偶然发现它。
首先,sklearn 使嵌套交叉验证看似简单。我一遍又一遍地阅读他们的例子,但直到我查看了这个问题的答案中给出的非常有用的伪代码,才得到它。
简而言之,这是我必须做的(这几乎是 scikit-learn 给出的示例的副本):
- 初始化两个交叉验证生成器,内部和外部。为此,我使用了 StratifiedKFold() 构造函数。
- 创建一个 RandomizedSearchCV 对象(比整个网格搜索快得多——我认为可以轻松地使用 sklearn 对象来计算贝叶斯信息准则并制作一个更酷/更快/更智能的超参数优化器,但这超出了我的知识范围,我只是听说Andreas Mueller 曾经在一些讲座中谈到过)将内部交叉验证器作为cv参数,其余的东西、估计器、评分函数等都是正常的。
- 适合您的训练集 (X) 和标签 (y)。您想要拟合它,因为下一步需要一个估计器(即,使用管道中的估计器转换 X 和 y 后得到的估计器 + 使用最终估计器拟合 X 和 y 以产生拟合估计器)。
- 使用cross_val_score并为其提供新安装的 RandomizedSearchCV 对象、X、y 和外部交叉验证器。我将其输出分配给一个名为scores的变量,并返回一个元组,该元组由一个具有最佳分数的元组和随机搜索(rs._best_params,rs._best_score)和score变量给出的最佳参数组成。我对我到底需要什么有点模糊并且有点懒惰,所以这可能是返回的信息比必要的多。
在代码中,它看起来是这样的:
def nestedCrossValidation(X, y, pipe, param_dist, scoring, outer, inner):
rs = RandomizedSearchCV(pipe, param_dist, verbose=1, scoring=scoring, cv=inner)
rs.fit(X, y)
scores = cross_val_score(rs, X, y, cv=outer)
return ((rs._best_score, rs.best_params), scores)
cross_val_score 将拆分为一个训练/测试集并对该训练集进行随机搜索,该训练集本身拆分为一个测试/训练集,生成分数,然后返回到 cross_val_score 进行测试并继续进行下一个测试/训练放。
完成此操作后,您将获得一堆交叉验证分数。我最初的问题是:“你现在得到/做什么?” 嵌套交叉验证不适用于模型选择。我的意思是,您并没有试图获得对最终模型有益的参数值。这就是内部 RandomizedSearchCV 的用途。
但是,当然,如果您在管道中使用 RandomForest 之类的东西进行特征选择,那么您每次都会期望一组不同的参数!那么你真正得到了什么有用的东西?
嵌套交叉验证是对您的方法论/一系列步骤的好坏给出一个公正的估计. 什么是好的”?好是由超参数的稳定性和您最终获得的交叉验证分数来定义的。假设你像我一样得到数字:我得到的交叉验证分数为:[0.57027027, 0.48918919, 0.37297297, 0.74444444, 0.53703704]。所以根据我做事方法的心情,我可以得到 0.37 到 0.74 之间的 ROC 分数——显然这是不可取的。如果您查看我的超参数,您会发现“最佳”超参数变化很大。然而,如果我得到一致的高交叉验证分数,并且最佳超参数都在同一个范围内,我可以相当自信地选择选择特征和建模我的数据的方式非常好。
如果您有不稳定因素——我不确定您能做什么。我还是新手——这个板上的专家可能有更好的建议,而不是盲目地改变你的方法。
但如果你有稳定,下一步是什么?这是我忽略理解的另一个重要方面:由您的训练数据创建的非常好的、可预测的和可推广的模型并不是最终模型。但它很接近。最终模型使用了你所有的数据,因为你已经完成了测试、优化和调整(是的,如果你尝试用你曾经适合它的数据交叉验证一个模型,你会得到一个有偏差的结果,但是你为什么要在这一点上交叉验证它?你已经这样做了,希望不存在偏见问题)——你给它所有你能提供的数据,这样它就可以做出最明智的决定,并且下一次你会看到你的模型有多好,是它在野外的时候,
我希望这可以帮助别人。出于某种原因,我花了很长时间来解决这个问题,这里有一些我曾经理解的其他链接:
http://www.pnas.org/content/99/10/6562.full.pdf — 重新检查其他遗传学论文得出的数据和结论的论文,这些论文不使用嵌套交叉验证进行特征选择/超-参数选择。知道即使是超级聪明和有成就的人也会时不时地被统计数据所欺骗,这有点令人欣慰。
http://jmlr.org/papers/volume11/cawley10a/cawley10a.pdf — iirc,我看到该作者的一位作者在此论坛上回答了大量有关此主题的问题
交叉验证后使用完整数据集进行训练?— 上述作者之一以更通俗的方式回答了类似的问题。
http://scikit-learn.org/stable/auto_examples/model_selection/plot_nested_cross_validation_iris.html — sklearn 示例