KNN交叉验证,找出合适的K值
在KNN里,通過交叉驗證,我們即可以得出最合適的K值。它的核心思想無非就是把一些可能的K逐個去嘗試一遍,然后選出效果最好的K值
交叉驗證的第一步是把訓練數(shù)據(jù)進一步分成訓練集和驗證集。
為什么這么做?
道理其實很簡單,因為我們需要一種評估的機制來選出最好的K值。那具體用什么數(shù)據(jù)來評估呢? 就是驗證集! 因為測試數(shù)據(jù)是用來一次性測試的。比如上線前來測試是否滿足上線的條件,但測試數(shù)據(jù)不能用于指導模型的訓練。
常用的交叉驗證技術(shù)叫做K折交叉驗證(K-fold Cross Validation)。 我們先把訓練數(shù)據(jù)再分成訓練集和驗證集,之后使用訓練集來訓練模型,然后再驗證集上評估模型的準確率。舉個例子,比如一個模型有個參數(shù)叫alphaα,我們一開始不清楚要選擇0.1還是1,所以這時候我們進行了交叉驗證:把所有訓練集分成K塊,依次對每一個alphaα值評估它的準確率。
一般情況下數(shù)據(jù)量較少的時候我們?nèi)〉腒值會更大,為什么呢?
因為數(shù)據(jù)量較少的時候如果每次留出比較多的驗證數(shù)據(jù),對于訓練模型本身來說是比較吃虧的,所以這時候我們盡可能使用更多的數(shù)據(jù)來訓練模型。由于每次選擇的驗證數(shù)據(jù)量較少,這時候K折中的K值也會隨之而增大,但到最后可以發(fā)現(xiàn),無論K值如何選擇,用來驗證的樣本個數(shù)都是等于總樣本個數(shù)。
最極端的情況下,我們可以采用leave_one_out交叉驗證,也就是每次只把一個樣本當做驗證數(shù)據(jù),剩下的其他數(shù)據(jù)都當做是訓練樣本。
從零寫交叉驗證
1.導入模塊
import numpy as np from sklearn import datasets from sklearn.neighbors import KNeighborsClassifier from sklearn.model_selection import KFold #主要用于K折交叉驗證
2.導入數(shù)據(jù)
# 導入iris數(shù)據(jù)集 iris=datasets.load_iris() X=iris.data y=iris.target print(X.shape,y.shape) # 定義我們想要搜索的K值(候選集),這里定義8個不同的值 ks=[1,3,5,7,9,11,13,15]
結(jié)果:
(150, 4) (150,)
3.應用
# 例:進行5折交叉驗證,KFold返回的是每一折中訓練數(shù)據(jù)和驗證數(shù)據(jù)的index
# 假設(shè)數(shù)據(jù)樣本為:[1,3,5,6,11,12,43,12,44,2],總共10個樣本
# 則返回的kf的格式為(前面的是訓練數(shù)據(jù),后面的是驗證數(shù)據(jù)):
# [0,1,3,5,6,7,8,9],[2,4]
# [0,1,2,4,6,7,8,9],[3,5]
# [1,2,3,4,5,6,7,8],[0,9]
# [0,1,2,3,4,5,7,9],[6,8]
# [0,2,3,4,5,6,8,9],[1,7]
kf =KFold(n_splits=5,random_state=2001,shuffle=True)
# 保存當前最好的K值和對應的準確值
best_k=ks[0]
best_score=0
# 循環(huán)每一個K值
for k in ks:
curr_score=0
for train_index,valid_index in kf.split(X):
#每一折的訓練以及計算準確率
clf=KNeighborsClassifier(n_neighbors=k)
clf.fit(X[train_index],y[train_index])
curr_score=curr_score+clf.score(X[valid_index],y[valid_index])
#求5折的平均準確率
avg_score=curr_score/5
if avg_score>best_score:
best_k=k
best_score=avg_score
print("現(xiàn)在的最佳準確率:%.2f"%best_score,"現(xiàn)在的最佳K值 %d"%best_k)
print("最終最佳準確率:%.2f"%best_score,"最終的最佳K值 %d"%best_k)
結(jié)果:
現(xiàn)在的最佳準確率:0.96 現(xiàn)在的最佳K值 1 現(xiàn)在的最佳準確率:0.96 現(xiàn)在的最佳K值 1 現(xiàn)在的最佳準確率:0.97 現(xiàn)在的最佳K值 5 現(xiàn)在的最佳準確率:0.98 現(xiàn)在的最佳K值 7 現(xiàn)在的最佳準確率:0.98 現(xiàn)在的最佳K值 7 現(xiàn)在的最佳準確率:0.98 現(xiàn)在的最佳K值 7 現(xiàn)在的最佳準確率:0.98 現(xiàn)在的最佳K值 7 現(xiàn)在的最佳準確率:0.98 現(xiàn)在的最佳K值 7 最終最佳準確率:0.98 最終的最佳K值 7
直接使用sklearn來實現(xiàn)同樣的邏輯,只需要調(diào)用即可以實現(xiàn)K折交叉驗證
from sklearn import datasets
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV #通過網(wǎng)絡(luò)方式來獲取參數(shù)
# 導入iris數(shù)據(jù)集
iris2=datasets.load_iris()
X2=iris2.data
y2=iris2.target
print(X2.shape,y2.shape)
# 設(shè)置需要搜索的K值,'n_neightbors'是sklearn中KNN的參數(shù)
parameters={'n_neightbors':[1,3,5,7,9,11,13,15]}
knn=KNeighborsClassifier()#注意:這里不用指定參數(shù)
# 通過GridSearchCV來搜索最好的K值。這個模塊的內(nèi)部其實就是對每一個K值進行評估
clf=GridSearchCV(knn,parameters,cv=5) #5折
clf.fit(X2,y2)
# 輸出最好的參數(shù)以及對應的準確率
print("最終最佳準確率:%.2f"%clf.best_score_,"最終的最佳K值",clf.best_params_)
總結(jié)
以上是生活随笔為你收集整理的KNN交叉验证,找出合适的K值的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何解决Ubuntu 12.04(64位
- 下一篇: linux系统设置允许密码登录