(我确定我已经在某个答案中写了大部分内容-但现在找不到它。如果有人偶然发现了该答案,请链接它)。我在这里看到2种略有不同的方法,我认为这都是明智的。
但是首先是一些术语:
- 来自一个应用领域,对我来说(适合/训练过的)模型很容易使用。也就是说,模型包含生成新数据预测所需的所有信息。因此,模型也包含超参数。您将看到,这种观点与下面的方法2密切相关。
- OTOH,在我的经验中,训练算法在以下意义上没有得到很好的定义:为了获得(拟合的)模型,不仅需要“正常”模型参数的-我们称之为“主要拟合”,但是超参数也需要固定。从我的应用程序角度来看,参数和超参数之间并没有太大区别:两者都是模型的一部分,需要在训练期间进行估计/确定。
我想它们之间的差异与开发新训练算法的人之间的差异有关,后者通常会描述一类训练算法以及一些转向参数(超参数))在没有应用/领域知识的情况下很难/不可能(或至少应该决定如何决定/估算)。
方法1:要求稳定的优化结果
通过这种方法,“模型训练”是“正常”模型参数的拟合,并给出了超参数。内部例如交叉验证负责超参数优化。
解决要选择其超参数集的困境的关键步骤/假设是要求优化过程稳定。出于验证目的的交叉验证假设所有替代模型都与最终模型足够相似(通过对整个数据集应用相同的训练算法获得),从而可以将它们(在最终模型之间)视为相等。如果这个假设失败了,
替代模型彼此之间仍然相等(或等效),但与最终模型不相等,我们谈论的是交叉验证的众所周知的悲观偏见。
如果替代模型也彼此不相等/相等,则存在不稳定的问题。
对于内循环的优化结果,这意味着如果优化是稳定的,则选择超参数不会有冲突。并且如果在内部交叉验证结果中观察到相当大的差异,则优化不稳定。不稳定的训练情况所带来的问题比仅仅决定选择哪个超参数要严重得多,我真的建议在这种情况下退一步并重新开始建模过程。
但是,这里有一个例外:优化中可能会有几个局部最小值,而实际应用中会产生相同的性能。也要求他们之间保持稳定的选择可能是不必要的强烈要求-但我不知道如何摆脱这一困境。
请注意,如果不是所有模型都产生相同的获胜参数集,则不应在此处使用外环估计作为泛化误差:
- p
- 但是,除非没有涉及所有分割产生相同参数的决策,否则这将破坏外部循环的独立性:每个分割的测试数据已经进入了决定哪个参数集获胜的决定,因为它是所有其他分割中的训练数据,因此可以使用优化参数。
方法2:将超参数调整作为模型训练的一部分
这种方法桥接了“训练算法开发人员”和训练算法的应用用户的观点。
训练算法开发人员提供了“裸”训练算法model = train_naked (trainingdata, hyperparameters)
。由于应用用户的需求 tunedmodel = train_tuned (trainingdata)
,这也需要修复超参数。
train_tuned
可以例如通过将基于交叉验证的优化器包装在裸训练算法周围来实现train_naked
。
train_tuned
然后可以像不需要超参数输入的任何其他训练算法一样使用,例如tunedmodel
可以对其输出进行交叉验证。现在,检查超参数的稳定性,就像在交叉验证评估中应检查“正常”参数的稳定性一样。
如果您对所有获胜模型的平均性能进行了评估,而不论它们各自的参数集如何,那么实际上这就是您在嵌套交叉验证中所做的评估。
有什么不同?
我们可能最终采用这两种方法得出不同的最终模型:
- 方法1的最终模型将是
train_naked (all data, hyperparameters from optimization)
- 而方法2将使用
train_tuned (all data)
和-从而在较大的数据集上再次运行超参数优化-最终可能会得到一组不同的超参数。
但是,同样的逻辑也适用:如果我们发现最终模型的参数与交叉验证代理模型的参数大不相同,那就是假设1被违反的征兆。所以恕我直言,我们没有冲突,而是要检查我们的(隐式)假设是否合理。如果不是这样,无论如何我们都不应该对最终模型的性能进行正确的估计。
我给人的印象(也是从CV上类似问题/困惑的数量中看到的),很多人认为嵌套交叉验证是在方法1上进行的。但是一般根据方法2来估计泛化误差,因此这就是方法最终模型。
虹膜示例
简介:优化基本上是没有意义的。可用的样本数量不允许在此处区分任何参数集的性能。
但是,从应用程序角度来看,得出的结论是,选择4个参数集中的哪一个都没有关系-并不是所有的坏消息:您发现了一个相对稳定的参数平台。这带来了对调整后的模型进行适当的嵌套验证的优势:虽然您不能断言它是最佳模型,但仍然可以断言使用方法2在整个数据上构建的模型将具有大约97%的准确度(150个测试案例中的145个正确案例的95%置信区间:92-99%)
请注意,方法1看起来也并非遥不可及-参见下文:由于关系的缘故,您的优化意外地错过了一个相对明确的“赢家”(这实际上是样本量问题的另一个非常明显的征兆)。
尽管我对SVM的了解还不够深,无法“看到” C = 1应该是一个不错的选择,但我会选择限制性更强的线性内核。此外,当你做了优化,没有什么不妥选择,即使你知道,所有参数集导致几乎相同的性能优胜参数集。
但是,在将来,请考虑您的经验是否会粗略估计您可以预期的性能以及大致上哪种模型会是一个不错的选择。然后构建该模型(使用手动固定的超参数)并计算其性能的置信区间。使用它来确定尝试进行优化是否合理。(我可能会补充说,我主要是在处理不易获得10个独立案例的数据的情况下-如果您所在的领域具有大量独立样本,那么情况对您来说会好得多)
长版:
至于示例结果在iris
数据集上。iris
在150个案例中,考虑了具有2 x 2参数网格的SVM(2个内核,惩罚的数量级为2个数量级C
)。
内部循环具有129(2x)和132(6x)情况的分割。“最好”的参数组是线性的或径向基核之间未定,都与C = 1然而,内测试精度是所有(包括始终松动C = 10)内94 - 98.5%观察到的精确度。对于C = 1 vs. 10的rbf,我们在拆分之一中的最大差异是3 vs. 8误差。
这根本不可能有很大的不同。我不知道如何提取CV中个别案例的预测,但是即使假设3个错误是共享的,并且C = 10模型又产生了5个错误:
> table (rbf1, rbf10)
rbf10
rbf1 correct wrong
correct 124 5
wrong 0 3
> mcnemar.exact(rbf1, rbf10)
Exact McNemar test (with central confidence intervals)
data: rbf1 and rbf10
b = 5, c = 0, p-value = 0.0625
alternative hypothesis: true odds ratio is not equal to 1
请记住,在2 x 2网格中有6个成对比较,因此我们也需要校正多个比较。
方法1
在rbf在线性核中胜出的4个外部拆分中的3个中,它们实际上具有相同的估计准确性(我猜是在平局的情况下,min返回第一个合适的索引)。
将网格更改为
params = {'kernel':['linear', 'rbf'],'C':[1,10]}
收益
({'kernel': 'linear', 'C': 1}, 0.95238095238095233, 0.97674418604651159)
({'kernel': 'rbf', 'C': 1}, 0.95238095238095233, 0.98449612403100772)
({'kernel': 'linear', 'C': 1}, 1.0, 0.97727272727272729)
({'kernel': 'linear', 'C': 1}, 0.94444444444444442, 0.98484848484848486)
({'kernel': 'linear', 'C': 1}, 0.94444444444444442, 0.98484848484848486)
({'kernel': 'linear', 'C': 1}, 1.0, 0.98484848484848486)
({'kernel': 'linear', 'C': 1}, 1.0, 0.96212121212121215)
方法二:
这clf
是您的最终模型。使用random_state = 2
,C = 1的rbf获胜:
In [310]: clf.grid_scores_
[...snip warning...]
Out[310]:
[mean: 0.97333, std: 0.00897, params: {'kernel': 'linear', 'C': 1},
mean: 0.98000, std: 0.02773, params: {'kernel': 'rbf', 'C': 1},
mean: 0.96000, std: 0.03202, params: {'kernel': 'linear', 'C': 10},
mean: 0.95333, std: 0.01791, params: {'kernel': 'rbf', 'C': 10}]
(在5次,1 6次发生约1 linear
和rbf
与C = 1
被绑定于秩1)