天天看點

翻譯:提高既定資料集下的模型效果——交叉驗證(CrossValidaton)

官方文檔連結

資料給定&模型給定的前提下,怎麼提高訓練模型的效果?

資料和模型給定之後,我們隻有一條路:提高資料的利用效率。方法有兩個:

1)使用train_test_split函數分成訓練集和測試集;

2)通過CrossValidaton (cross_val_score函數) 進一步壓榨訓練集的價值;

1) 一般我們用的方法是:将原始資料集分為 訓練資料集 & 測試資料集。

優點:思路正确,但僅僅是思路正确。

缺點:思路正确,但是方法不夠高明。

import numpy as np
from sklearn.model_selection import train_test_split
from sklearn import datasets                  # sklearn 自帶的給學習人員用的資料集
from sklearn import svm

# 首先,引入原始資料集
x, y = datasets.load_iris(return_X_y=True)    # iris: 鸢尾花資料集
print(x.shape)
print(y.shape)
"""
結果如下:
(150, 4)
(150,)
"""
           
# 其次,把資料集按6:4的比例劃分為訓練資料集和測試資料集
x_train, x_test, y_train, y_test = train_test_split(x, y, train_size=0.6, random_state=0) # random_state的用處見下邊注釋。

print(x_train.shape)
print(x_test.shape)
print(y_train.shape)
print(y_test.shape)
"""
結果如下:
(90, 4)
(60, 4)
(90,)
(60,)
"""
           
# 最後,用SVC模型測試一下:
clf = svm.SVC(kernel='linear', C=1)  # C的作用見下便注釋
clf.fit(x_train, y_train)
score = clf.score(x_test, y_test)

print(score)
"""
0.9666666666666667
"""
           
注釋:
  1. train_test_split(random_state=0):一方面,random_state不設定的話,每次函數train_test_split得到的訓練集和測試集都不一樣;另一方面,random_state設定為INT的話每次得到的訓練集和測試集保持一緻(INT可以是0也可以是42,效果一樣)
  2. svm.SVC(C=1):kernel='linear'時
    翻譯:提高既定資料集下的模型效果——交叉驗證(CrossValidaton)
    ,C用來告訴SVM你有多想把訓練資料正确分好類。對于一個大的C值,分類器選用margin小的超平面,代價是分類器的泛化性會降低;反之亦然,

評價:

一方面,看它的優點:如果原始資料集沒有被劃分為 訓練資料集&測試資料集兩部分,而是直接給訓練模型的話,結果會是過拟合、泛化能力極低(即模型完美于預測樣本資料,完敗于預測原始樣本之外的任何資料);

另一方面看它的不足:

  1. 訓練結果更大地依賴于訓練資料集和測試資料集占原始資料集的比重。
  2. 用訓練資料集得到算法參數/模型參數的方法不夠好,因為最終的一組參數其實是從N組參數中對比得來的,這意味着測試資料集的資訊會被間接地洩露出來,參數調整得越多、洩露越多,使得測試資料集的意義越低;

2)一個壓榨資料價值更好的方法就是 cross-validation / CV / 交叉檢驗:

以k-fold CV為例:仍然是把原始資料集分成訓練集和測試集,但是訓練模型的時候不使用測試集。最常見的一個叫做k_fold CV。

  • 具體來說就是把訓練集平分為k個fold,其中每個fold依次作為測試集、餘下的作為訓練集,進行k次訓練,得到共計k組參數。取k組參數的均值作為模型的最終參數。
  1. 優點:充分壓榨了資料集的價值。在樣本集不夠大的情況下尤其珍貴。
  2. 缺點:運算起來花時間。
翻譯:提高既定資料集下的模型效果——交叉驗證(CrossValidaton)

我們用SVM()/support vector machines(支援向量機)中的SVC分類算法為例:

from sklearn.model_selection import cross_val_score

clf = svm.SVC(kernal='linear', C=1)
scores = cross_val_score(clf, x, y, cv=5)

print(scores)
print(f"Accuracy: {scores.mean():.3f},{scores.std()**2:.3f}")
"""
[0.96666667     1.     0.96666667    0.96666667     1.        ]
Accuracy: 0.980,0.000
"""
           

繼續閱讀