CH1 统计学习方法概论|1.5.2交叉验证《统计学习方法》-学习笔记

文章原创,最近更新:2018-06-11

1.什么是交叉验证法?
2.为什么用交叉验证法?
3.交叉验证主要有哪些方法?优缺点?
4.各方法应用举例?

参考链接:
1、 为什么要用交叉验证?
2、机器学习中的交叉验证
3、K折交叉验证的前生今世
4、统计挖掘那些事:分层抽样与交叉验证
5、交叉验证,模型选择(cross validation)
6、10折交叉验证的例子
前言:通过网上找的文章,通过归纳总结具体如下:

1.什么是交叉验证法?

在说交叉验证以前,我们先想一下我们在搭建模型时的关于数据切分的常规做法[直接利用train_test_split把所有的数据集分成两部分:train_datatest_data,先在train_data上进行训练,然后再在test_data上进行测试评估模型效果的好坏。

因为我们训练模型时,不是直接把数丢进去就好了,而是需要对模型的不断进行调整(比如参数),使模型在测试集上的表现足够好,但是即使模型在测试集上效果好,不一定在其他数据集上效果好,因为这个模型是“专门”针对这个测试集而调整的,你为了测试这个模型真正的效果,你就得找另外的一部分数据,看模型在这些数据上的效果怎么样,只有模型在另外的数据上效果也好,那才可以说明的模型的效果是真的好(泛化能力不错,也可以理解成是举一反三的能力)。

其实这个和我们上学时候的上课—做练习题—考试的关系很像,我们在每上完每一节课的时候,就会去做练习题来检验这节课的知识点掌握的怎么样,你的练习题几乎全部能做对,可能是因为刚上完这个章节,你一看到题就知道用这节课的知识点,直接把知识点套进去就可以做出来,每章如此,但是,期末考试的时候是把所有的章节结合起来考,不会告诉你用哪个知识点,这个时候就是检验你是否真的把这个知识点学会了的时候,你只有在期末考试的时候考的好,才能说明你是真的学习好。

简单通俗的表达:


为了方便调试超参数,从训练集中划分一部分作为验证集,但是由于划分出一个验证集调节的参数可能受到验证集数据影响有偏差不够准确,于是进行交叉,如图,其中fold1-fold5可以进行任意4个组合作为训练集,剩下一个作为验证集,这样得到不同的训练模型,然后对最终预测结果进行求平均,这样就消除了只取一次验证集调节参数带来的“偏见”.

总结:
它的基本思想就是将原始数据(dataset)进行分组,一部分做为训练集来训练模型,另一部分做为测试集来评价模型。

2.为什么用交叉验证法?

这样就需要把数据分成三份,一份训练、一份验证、一份测试,先在训练集上训练模型,然后验证模型结果,最后再在测试集上判断模型的真正效果,但是这样做的结果就是大幅降低了数据的使用率,因训练数据不够多而造成欠拟合,并且数据切分的随机性也会对模型的效果有影响,这两个问题可以通过交叉验证(CV)的方式解决。

总结:

  • 1.交叉验证用于评估模型的预测性能,尤其是训练好的模型在新数据上的表现,可以在一定程度上减小过拟合。
  • 2.还可以从有限的数据中获取尽可能多的有效信息。

3.交叉验证主要有哪些方法?优缺点?

3.1简单交叉验证(hold-outcross validation)

简单交叉验证方法是:首先随机地将已给数据分为两部分,一部分作为训练集,另一部分作为测试集(例如,70%的数据为训练集,30%的数据为测试集);然后用训练集在各种条件下(例如,不同的参数个数)训练模型,从而得到不同的模型;在测试集上评价各个模型的测试误差,选出测试误差最小的模型.

缺点:
在于得到的最佳模型是在70%的训练数据上选出来的,不代表在全部训练数据上是最佳的。还有当训练数据本来就很少时,再分出测试集后,训练数据就太少了。
其实严格意义来说Hold-OutMethod并不能算是CV,因为这种方法没有达到交叉的思想,由于是随机的将原始数据分组,所以最后验证集分类准确率的高低与原始数据的分组有很大的关系,所以这种方法得到的结果其实并不具有说服性.

3.2 k折交叉验证(k-fold cross validation)

进一步对简单交叉验证方法再做一次改进,如下:

  • 第一步,不重复抽样将原始数据随机分为 k 份。
  • 第二步,每一次挑选其中 1 份作为测试集,剩余 k-1 份作为训练集用于模型训练。
  • 第三步,重复第二步 k 次,这样每个子集都有一次机会作为测试集,其余机会作为训练集。
  • 在每个训练集上训练后得到一个模型,
  • 用这个模型在相应的测试集上测试,计算并保存模型的评估指标,
  • 第四步,计算 k 组测试结果的平均值作为模型精度的估计,并作为当前 k 折交叉验证下模型的性能指标。

k 一般取 10,
数据量小的时候,k 可以设大一点,这样训练集占整体比例就比较大,不过同时训练的模型个数也增多。
数据量大的时候,k 可以设小一点。

通俗的表达:
一般我们常用十折交叉检验,不妨我们设定k=10,具体如下:

  • 首先我们把总数据集划分为10份,分别成D1,D2,… …,D10;
  • 首先选择D1数据集作为测试集,D2,…D10作为训练集。在训练集上构建模型,在测试集上进行模型评估,得到评估记过O1;
  • 之后选择D2数据集作为测试集,D1,D3,…D10作为训练集。在训练集上构建模型,在测试集上进行模型评估,得到评估记过O2;
  • 分别抽去D3,D4,…,D10作为测试集,一共重复10次,并得到10个结果:O1,O2,…,O10;
  • 将得到10个结果:O1,O2,…,O10加和取平均,作为最终评估结果O。



以上过程,我们称之为10折交叉检验。一般而言,在平常的使用中,10折交叉检验比较常见,当然也会有5折交叉检验,3折交叉检验。

此方法称为k-fold cross validation(k-折叠交叉验证)说白了,这个方法就是将简单交叉验证的测试集改为1/k,每个模型训练k次,测试k次,预测误差为k次的平均。K一般大于等于2,实际操作时一般从3开始取,只有在原始数据集合数据量小的时候才会尝试取2.

K-CV可以有效的避免过学习以及欠学习状态的发生,最后得到的结果也比较具有说服性.一般讲k取值为10。这样数据稀疏时基本上也能进行。

缺点:
缺点就是训练和测试次数过多。

案例:
关于10折交叉验证的例子,具体如下:

  • 第1步,将数据等分到10个桶中。
    我们会将50名篮球运动员和50名非篮球运动员分到每个桶中。每个桶当中放入了100人的信息。
  • 第2步,下列步骤重复10次。

(1)每一次迭代中留存其中一个桶。第一次迭代中留存桶1,第二次留存桶2,其余依此类推。
(2)用其他9个桶的信息训练分类器(第一次迭代中利用从桶2到桶10的信息训练分类器)。
(3)利用留存的数据来测试分类器并保存测试结果。在上例中,这些结果可能如下:35个篮球运动员被正确分类;29个非篮球运动员被正确分类。

  • 第3步,对上述结果汇总。

通常情况下我们会将结果放到与下表类似的表格中:


在所有500名篮球运动员中,有372人被正确分类。可能需要做的一件事是将右下角的数字也加上去,也就是说1000人当中有652(372+280)人被正确分类。因此得到的精确率为65.2%。与2折或3折交叉验证相比,基于10折交叉验证得到的结果可能更接近于分类器的真实性能。之所以这样,是因为每次采用90%而不是2折交叉验证中仅仅50%的数据来训练分类器。

3.3 留一交叉验证(leave one out cross validation)

它是指,我们令样本划分次数k等于数据集合D的样本数量n,即对样本集合D划分为n份子集,每份子集只包含一个样本。

优缺点:

留一法的主要不足在于计算的开销很大。考虑一个包含1000个实例的中等规模的数据集,需要一分钟来训练分类器。对于10折交叉验证来说,我们将花费10分钟用于训练。而对于留一法来说,训练时间需要16个小时。如果数据集包含百万样本,那么花费在训练上的总时间将接近两年。我的天哪!

3.4注意事项

交叉验证使用中注意的事项:

  • 训练集中样本数量要足够多,一般至少大于总样本数的50%。
  • 训练集和测试集必须从完整的数据集中均匀取样。均匀取样的目的是希望减少训练集、测试集与原数据集之间的偏差。当样本数量足够多时,通过随机取样,便可以实现均匀取样的效果。(随机取样,可重复性差)

4.各方法应用举例?

4.1留出法 (holdout cross validation)

下面例子,一共有 150 条数据:

>>> import numpy as np
>>> from sklearn.model_selection import train_test_split
>>> from sklearn import datasets
>>> from sklearn import svm

>>> iris = datasets.load_iris()
>>> iris.data.shape, iris.target.shape
((150, 4), (150,))

用 train_test_split 来随机划分数据集,其中 40% 用于测试集,有 60 条数据,60% 为训练集,有 90 条数据:

>>> X_train, X_test, y_train, y_test = train_test_split(
...     iris.data, iris.target, test_size=0.4, random_state=0)

>>> X_train.shape, y_train.shape
((90, 4), (90,))
>>> X_test.shape, y_test.shape
((60, 4), (60,))

用 train 来训练,用 test 来评价模型的分数。

>>> clf = svm.SVC(kernel='linear', C=1).fit(X_train, y_train)
>>> clf.score(X_test, y_test)                           
0.96...

4.2 k 折交叉验证(k-fold cross validation)

最简单的方法是直接调用 cross_val_score,这里用了 5 折交叉验证:

>>> from sklearn.model_selection import cross_val_score
>>> clf = svm.SVC(kernel='linear', C=1)
>>> scores = cross_val_score(clf, iris.data, iris.target, cv=5)
>>> scores                                              
array([ 0.96...,  1.  ...,  0.96...,  0.96...,  1.        ])

得到最后平均分为 0.98,以及它的 95% 置信区间:

>>> print("Accuracy: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))
Accuracy: 0.98 (+/- 0.03)

我们可以直接看一下 K-fold是怎样划分数据的:
X 有四个数据,把它分成 2 折,
结果中最后一个集合是测试集,前面的是训练集,
每一行为 1 折:

>>> import numpy as np
>>> from sklearn.model_selection import KFold

>>> X = ["a", "b", "c", "d"]
>>> kf = KFold(n_splits=2)
>>> for train, test in kf.split(X):
...     print("%s %s" % (train, test))
[2 3] [0 1]
[0 1] [2 3]

同样的数据 X,我们看 LeaveOneOut后是什么样子,
那就是把它分成 4 折,
结果中最后一个集合是测试集,只有一个元素,前面的是训练集,
每一行为 1 折:

>>> from sklearn.model_selection import LeaveOneOut

>>> X = [1, 2, 3, 4]
>>> loo = LeaveOneOut()
>>> for train, test in loo.split(X):
...     print("%s %s" % (train, test))
[1 2 3] [0]
[0 2 3] [1]
[0 1 3] [2]
[0 1 2] [3]
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343