模型評估與改進:交叉驗證
- 2022 年 5 月 26 日
- 筆記
- 《Pyhton機器學習基礎教程》, 機器學習
⭐為什麼要劃分測試集與訓練集?
- 用測試集度量模型對未見過數據的泛化性能
⭐交叉驗證
- 數據被多次劃分,需要訓練多個模型
- 最常用K折交叉驗證
-
k是用戶指定的數字,通常取0/5,
-
5折交叉驗證:數據劃分為5部分,每一部分叫做折。每一折依次輪流作為測試集,其餘做訓練集
mglearn.plots.plot_cross_validation()
-
1、scikit-learn中的交叉驗證
利用model_selection中的cross_val_score(模型,訓練數據,真實標籤)
#在iris數據上,利用logisticregre進行評估
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_iris
from sklearn.model_selection import cross_val_score
iris = load_iris()
lrg = LogisticRegression()
scores = cross_val_score(lrg,iris.data,iris.target)
print("cross_validation scores:{}".format(scores))
'''
`cross_validation scores:[0.96666667 1. 0.93333333 0.96666667 1. ]`
'''
默認情況下,cross_val_score執行3折交叉驗證,可通過修改cv值改變折數
#總結交叉驗證精度:計算平均值
print("Average cross-validation:{:.2f}".format(scores.mean()))
'''
`Average cross-validation:0.97`
'''
2、分層k折交叉驗證和其它策略
⭐sklearn裡面的交叉驗證
-
分類問題時使用:分層交叉驗證
- 使每個折中類別之間的比例與整個數據集中的比例相同
-
回歸問題:標準k折交叉驗證
mglearn.plots.plot_stratified_cross_validation()
2.1 對交叉驗證的更多控制
⭐可以用cv來調節cross_val_score的折數
-
sklearn還提供一個交叉驗證分離器(cross_validatoin splitter)作為cv參數
#在分類數據集上使用標準K折交叉驗證 #需要從model_selection導入KFold分離器類,並將其實例化 from sklearn.model_selection import KFold kf = KFold(n_splits=5) #5折 scores = cross_val_score(lrg,iris.data,iris.target,cv=kf) print("cross_validation scores:{}".format(scores)) ''' `cross_validation scores:[1. 1. 0.86666667 0.93333333 0.83333333]` ''' kf = KFold(n_splits=3) #3折 scores = cross_val_score(lrg,iris.data,iris.target,cv=kf) print("cross_validation scores:{}".format(scores)) ''' `cross_validation scores:[0. 0. 0.]` '''
📣
在iris數據集上使用3折交叉驗證很糟,因為它每個折對應一個類別
⭐可以將數據打亂,代替分層
kf = KFold(n_splits=3,shuffle=True)
scores = cross_val_score(lrg,iris.data,iris.target,cv=kf)
print("cross_validation scores:{}".format(scores))
'''
`cross_validation scores:[0.94 0.96 0.98]`
'''
2.2 留一法交叉驗證(leave-one-out)
⭐每折只包含單個樣本的k折交叉驗證
-
每次劃分,選擇單個數據點作為測試集
-
非常耗時,適合小數據集給出好的估計結果
from sklearn.model_selection import LeaveOneOut loo = LeaveOneOut() scores = cross_val_score(lrg,iris.data,iris.target,cv=loo) print("cross_validation scores:{}".format(scores.mean())) ''' `cross_validation scores:0.9666666666666667` '''
2.3 打亂劃分交叉驗證
⭐每次劃分為訓練集取樣train_size個樣本,為測試集取樣test_size個樣本,將這個劃分重複n_iters次
mglearn.plots.plot_shuffle_split()
#將數據集劃分為50%的訓練集和50%的測試集,共運行10次迭代
from sklearn.model_selection import ShuffleSplit
shuffle_split = ShuffleSplit(test_size=.5,train_size=.5,n_splits=10)
scores = cross_val_score(lrg,iris.data,iris.target,cv=shuffle_split)
print("cross_validation scores:{}".format(scores))
'''
```
cross_validation scores:[0.97333333 0.93333333 0.92 0.94666667 0.93333333 0.97333333
0.94666667 0.88 0.97333333 0.96 ]
```
'''
📣
打亂劃分交叉驗證可以在訓練集和測試集大小之外獨立控制迭代次數
允許在每次迭代中僅使用部分數據
- train_size,test_size之和不等於1來實現
2.4 分組交叉驗證
⭐適用於數據中分組高相關度時。
GroupsKFold
-
參數:groups,說明數據屬於哪一組,同一組的數據要麼都在測試集,要麼都在訓練集
from sklearn.model_selection import GroupKFold from sklearn.datasets import make_blobs X,y = make_blobs(n_samples=12,random_state=0) groups = [0,0,0,1,1,1,1,2,2,3,3,3] gk = GroupKFold(n_splits=3) #3折 scores = cross_val_score(lrg,X,y,groups,cv=gk) print("cross_validation scores:{}".format(scores)) ''' `cross_validation scores:[0.75 0.6 0.66666667]` '''
mglearn.plots.plot_group_kfold()
3、交叉驗證的優點
⭐1、每個樣例都能在測試集中出現一次
- 每個樣例位於一個折中,而每一個折都會被作為一次test
⭐2、提供我們的模型對訓練集選擇的敏感性資訊
- 它可以告訴我們模型應用於新數據時在最壞和最好情況下的可能表現
⭐3、對我們的數據的使用更加高效
缺點:增加計算成本
📣記住:交叉驗證不會返回一個模型
- 目的只是評估給定演算法在特定數據集訓練後的泛化性能
4、參考文獻
《python機器學習基礎教程》