sklearn中交叉驗證

交叉驗證概述

進行模型驗證的一個重要目的是要選出一個最合適的模型嚷堡,對于監(jiān)督學(xué)習而言,我們希望模型對于未知數(shù)據(jù)的泛化能力強艇棕,所以就需要模型驗證這一過程來體現(xiàn)不同的模型對于未知數(shù)據(jù)的表現(xiàn)效果蝌戒。

最先我們用訓(xùn)練準確度(用全部數(shù)據(jù)進行訓(xùn)練和測試)來衡量模型的表現(xiàn)串塑,這種方法會導(dǎo)致模型過擬合;為了解決這一問題北苟,我們將所有數(shù)據(jù)分成訓(xùn)練集和測試集兩部分疾牲,我們用訓(xùn)練集進行模型訓(xùn)練诲锹,得到的模型再用測試集來衡量模型的預(yù)測表現(xiàn)能力楞卡,這種度量方式叫測試準確度篓叶,這種方式可以有效避免過擬合溉旋。

測試準確度的一個缺點是其樣本準確度是一個高方差估計(high varianceestimate)社痛,所以該樣本準確度會依賴不同的測試集胀蛮,其表現(xiàn)效果不盡相同蹂析。

模塊分割方法

K折交叉驗證

  1. 將數(shù)據(jù)集平均分割成K個等份
  2. 使用1份數(shù)據(jù)作為測試數(shù)據(jù)葛碧,其余作為訓(xùn)練數(shù)據(jù)
  3. 計算測試準確率
  4. 使用不同的測試集借杰,重復(fù)2、3步驟
  5. 對測試準確率做平均进泼,作為對未知數(shù)據(jù)預(yù)測準確率的估計

n_splits : 默認3蔗衡,最小為2;K折驗證的K值
shuffle : 默認False;shuffle會對數(shù)據(jù)產(chǎn)生隨機攪動(洗牌)
random_state :默認None乳绕,隨機種子

from sklearn.model_selection import KFold
from numpy import *
X = array([[1, 2], [3, 4], [1, 2], [3, 4]])
y = array([1, 2, 3, 4])
kf = KFold(n_splits=2)
kf.get_n_splits(X)

print(kf)
#kf.split(x) 返回訓(xùn)練集和測試集的索引
# http://scikit-learn.org/stable/modules/generated/sklearn.model_selection.KFold.html
for train_index, test_index in kf.split(X):
   print("TRAIN:", train_index, "TEST:", test_index)
#輸出:TRAIN: [2 3] TEST: [0 1]  
#      TRAIN: [0 1] TEST: [2 3]  
   X_train, X_test = X[train_index], X[test_index]
   y_train, y_test = y[train_index], y[test_index]

Stratified k-fold

與k-fold類似绞惦,將數(shù)據(jù)集劃分成k份,不同點在于洋措,劃分的k份中济蝉,每一份內(nèi)各個類別數(shù)據(jù)的比例和原始數(shù)據(jù)集中各個類別的比例相同。

from sklearn.model_selection importStratifiedKFold  
X= np.array([[1, 2], [3, 4], [1, 2], [3, 4]])  
y= np.array([0, 0, 1, 1])  
skf= StratifiedKFold(n_splits=2)  
skf.get_n_splits(X, y)#給出K折的折數(shù)菠发,輸出為2  
print(skf)   
#輸出為:StratifiedKFold(n_splits=2,random_state=None, shuffle=False)  
for train_index, test_index in skf.split(X, y):  
print("TRAIN:",train_index, "TEST:", test_index)  
X_train,X_test = X[train_index], X[test_index]  
y_train,y_test = y[train_index], y[test_index]  
#輸出:TRAIN: [1 3] TEST: [0 2]  
       TRAIN: [0 2] TEST: [1 3]  

模型驗證方法

cross validation(現(xiàn)在更換為Model selection)大概的意思是:對于原始數(shù)據(jù)我們要將其一部分分為traindata王滤,一部分分為test data。train data用于訓(xùn)練滓鸠,test data用于測試準確率雁乡。在test data上測試的結(jié)果叫做validation error。將一個算法作用于一個原始數(shù)據(jù)糜俗,我們不可能只做出隨機的劃分一次train和testdata踱稍,然后得到一個validation error,就作為衡量這個算法好壞的標準悠抹。因為這樣存在偶然性珠月。我們必須多次的隨機的劃分train data和test data,分別在其上面算出各自的validation error锌钮。這樣就有一組validationerror桥温,根據(jù)這一組validationerror,就可以較好的準確的衡量算法的好壞梁丘。crossvalidation是在數(shù)據(jù)量有限的情況下的非常好的一個evaluate performance的方法侵浸。而對原始數(shù)據(jù)劃分出train data和testdata的方法有很多種旺韭,這也就造成了cross validation的方法有很多種。
返回值就是對于每次不同的的劃分raw data時掏觉,在test data上得到的分類的準確率区端。

參數(shù)解釋:
estimator:是不同的分類器,可以是任何的分類器澳腹。比如支持向量機分類器:estimator = svm.SVC(kernel='linear', C=1)

cv:代表不同的cross validation的方法织盼。如果cv是一個int值,并且如果提供了rawtarget參數(shù)酱塔,那么就代表使用StratifiedKFold分類方式沥邻;如果cv是一個int值,并且沒有提供rawtarget參數(shù)羊娃,那么就代表使用KFold分類方式唐全;也可以給定它一個CV迭代策略生成器,指定不同的CV方法蕊玷。

scoring:默認Nnoe邮利,準確率的算法,可以通過score_func參數(shù)指定垃帅;如果不指定的話延届,是用estimator默認自帶的準確率算法。

from sklearn.model_selection import cross_val_score
from sklearn.datasets import make_blobs
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.tree import DecisionTreeClassifier

X, y = make_blobs(n_samples=10000, n_features=10, centers=100,
  random_state=0)

clf = DecisionTreeClassifier(max_depth=None, min_samples_split=2,
     random_state=0)
scores = cross_val_score(clf, X, y)
print(scores)
print(scores.mean())

clf = RandomForestClassifier(n_estimators=10, max_depth=None,
     min_samples_split=2, random_state=0)
scores = cross_val_score(clf, X, y)
print(scores.mean())

clf = ExtraTreesClassifier(n_estimators=10, max_depth=None,
     min_samples_split=2, random_state=0)
scores = cross_val_score(clf, X, y)
print(scores.mean() > 0.999)

輸出結(jié)果

[0.97852941 0.98212121 0.97757576]
0.9794087938205586
0.9996078431372549
True

實戰(zhàn)

使用knn和iris數(shù)據(jù)集測試
一個是通過 train_test_split方法分割贸诚,訓(xùn)練方庭,預(yù)測,然后metrics.accuracy_score計算準確率赦颇。
或者直接通過上面講的cross_val_score進行驗證二鳄。

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn import metrics
from numpy import *

iris = load_iris()
X = iris.data
y = iris.target
knn = KNeighborsClassifier(n_neighbors=5)
for i in range(1,5):
    print("random_state is ", i,", and accuracy score is:")
    X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=i)
    knn.fit(X_train, y_train)
    y_pred = knn.predict(X_test)
    print(metrics.accuracy_score(y_test, y_pred))

print(cross_val_score(knn,X,y))

輸出

random_state is  1 , and accuracy score is:
1.0
random_state is  2 , and accuracy score is:
1.0
random_state is  3 , and accuracy score is:
0.9473684210526315
random_state is  4 , and accuracy score is:
0.9736842105263158
[0.98039216 0.98039216 1.        ]

可以同時對比logtic回歸和knn的準確率

from sklearn.linear_model import LogisticRegression
iris = load_iris()
X = iris.data
y = iris.target
knn = KNeighborsClassifier(n_neighbors=5)
print(cross_val_score(knn,X,y,cv=10,scoring='accuracy').mean())
logreg = LogisticRegression()
print(cross_val_score(logreg, X, y, cv=10, scoring='accuracy').mean())

用于特征選擇

使用advertising數(shù)據(jù),通過交叉驗證來進行特征的選擇媒怯,對比不同的特征組合對于模型的預(yù)測效果

import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression
# read in the advertising dataset
data = pd.read_csv('http://www-bcf.usc.edu/~gareth/ISL/Advertising.csv', index_col=0)
# create a Python list of three feature names
feature_cols = ['TV', 'radio', 'newspaper']
# use the list to select a subset of the DataFrame (X)
X = data[feature_cols]
# select the Sales column as the response (y)
y = data.sales
# 10-fold cv with all features
lm = LinearRegression()
scores = cross_val_score(lm, X, y, cv=10, scoring='neg_mean_squared_error')
print(scores)

輸出

[-3.56038438 -3.29767522 -2.08943356 -2.82474283 -1.3027754  -1.74163618
 -8.17338214 -2.11409746 -3.04273109 -2.45281793]

這里要注意的是订讼,上面的scores都是負數(shù),為什么均方誤差會出現(xiàn)負數(shù)的情況呢扇苞?因為這里的mean_squared_error是一種損失函數(shù)欺殿,優(yōu)化的目標的使其最小化,而分類準確率是一種獎勵函數(shù)鳖敷,優(yōu)化的目標是使其最大化脖苏。

mse_scores = -scores
rmse_scores = np.sqrt(mse_scores)
print(rmse_scores.mean())
# 10-fold cross-validation with two features (excluding Newspaper)
feature_cols = ['TV', 'radio']
X = data[feature_cols]
print(np.sqrt(-cross_val_score(lm, X, y, cv=10, scoring='neg_mean_squared_error')).mean())

結(jié)果分別是1.6913531708051797和1.6796748419090766
由于不加入Newspaper這一個特征得到的分數(shù)較小(1.68 < 1.69)定踱,所以棍潘,使用所有特征得到的模型是一個更好的模型。

參考
https://blog.csdn.net/jasonding1354/article/details/50562513
https://blog.csdn.net/cherdw/article/details/54986863
http://www.reibang.com/p/a4e94e72a46d

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市亦歉,隨后出現(xiàn)的幾起案子恤浪,更是在濱河造成了極大的恐慌,老刑警劉巖肴楷,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件水由,死亡現(xiàn)場離奇詭異,居然都是意外死亡赛蔫,警方通過查閱死者的電腦和手機砂客,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來呵恢,“玉大人鞠值,你說我怎么就攤上這事∩ぃ” “怎么了齿诉?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長晌姚。 經(jīng)常有香客問我,道長歇竟,這世上最難降的妖魔是什么挥唠? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮焕议,結(jié)果婚禮上宝磨,老公的妹妹穿的比我還像新娘。我一直安慰自己盅安,他們只是感情好唤锉,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著别瞭,像睡著了一般窿祥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蝙寨,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天晒衩,我揣著相機與錄音,去河邊找鬼墙歪。 笑死听系,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的虹菲。 我是一名探鬼主播靠胜,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了浪漠?” 一聲冷哼從身側(cè)響起陕习,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎郑藏,沒想到半個月后衡查,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡必盖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年拌牲,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片歌粥。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡塌忽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出失驶,到底是詐尸還是另有隱情土居,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布嬉探,位于F島的核電站擦耀,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏涩堤。R本人自食惡果不足惜眷蜓,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望胎围。 院中可真熱鬧吁系,春花似錦、人聲如沸白魂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽福荸。三九已至蕴坪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間逞姿,已是汗流浹背辞嗡。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留滞造,地道東北人续室。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像谒养,于是被迫代替她去往敵國和親挺狰。 傳聞我的和親對象是個殘疾皇子明郭,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容