特征选择和交叉验证


76

我最近在这个站点(@ Aniko,@ Dikran Marsupial,@ Erik)和其他地方阅读了很多有关交叉验证时出现过拟合问题的信息-(Smialowski等人2010 Bioinformatics,Hastie,统计学习元素)。建议是,在使用交叉验证(或其他模型估计方法,例如自举)的模型性能估计之外执行的任何监督特征选择(使用与类标签的相关性)都可能导致过度拟合。

这对我来说似乎并不直观-当然,如果选择一个功能集,然后使用交叉验证使用选定的功能评估模型,那么您将获得对这些功能的广义模型性能的无偏估计(假设所研究的样本具有代表性)人口)?

通过此过程,当然不能要求一个最佳功能集,但可以将未看到的数据上所选功能集的性能报告为有效吗?

我接受基于整个数据集选择功能可能会导致测试集和训练集之间的数据泄漏。但是,如果在初始选择之后功能部件集是静态的,并且没有进行其他调整,那么报告交叉验证的性能指标是否有效?

就我而言,我有56个要素和259个案例,因此#cases> #features。这些特征来自传感器数据。

抱歉,我的问题似乎是派生的,但这似乎是需要澄清的重要点。

编辑: 在上面详细描述的数据集上通过交叉验证实现特征选择(由于下面的答案),我可以确认在此数据集中交叉验证之前选择特征引入了重要意义偏压。与2类配方相比,这种偏倚/过度拟合对于3类配方而言最大。我认为我使用逐步回归进行特征选择的事实加剧了这种过度拟合的现象。为了进行比较,在另一个但相关的数据集上,我将交叉验证之前执行的顺序正向特征选择例程与我先前在CV中使用特征选择所获得的结果进行了比较。两种方法之间的结果没有显着差异。这可能意味着逐步回归比顺序FS更容易过度拟合,或者可能是此数据集的怪癖。


7
我不认为这是Hastie等人的(相当)。在提倡。一般的论点是,如果要素选择使用响应,那么最好将其作为CV过程的一部分。如果进行预测变量筛选,例如,通过查看其样本方差并排除变化较小的预测变量,则可以一次性完成。
主教

3
+1然而,即使在这种情况下,交叉验证也不代表特征选择过程中的差异,如果特征选择不稳定,则可能会出现问题。如果您首先进行筛选,那么每折的性能差异将不足以代表真实的差异。如果在每个折叠中执行筛选,则会适当增加每个折叠中的性能差异。如果我能负担得起计算费用,我仍然会始终对每一步进行筛选。
迪克兰有袋动物博物馆,

1
我认为,“在使用交叉验证进行模型性能评估之前执行的任何特征选择都可能导致过度拟合。” 是对Hastie和其他人的建议的错误引用或错误陈述。如果您将单词“ prior”更改为“ without”,则更有意义;这句话似乎暗示了交叉验证是合法测试所选变量是否适当的唯一方法,例如,引导程序可能是另一种合法方法。 。
迈克尔Chernick

@MichaelChernick-同意。我在上面进行了编辑,以更好地体现我的意思。
格林格林(BGreene)

1
@Bgreene:最近对此问题进行了讨论,可以在goo.gl/C8BUa上阅读。
Alekk

Answers:


68

如果对所有数据都进行特征选择,然后进行交叉验证,那么交叉验证过程的每一折中的测试数据也将用于选择特征,这就是性能分析的偏向。

考虑这个例子。我们通过翻转硬币10次并记录其落下是正面还是反面来生成一些目标数据。接下来,我们通过将每个特征抛硬币10次并写下我们得到的内容来生成20个特征。然后,我们通过选择尽可能与目标数据匹配的特征来执行特征选择,并将其用作我们的预测。然后,如果我们交叉验证,我们将获得略低于0.5的预期错误率。这是因为我们在交叉验证过程的每一步中都基于训练集和测试集两者之间的相关性来选择特征。但是,由于目标数据只是随机的,因此真正的错误率将为0.5。如果在交叉验证的每一折内独立执行特征选择,则错误率的期望值为0。

关键思想是交叉验证是一种评估构建模型的流程的泛化性能的方法,因此您需要在每一折中重复整个流程。否则,您最终将得到有偏差的估计值,或者估计值方差偏低的估计值(或两者兼有)。

高温超导

这是一些执行此设置的蒙特卡洛模拟的MATLAB代码,具有56个特征和259个案例,以匹配您的示例,它给出的输出为:

偏倚估算器:错误= 0.429210(0.397683-0.451737)

无偏估计量:错误= 0.499689(0.397683-0.590734)

偏向估计器是在交叉验证之前执行特征选择的一种,无偏估计器是在交叉验证的每一步中独立执行特征选择的一种。这表明,根据学习任务的性质,这种情况下的偏见可能非常严重。

NF    = 56;
NC    = 259;
NFOLD = 10;
NMC   = 1e+4;

% perform Monte-Carlo simulation of biased estimator

erate = zeros(NMC,1);

for i=1:NMC

   y = randn(NC,1)  >= 0;
   x = randn(NC,NF) >= 0;

   % perform feature selection

   err       = mean(repmat(y,1,NF) ~= x);
   [err,idx] = min(err);

   % perform cross-validation

   partition = mod(1:NC, NFOLD)+1;
   y_xval    = zeros(size(y));

   for j=1:NFOLD

      y_xval(partition==j) = x(partition==j,idx(1));

   end

   erate(i) = mean(y_xval ~= y);

   plot(erate);
   drawnow;

end

erate = sort(erate);

fprintf(1, '  Biased estimator: erate = %f (%f - %f)\n', mean(erate), erate(ceil(0.025*end)), erate(floor(0.975*end)));

% perform Monte-Carlo simulation of unbiased estimator

erate = zeros(NMC,1);

for i=1:NMC

   y = randn(NC,1)  >= 0;
   x = randn(NC,NF) >= 0;

   % perform cross-validation

   partition = mod(1:NC, NFOLD)+1;
   y_xval    = zeros(size(y));

   for j=1:NFOLD

      % perform feature selection

      err       = mean(repmat(y(partition~=j),1,NF) ~= x(partition~=j,:));
      [err,idx] = min(err);

      y_xval(partition==j) = x(partition==j,idx(1));

   end

   erate(i) = mean(y_xval ~= y);

   plot(erate);
   drawnow;

end

erate = sort(erate);

fprintf(1, 'Unbiased estimator: erate = %f (%f - %f)\n', mean(erate), erate(ceil(0.025*end)), erate(floor(0.975*end)));

3
谢谢-这非常有帮助。如果采用建议的方法,那么如何评估最终模型?由于您将拥有多组功能,因此如何选择最终功能集?从历史上看,我还报告了基于一次交叉验证并选择了模型参数和特征的结果。
BGreene

15
最好将交叉验证视为评估拟合模型的过程的性能,而不是模型本身。最好的做法通常是执行上述交叉验证,然后使用交叉验证过程每一折叠中使用的相同过程,使用整个数据集构建最终模型。
迪克兰有袋博物馆,2012年

2
在这种情况下,我们是否基于交叉验证(可能有许多不同的特征集)报告分类结果,但仍报告模型仅包含那些特征集之一,即交叉验证的分类结果不一定与特征集匹配?
格林格林(BGreene)

10
本质上是的,交叉验证仅估算模型构建过程的预期性能,而不估算模型本身。如果特征集从交叉验证的一倍变化到另一倍,则表明该特征选择是不稳定的,可能不是很有意义。通常最好使用正则化(例如岭回归)而不是特征选择,尤其是在特征选择不稳定的情况下。
迪克兰有袋博物馆,2012年

3
这是一个非常重要的职位。令人惊讶的是有多少人没有这样做。
克里斯·A

12

要添加一个稍微不同且更笼统的问题描述:

如果您进行任何类型的数据驱动的预处理,例如

  1. 通过交叉验证/引导外进行参数优化
  2. 使用PCA或PLS之类的技术来降维以产生模型的输入(例如PLS-LDA,PCA-LDA)
  3. ...

如果想使用交叉验证/引导外验证来估计最终模型的性能,则需要对代理训练数据进行数据驱动的预处理,即针对每个代理模型分别进行。

如果数据驱动的预处理类型为1,则将导致“双重”或“嵌套”交叉验证:仅使用“外部”交叉验证的训练集在交叉验证中进行参数估计。ElemStatLearn有插图(https://web.stanford.edu/~hastie/Papers/ESLII.pdf第222页,第5页)。

您可能会说,预处理实际上是模型构建的一部分。仅完成预处理

  • 针对每种情况独立地
  • 独立于实际数据集

可以从验证循环中取出以节省计算量。

所以反过来:如果您的模型是完全由特定数据集外部的知识构建的(例如,您事先根据专家知识确定测量通道63-79可能无法解决问题,那么您当然可以排除这些通道,建立模型并交叉验证模型。同样,如果您进行PLS回归并根据经验确定3个潜变量是一个合理的选择(但不要随意选择2或5 lv会给出更好的结果),则可以进行正常的自举/交叉验证。


不幸的是,ElemStatLearn书的印刷版5的链接不起作用。我想知道您所引用的插图是否仍在同一页面上。请提及标题。
rraadd88

因此,如果我有两组数据,那么其中一组进行特征选择/工程处理,而另一组进行CV处理就不会有问题吗?
米洛斯(Milos)'18

1
@Milos:不,只要这些功能成为交叉验证模型的固定参数,就可以了。这将是正确的假设生成(=数据集A上的特征开发)/假设测试(=数据集B上现在固定的特征的性能测量)设置。
cbeleites

@cbeleites是的,这就是我想要做的。确定A上的特征,然后修复这些特征并对B上的模型进行交叉验证。谢谢。:)
Milos '18

@Milos:但是请记住,如果您在A上完全训练模型,然后将B 用于测试,则对获得的性能的争论甚至会更好。
cbeleites '18

5

让我们尝试使其更加直观。考虑以下示例:您有一个二进制相关的变量和两个二进制预测变量。您需要一个只有一个预测变量的模型。两个预测变量都有说95%的可能性与被抚养人相等,还有5%的可能性与被抚养人不同。

现在,偶然地在您的数据上有一个预测变量在97%的时间内等于对整个数据的依赖,而另一个在93%的时间内等于整个数据的依赖。您将选择97%的预测变量并构建模型。在交叉验证的每一步中,您都将拥有模型相关的=预测变量,因为它几乎总是正确的。因此,您将获得97%的交叉预测效果。

现在,您可以说,好吧,这真是不幸。但是,如果按上述方式构造预测变量,则您至少有一个预测变量中有75%的概率在整个数据集上的准确度> 95%,这就是您将选择的预测变量。因此,您有75%的机会高估性能。

在实践中,估计效果并非易事。您的特征选择很有可能会在每个折叠中选择相同的特征,就像您在整个数据集上所做的一样,这样就不会产生偏差。如果您有更多的样本但功能很多,效果也会变小。两种方式同时使用数据并查看结果如何可能会有所启发。

您还可以预留一定数量的数据(例如20%),通过对80%进行交叉验证,使用您自己的方法和正确的方法来获得性能估算,并查看将模型转移到20%时哪种性能预测证明更为准确预留的数据百分比。请注意,要使此工作正常进行,必须仅对80%的数据进行CV之前的功能选择。否则,它不会模拟将模型转移到样本之外的数据。


您可以通过直观的示例来详细说明进行特征选择的正确方法吗?谢谢。
uared1776
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.