1. 程式人生 > >為什麼要用交叉驗證

為什麼要用交叉驗證

本文結構:

  • 什麼是交叉驗證法?
  • 為什麼用交叉驗證法?
  • 主要有哪些方法?優缺點?
  • 各方法應用舉例?

什麼是交叉驗證法?

它的基本思想就是將原始資料(dataset)進行分組,一部分做為訓練集來訓練模型,另一部分做為測試集來評價模型。

為什麼用交叉驗證法?

  1. 交叉驗證用於評估模型的預測效能,尤其是訓練好的模型在新資料上的表現,可以在一定程度上減小過擬合。
  2. 還可以從有限的資料中獲取儘可能多的有效資訊。

主要有哪些方法?

1. 留出法 (holdout cross validation)

在機器學習任務中,拿到資料後,我們首先會將原始資料集分為三部分:訓練集、驗證集和測試集


訓練集用於訓練模型,驗證集用於模型的引數選擇配置,測試集對於模型來說是未知資料,用於評估模型的泛化能力。

這個方法操作簡單,只需隨機把原始資料分為三組即可。
不過如果只做一次分割,它對訓練集、驗證集和測試集的樣本數比例,還有分割後資料的分佈是否和原始資料集的分佈相同等因素比較敏感,不同的劃分會得到不同的最優模型,而且分成三個集合後,用於訓練的資料更少了。

於是有了 2. k 折交叉驗證(k-fold cross validation)加以改進:

k 折交叉驗證通過對 k 個不同分組訓練的結果進行平均來減少方差,因此模型的效能對資料的劃分就不那麼敏感。

  • 第一步,不重複抽樣將原始資料隨機分為 k 份。
  • 第二步,每一次挑選其中 1 份作為測試集,剩餘 k-1 份作為訓練集用於模型訓練。
  • 第三步,重複第二步 k 次,這樣每個子集都有一次機會作為測試集,其餘機會作為訓練集。
  • 在每個訓練集上訓練後得到一個模型,
  • 用這個模型在相應的測試集上測試,計算並儲存模型的評估指標,
  • 第四步,計算 k 組測試結果的平均值作為模型精度的估計,並作為當前 k 折交叉驗證下模型的效能指標。

k 一般取 10,
資料量小的時候,k 可以設大一點,這樣訓練集佔整體比例就比較大,不過同時訓練的模型個數也增多。
資料量大的時候,k 可以設小一點。

當 k=m 即樣本總數時,叫做 3. 留一法(Leave one out cross validation)

,每次的測試集都只有一個樣本,要進行 m 次訓練和預測。
這個方法用於訓練的資料只比整體資料集少了一個樣本,因此最接近原始樣本的分佈。
但是訓練複雜度增加了,因為模型的數量與原始資料樣本數量相同。
一般在資料缺乏時使用。

此外:

  1. 多次 k 折交叉驗證再求均值,例如:10 次 10 折交叉驗證,以求更精確一點。
  2. 劃分時有多種方法,例如對非平衡資料可以用分層取樣,就是在每一份子集中都保持和原始資料集相同的類別比例。
  3. 模型訓練過程的所有步驟,包括模型選擇,特徵選擇等都是在單個摺疊 fold 中獨立執行的。

還有一種比較特殊的交叉驗證方式,Bootstrapping: 通過自助取樣法,即在含有 m 個樣本的資料集中,每次隨機挑選一個樣本,再放回到資料集中,再隨機挑選一個樣本,這樣有放回地進行抽樣 m 次,組成了新的資料集作為訓練集。

這裡會有重複多次的樣本,也會有一次都沒有出現的樣本,原資料集中大概有 36.8% 的樣本不會出現在新組資料集中。

優點是訓練集的樣本總數和原資料集一樣都是 m,並且仍有約 1/3 的資料不被訓練而可以作為測試集。
缺點是這樣產生的訓練集的資料分佈和原資料集的不一樣了,會引入估計偏差。
此種方法不是很常用,除非資料量真的很少。

各方法應用舉例?

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...

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]

相關推薦

2.機器學習之 為什麼交叉驗證

本文結構: 什麼是交叉驗證法? 為什麼用交叉驗證法? 主要有哪些方法?優缺點? 各方法應用舉例? 什麼是交叉驗證法? 它的基本思想就是將原始資料(dataset)進行分組,一部分做為訓練集來訓練模型,另一部分做為測試集來評價模型。 為什麼用交叉驗證法? 交叉驗證

為什麼交叉驗證

本文結構: 什麼是交叉驗證法? 為什麼用交叉驗證法? 主要有哪些方法?優缺點? 各方法應用舉例? 什麼是交叉驗證法? 它的基本思想就是將原始資料(dataset)進行分組,一部分做為訓練集來訓練模型,另一部分做為測試集來評價模型。 為

交叉驗證改善模型的預測表現(適用於Python和R)

我一直對資料界的程式設計馬拉松(Hackathons)保持關注。通過對比排名榜初期和最終的結果, 我發現了一個有趣的現象:在初期排名較高的參賽者,在最終的驗證環節往往地位不保,有些甚至跌出前 20 名。 猜猜是什麼對引起了排名的劇烈變化?換句話說,為什麼這些參

交叉驗證調整KNN模型的引數

import pandas as pd import matplotlib.pyplot as plt import numpy as np #載入資料 def inspect_data(file_root): dataframe=pd.read_csv(file_r

K折交叉驗證估計KNN演算法中的K值

       前幾天用KNN對自己的資料進行了分類,對於KNN中的K值,之前一直是靠緣分來試的,試的時候感覺K=3的效果挺好的。之後看了好多CSDN的部落格,發現一般大家除了靠緣分去試K值之外,也會採用交叉驗證的方法去近似求得K值,因此我決定自己實現一下,看看有什麼效果。 

由於mpu6050模塊,所以上i2c通信原理。

發送 表示 error art 多個 實時性 erro 字節 空閑 i2c通信原理 i2c總線只有兩根雙向信號線,一根是數據線SDA,一根是時鐘線SCL。 每個接到i2c總線上的器件都有唯一的地址,主機與其他器件之間的數據傳送可以是由主

為什麽MarkDown?

doc bsp 寫作 ffi 心情 color href 編輯 off 【為什麽要用MarkDown?】   大部分作家用 Word 或 Pages 寫作,過去的文檔也大都以 .doc, .docx 格式或是 Pages 格式儲存。還有人為了保證文稿發給誰都能正常打開,會

程序員為什麽一定Linux

linux程序員大多數人引薦Linux,基本上都會說Linux讓你更高效、更優異。然而工具只是工具。然而工具只是工具。然而工具只是工具。優異程序員和不優異程序員的差異首先是態度上的差異。他們有自個的理想,考慮許多,不管是項目開端之前還是在項目進行中,項目完結以後也會進行總結。他們對待疑問對比謹慎,考慮對比全部

重構機房收費系統你的——異常處理和拋出異常(try catch finally)——(vb.net)

style post blue 通過 alt list bcm round 導致 你能保證你的程序不會出問題嗎? 不能 當你的程序執行到某個地方發生了你不想要的結果。你是否想讓它一錯再錯? 不想 你是否想讓你的程序占著茅坑不拉屎? 不想 你是否想知道你的程序出錯的原因?

R語言——K折交叉驗證之隨機均分數據集

present sent new 理解 6.5 ble 數據表 uno repr 今天,在閱讀吳喜之教授的《復雜數據統計方法》時,遇到了把一個數據集按照某個因子分成若幹子集,再把若幹子集隨機平均分成n份的問題,吳教授的方法也比較好理解,但是我還是覺得有點繁瑣,因此自己編寫了

原始方法解析復雜字符串,json一定JsonMapper麽?

之間 正則表達式 isn ces plain cli shu 如何解決 clist 轉自數據之巔原文用原始方法解析復雜字符串,json一定要用JsonMapper麽? 閱讀目錄 1.不規則非json字符串 2.鍵值對字符串分割函數 3.復雜Json格式

交叉驗證

out 真的 trap for tex 估計 深入分析 neu 一份 交叉驗證是在機器學習建立模型和驗證模型參數時常用的辦法。交叉驗證,顧名思義,就是重復的使用數據,把得到的樣本數據進行切分,組合為不同的訓練集和測試集,用訓練集來訓練模型,用測試集來評估模型預測的好壞。在此

React為啥很多類裏的標簽上事件處理函數bind(this)

return 運行 情況 col 有時 code urn ole ret    render() { return ( <div> <p onClick={this.clic

微軟放大招:人工智能抗擊黑客

data 隨著 應用 範圍 以及 pac 提供商 新功能 時代 最近一段時間,在全球互聯網界可不太平,先是比特幣病 毒“WannaCry”席卷全球,這幾天又有“Petya”病 毒襲擊用戶電腦的消息傳出。人們不禁會問:我們的網絡安全要如何維護? ▲petya病 毒 作為全球頂

Django自帶驗證框架

eat 一個 onetoone ast staf req als rect blank 一 分析源碼 User Django的標準庫存放在 django.contrib 包中。每個子包都是一個獨立的附加功能包。 這些子包一般是互相獨立的,不過有些d

(轉)log4j(一)——為什麽log4j?

控制 clas 姓名 private 開發環境 負責人 getname 麻煩 方法名 1 試驗環境 OS:win7 JDK:jdk7 Log4j:1.2.17(好尷尬,原本是想試驗下log4j2的,結果陰差陽錯用了這個版本,不過幸好,試驗也不白試驗,試驗的作用是一樣的

為什麽獨立香港服務器,真的只是因為它速度快嗎

為什麽要用獨立香港服務器對於很多人來說都不太理解,也不清楚為什麽需要這樣做,對於獨立香港服務器 的好處也不太清楚明白,只是聽人說好,所以就用了,其實大家說他好其實是有原因,下面我們就有請專業 的人士來給我們大家講解一下,獨立香港服務器的好處有哪些。 1、獨立香港服務器,在使用上,更加的安全,

交叉驗證思想

避免 實用 utm -o val 出現 循環 集合 階段 交叉驗證 寫一個函數,實現交叉驗證功能,不能用sklearn庫。 交叉驗證(Cross-Validation): 有時亦稱循環估計, 是一種統計學上將數據樣本切割成較小子集的實用方法。於是可以先在一個子集上做分析,

為什麽Docker

專用 linux style 為什麽 學習 工作 一個 無限 神秘感 說起學習docker,本人有以下的原因,大道理就不說了,他的好處結果自身的工作來談談 1、源於他的神秘感,有好多人在用,所以就去學。 2、因為容器具有封閉性,在一個服務器裏,可以有好多容器。每個容器他可以

為什麽多線程

2個 只需要 成員變量 變量 混亂 了解 pan 運算 完成 1. 先討論一下CApp類的實質。App就是一個用戶界面線程。 1.1 App對象使一個線程具有了處理消息的能力,而線程本身並沒有這個能力,(了解這一點的目的在於弄清楚線程消息的概念。)擁有這種能力的線程也就是用