本文結(jié)構(gòu):
- 什么是交叉驗(yàn)證法货邓?
- 為什么用交叉驗(yàn)證法秆撮?
- 主要有哪些方法??jī)?yōu)缺點(diǎn)换况?
- 各方法應(yīng)用舉例职辨?
什么是交叉驗(yàn)證法?
它的基本思想就是將原始數(shù)據(jù)(dataset)進(jìn)行分組戈二,一部分做為訓(xùn)練集來(lái)訓(xùn)練模型舒裤,另一部分做為測(cè)試集來(lái)評(píng)價(jià)模型。
為什么用交叉驗(yàn)證法觉吭?
- 交叉驗(yàn)證用于評(píng)估模型的預(yù)測(cè)性能腾供,尤其是訓(xùn)練好的模型在新數(shù)據(jù)上的表現(xiàn),可以在一定程度上減小過(guò)擬合节值。
- 還可以從有限的數(shù)據(jù)中獲取盡可能多的有效信息黎侈。
主要有哪些方法?
1. 留出法 (holdout cross validation)
在機(jī)器學(xué)習(xí)任務(wù)中贴汪,拿到數(shù)據(jù)后扳埂,我們首先會(huì)將原始數(shù)據(jù)集分為三部分:訓(xùn)練集阳懂、驗(yàn)證集和測(cè)試集柜思。
訓(xùn)練集用于訓(xùn)練模型赡盘,驗(yàn)證集用于模型的參數(shù)選擇配置,測(cè)試集對(duì)于模型來(lái)說(shuō)是未知數(shù)據(jù)葱淳,用于評(píng)估模型的泛化能力赞厕。
這個(gè)方法操作簡(jiǎn)單定硝,只需隨機(jī)把原始數(shù)據(jù)分為三組即可蔬啡。
不過(guò)如果只做一次分割星爪,它對(duì)訓(xùn)練集顽腾、驗(yàn)證集和測(cè)試集的樣本數(shù)比例,還有分割后數(shù)據(jù)的分布是否和原始數(shù)據(jù)集的分布相同等因素比較敏感久信,不同的劃分會(huì)得到不同的最優(yōu)模型裙士,而且分成三個(gè)集合后管毙,用于訓(xùn)練的數(shù)據(jù)更少了夭咬。
于是有了 2. k 折交叉驗(yàn)證(k-fold cross validation)加以改進(jìn):
k 折交叉驗(yàn)證通過(guò)對(duì) k 個(gè)不同分組訓(xùn)練的結(jié)果進(jìn)行平均來(lái)減少方差南用,因此模型的性能對(duì)數(shù)據(jù)的劃分就不那么敏感掏湾。
- 第一步融击,不重復(fù)抽樣將原始數(shù)據(jù)隨機(jī)分為 k 份砚嘴。
- 第二步,每一次挑選其中 1 份作為測(cè)試集耸采,剩余 k-1 份作為訓(xùn)練集用于模型訓(xùn)練虾宇。
- 第三步嘱朽,重復(fù)第二步 k 次搪泳,這樣每個(gè)子集都有一次機(jī)會(huì)作為測(cè)試集扼脐,其余機(jī)會(huì)作為訓(xùn)練集奋刽。
- 在每個(gè)訓(xùn)練集上訓(xùn)練后得到一個(gè)模型佣谐,
- 用這個(gè)模型在相應(yīng)的測(cè)試集上測(cè)試狭魂,計(jì)算并保存模型的評(píng)估指標(biāo)雌澄,
- 第四步仔役,計(jì)算 k 組測(cè)試結(jié)果的平均值作為模型精度的估計(jì),并作為當(dāng)前 k 折交叉驗(yàn)證下模型的性能指標(biāo)任柜。
k 一般取 10沛厨,
數(shù)據(jù)量小的時(shí)候宅粥,k 可以設(shè)大一點(diǎn)秽梅,這樣訓(xùn)練集占整體比例就比較大剿牺,不過(guò)同時(shí)訓(xùn)練的模型個(gè)數(shù)也增多晒来。
數(shù)據(jù)量大的時(shí)候湃崩,k 可以設(shè)小一點(diǎn)。
當(dāng) k=m 即樣本總數(shù)時(shí)朵诫,叫做 3. 留一法(Leave one out cross validation)剪返,每次的測(cè)試集都只有一個(gè)樣本,要進(jìn)行 m 次訓(xùn)練和預(yù)測(cè)。
這個(gè)方法用于訓(xùn)練的數(shù)據(jù)只比整體數(shù)據(jù)集少了一個(gè)樣本宾毒,因此最接近原始樣本的分布诈铛。
但是訓(xùn)練復(fù)雜度增加了幢竹,因?yàn)槟P偷臄?shù)量與原始數(shù)據(jù)樣本數(shù)量相同焕毫。
一般在數(shù)據(jù)缺乏時(shí)使用邑飒。
此外:
- 多次 k 折交叉驗(yàn)證再求均值疙咸,例如:10 次 10 折交叉驗(yàn)證撒轮,以求更精確一點(diǎn)贼穆。
- 劃分時(shí)有多種方法扮惦,例如對(duì)非平衡數(shù)據(jù)可以用分層采樣崖蜜,就是在每一份子集中都保持和原始數(shù)據(jù)集相同的類別比例。
- 模型訓(xùn)練過(guò)程的所有步驟抡柿,包括模型選擇洲劣,特征選擇等都是在單個(gè)折疊 fold 中獨(dú)立執(zhí)行的囱稽。
還有一種比較特殊的交叉驗(yàn)證方式战惊,Bootstrapping: 通過(guò)自助采樣法,即在含有 m 個(gè)樣本的數(shù)據(jù)集中况凉,每次隨機(jī)挑選一個(gè)樣本刁绒,再放回到數(shù)據(jù)集中知市,再隨機(jī)挑選一個(gè)樣本,這樣有放回地進(jìn)行抽樣 m 次速蕊,組成了新的數(shù)據(jù)集作為訓(xùn)練集初狰。
這里會(huì)有重復(fù)多次的樣本,也會(huì)有一次都沒(méi)有出現(xiàn)的樣本互例,原數(shù)據(jù)集中大概有 36.8% 的樣本不會(huì)出現(xiàn)在新組數(shù)據(jù)集中奢入。
優(yōu)點(diǎn)是訓(xùn)練集的樣本總數(shù)和原數(shù)據(jù)集一樣都是 m,并且仍有約 1/3 的數(shù)據(jù)不被訓(xùn)練而可以作為測(cè)試集媳叨。
缺點(diǎn)是這樣產(chǎn)生的訓(xùn)練集的數(shù)據(jù)分布和原數(shù)據(jù)集的不一樣了腥光,會(huì)引入估計(jì)偏差。
此種方法不是很常用糊秆,除非數(shù)據(jù)量真的很少武福。
各方法應(yīng)用舉例?
1. 留出法 (holdout cross validation)
下面例子捉片,一共有 150 條數(shù)據(jù):
>>> 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 來(lái)隨機(jī)劃分?jǐn)?shù)據(jù)集莹规,其中 40% 用于測(cè)試集,有 60 條數(shù)據(jù),60% 為訓(xùn)練集,有 90 條數(shù)據(jù):
>>> 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 來(lái)訓(xùn)練括荡,用 test 來(lái)評(píng)價(jià)模型的分?jǐn)?shù)。
>>> clf = svm.SVC(kernel='linear', C=1).fit(X_train, y_train)
>>> clf.score(X_test, y_test)
0.96...
2. k 折交叉驗(yàn)證(k-fold cross validation)
最簡(jiǎn)單的方法是直接調(diào)用 cross_val_score州邢,這里用了 5 折交叉驗(yàn)證:
>>> 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% 置信區(qū)間:
>>> print("Accuracy: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))
Accuracy: 0.98 (+/- 0.03)
我們可以直接看一下 K-fold 是怎樣劃分?jǐn)?shù)據(jù)的:
X 有四個(gè)數(shù)據(jù)摘刑,把它分成 2 折紧唱,
結(jié)果中最后一個(gè)集合是測(cè)試集深胳,前面的是訓(xùn)練集敛劝,
每一行為 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]
同樣的數(shù)據(jù) X像捶,我們看 LeaveOneOut 后是什么樣子硼莽,
那就是把它分成 4 折矾瑰,
結(jié)果中最后一個(gè)集合是測(cè)試集采幌,只有一個(gè)元素,前面的是訓(xùn)練集凫岖,
每一行為 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]
資料:
機(jī)器學(xué)習(xí)
http://scikit-learn.org/stable/modules/cross_validation.html
https://ljalphabeta.gitbooks.io/python-/content/kfold.html
http://www.csuldw.com/2015/07/28/2015-07-28%20crossvalidation/
推薦閱讀 歷史技術(shù)博文鏈接匯總
http://www.reibang.com/p/28f02bb59fe5
也許可以找到你想要的