1. 程式人生 > >機器學習中資料訓練集,測試集劃分與交叉驗證的聯絡與區別(含程式)

機器學習中資料訓練集,測試集劃分與交叉驗證的聯絡與區別(含程式)


因為一個模型僅僅重複了剛剛訓練過的樣本的標籤,這種情況下得分會很高,但是遇到沒有訓練過的樣本就無法預測了。這種情況叫做過擬合。為了避免過擬合,一個常見的做法就是在進行一個(有監督的)機器學習實驗時,保留一部分樣本作為測試集(X_test, y_test。為了提高訓練資料的泛化能力,我們把訓練集和測試集對半劃分,即:X_testy_test=11test_size=0.5。但是僅僅如此,再訓練時,訓練集可能自身會出現過擬合現象,從而使測試集的驗證效果降低。為了解決這個問題,另一部分資料被取出來作為“驗證集”:在訓練集上訓練,驗證集上評估,當實驗看起開比較成功的時候,在測試集上進行最終的評估

但是把獲得的資料分成三部分,會大量減少訓練模型的樣本數量,並且結果很依賴於隨機選擇的訓練和驗證集解決這個問題的一個方法就是交叉驗證(簡寫CV)。如採用10次交叉驗證(或者留出法)。


下面看一篇部落格,已經詳細敘述了下他們的聯絡與區別

https://blog.csdn.net/laolu1573/article/details/51160019

在一個數據集上學習預測函式的引數並且在相同的資料集上測試是一種錯誤的方法:因為一個模型僅僅重複了剛剛訓練過的樣本的標籤,這種情況下得分會很高,但是遇到沒有訓練過的樣本就無法預測了。這種情況叫做過擬合。為了避免過擬合,一個常見的做法就是在進行一個(有監督的)機器學習實驗時,保留一部分樣本作為測試集(X_test, y_test)。需要注意的是,“實驗”這個詞並不是為了表示只是學術上使用,即使是商用場景,機器學習通常也是從實驗著手。

scikit- learn中,使train_test_split這個幫助函式可以很快的將樣本隨機的切分成訓練集和測試集。我們現在載入iris資料集來訓練一

個線性支援向量機:

>>> import numpy as np
>>> from sklearn import cross_validation
>>> from sklearn import datasets
>>> from sklearn import svm

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

我們現在可以很快的取樣出一個訓練集,並且拿出40%的資料來測試(評估)我們的估計器:

>>> X_train, X_test, y_train, y_test = cross_validation.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,))

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

在評估不同設定(超參)對分類器的影響時(比如 SVM的需要人工設定的C 這個引數),因為需要不斷調整引數直到分類器效能最好,仍然存在在測試資料集上的過擬合現象。這種情況下,模型會漏掉測試集資料的知識,評估矩陣不能反應其泛化效能。為了解決這個問題,另一部分資料被取出來作為“驗證集”:在訓練集上訓練,驗證集上評估,當實驗看起開比較成功的時候,在測試集上進行最終的評估。

但是把獲得的資料分成三部分,會大量減少訓練模型的樣本數量,並且結果很依賴於隨機選擇的訓練和驗證集。

解決這個問題的一個方法就是交叉驗證(簡寫CV)。依然需要保留一個測試集來做最後評估,但是不需要驗證集。最基本的方法,就是k-折交叉驗證,訓練集被分成K個小集合(其他方法將在後面描述,但是一般遵守相同的準則)。這K“折”的每個都依照下面的過程:

  • k-1部分作為訓練樣本來訓練模型;
  • 用剩餘1部分資料對訓練好的模型進行驗證。
k-折交叉驗證的準確率是迴圈中計算的每個準確率的平均。這種方式可能計算消耗大些,但是不需要浪費很多資料(對比固定任意測試集的情況),這是解決小樣本情況下逆向推理的一個主要優勢。3.1.1.計算交叉驗證矩陣使用交叉驗證的最簡單的方法是在估計器和資料集上使用下面的例子示例了怎樣通過切分資料,擬合模型和連續5次計算得分(每次使用不同的切片)來估計線性核函式SVM在iris資料上準確率。
>>> clf = svm.SVC(kernel='linear', C=1)
>>> scores = cross_validation.cross_val_score(
...    clf, iris.data, iris.target, cv=5)
...
>>> scores                                              
array([ 0.96...,  1.  ...,  0.96...,  0.96...,  1.        ])

給出平均得分和在95%的置信區間內的估計得分:
>>> print("Accuracy: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))
Accuracy: 0.98 (+/- 0.03)
預設每次CV迭代計算的得分是估計器的score方法得分,可以使用得分引數改變預設配置。
>>> from sklearn import metrics
>>> scores = cross_validation.cross_val_score(clf, iris.data, iris.target,
...     cv=5, scoring='f1_weighted')
>>> scores                                              
array([ 0.96...,  1.  ...,  0.96...,  0.96...,  1.        ])