KNN分類(lèi)算法
分類(lèi):將一個(gè)未知?dú)w類(lèi)的樣本歸屬到某一個(gè)已知的類(lèi)群中。
預(yù)測(cè):可以根據(jù)數(shù)據(jù)的規(guī)律計(jì)算出一個(gè)未知的數(shù)據(jù)旗芬。
概念:
??簡(jiǎn)單地說(shuō),K-近鄰算法采用測(cè)量不同特征值之間的距離方法進(jìn)行分類(lèi)(k-Nearest Neighbor,KNN)弯菊。
工作原理:
??設(shè)有一個(gè)集合,已知集合的數(shù)據(jù)及其所對(duì)應(yīng)的標(biāo)簽踱阿,輸入新的無(wú)標(biāo)簽數(shù)據(jù)管钳,將其與已知集合的數(shù)據(jù)特征進(jìn)行比較,選出最接近的K個(gè)數(shù)據(jù)特征的標(biāo)簽软舌,出現(xiàn)次數(shù)最多的標(biāo)簽即為無(wú)標(biāo)簽數(shù)據(jù)的標(biāo)簽才漆。
例子:
# 加載模塊
from sklearn.neighbors import KNeighborsClassifier
import sklearn.datasets as datasets
from sklearn.model_selection import train_test_split
# 加載數(shù)據(jù)
iris = datasets.load_iris()
# 取得特征
feature = iris.data
# 取得標(biāo)簽
target = iris.target
# 拆分出訓(xùn)練集的特征與標(biāo)簽和測(cè)試集的特征與標(biāo)簽
x_train,x_test,y_train,y_test = train_test_split(feature,target,test_size=0.2,random_state=2020)
# 將模型實(shí)例化
knn = KNeighborsClassifier(n_neighbors=9)
# 訓(xùn)練模型;特征形狀的維度必須為二維
knn.fit(x_train,y_train)
# 打印測(cè)試集的實(shí)際標(biāo)簽和預(yù)測(cè)標(biāo)簽
print('真實(shí)的分類(lèi)結(jié)果:',y_test)
print('模型分類(lèi)的結(jié)果:',knn.predict(x_test))
真實(shí)的分類(lèi)結(jié)果: [2 0 1 1 1 2 2 1 0 0 2 2 0 2 2 0 1 1 2 0 0 2 1 0 2 1 1 1 0 0]
模型分類(lèi)的結(jié)果: [2 0 1 1 1 2 2 1 0 0 2 1 0 2 2 0 1 1 2 0 0 2 2 0 2 1 1 1 0 0]
# 對(duì)模型的精度進(jìn)行打分
knn.score(x_test,y_test)
0.9333333333333333
模型的超參數(shù):
??如果算法模型類(lèi)的參數(shù)如果發(fā)生數(shù)值的變化佛点,直接會(huì)影響模型的精度栽烂,則該參數(shù)就叫做模型的超參數(shù)。
學(xué)習(xí)曲線(xiàn)尋找最優(yōu)的k值
??窮舉不同的k值
import numpy as np
ks = [] #保存模型使用過(guò)的k值
scores = [] #保存模型對(duì)應(yīng)k值的分值
for k in range(2,50,2):
knn = KNeighborsClassifier(n_neighbors=k).fit(x_train,y_train)
score = knn.score(x_test,y_test)
ks.append(k)
scores.append(score)
arr_ks = np.array(ks)
arr_scores = np.array(scores)
arr_ks,arr_scores
(array([ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34,
36, 38, 40, 42, 44, 46, 48]),
array([0.93 , 0.945, 0.945, 0.95 , 0.95 , 0.95 , 0.955, 0.96 , 0.955,
0.955, 0.955, 0.95 , 0.955, 0.955, 0.95 , 0.955, 0.955, 0.955,
0.96 , 0.955, 0.955, 0.955, 0.96 , 0.96 ]))
np.argmax(arr_scores) #找出arr_scores數(shù)組中最大值對(duì)應(yīng)的下標(biāo)
arr_ks[np.argmax(arr_scores)]#找出最優(yōu)的模型參數(shù)的值
k的取值問(wèn)題:學(xué)習(xí)曲線(xiàn)與交叉驗(yàn)證選取K值
??①K值較小恋脚,則模型復(fù)雜度較高腺办,容易發(fā)生過(guò)擬合,學(xué)習(xí)的估計(jì)誤差會(huì)增大糟描,預(yù)測(cè)結(jié)果對(duì)近鄰的實(shí)例點(diǎn)非常敏感怀喉。
??②K值較大可以減少學(xué)習(xí)的估計(jì)誤差,但是學(xué)習(xí)的近似誤差會(huì)增大船响,與輸入實(shí)例較遠(yuǎn)的訓(xùn)練實(shí)例也會(huì)對(duì)預(yù)測(cè)起作用躬拢,使預(yù)測(cè)發(fā)生錯(cuò)誤,k值增大模型的復(fù)雜度會(huì)下降见间。
??③在應(yīng)用中聊闯,k值一般取一個(gè)比較小的值,通常采用交叉驗(yàn)證法來(lái)來(lái)選取最優(yōu)的K值米诉。
K值的交叉驗(yàn)證
目的:
??選出最為適合的模型超參數(shù)的取值菱蔬,然后將超參數(shù)的值作用到模型的創(chuàng)建中。
思想:
??將樣本的訓(xùn)練數(shù)據(jù)交叉的拆分出不同的訓(xùn)練集和驗(yàn)證集史侣,使用交叉拆分出不同的訓(xùn)練集和驗(yàn)證集測(cè)分別試模型的精準(zhǔn)度拴泌,然后求出的精準(zhǔn)度的均值就是此次交叉驗(yàn)證的結(jié)果。將交叉驗(yàn)證作用到不同的超參數(shù)中惊橱,選取出精準(zhǔn)度最高的超參數(shù)作為模型創(chuàng)建的超參數(shù)即可蚪腐。
實(shí)現(xiàn)思路:
??①將訓(xùn)練數(shù)據(jù)平均分割成K個(gè)等份
??②使用1份數(shù)據(jù)作為驗(yàn)證數(shù)據(jù),其余作為訓(xùn)練數(shù)據(jù)
??③計(jì)算驗(yàn)證準(zhǔn)確率
??④使用不同的測(cè)試集税朴,重復(fù)2回季、3步驟家制,直到所有等份都作為過(guò)訓(xùn)練數(shù)據(jù)
??⑤對(duì)準(zhǔn)確率做平均,作為對(duì)未知數(shù)據(jù)預(yù)測(cè)準(zhǔn)確率的估計(jì)
ks = []
scores = []
for k in range(2,50):
knn = KNeighborsClassifier(n_neighbors=k)
score = cross_val_score(knn,x_train,y_train,cv=5).mean() # cv表示五等分
ks.append(k)
scores.append(score)
arr_ks = np.array(ks)
arr_scores = np.array(scores)
與未使用交叉驗(yàn)證的學(xué)習(xí)曲線(xiàn)的代碼的區(qū)別為
knn = KNeighborsClassifier(n_neighbors=k)
和score = cross_val_score(knn,x_train,y_train,cv=5).mean()
泡一。因?yàn)閒it函數(shù)會(huì)使模型完全符合訓(xùn)練數(shù)據(jù)慰丛,所以交叉驗(yàn)證并未使用fit函數(shù)。
交叉驗(yàn)證的cross_val_score
函數(shù)(cv=5)相當(dāng)于進(jìn)行了5次用4/5的訓(xùn)練集數(shù)據(jù)進(jìn)行訓(xùn)練瘾杭,1/5的數(shù)據(jù)進(jìn)行測(cè)試诅病,最后給出5個(gè)精度。