KNN算法既可以解決分類問(wèn)題喜颁,也可以解決預(yù)測(cè)問(wèn)題。
基礎(chǔ)思想:通過(guò)計(jì)算每個(gè)訓(xùn)練樣例到待分類樣品的距離曹阔,取和待分類樣品距離最近的K個(gè)訓(xùn)練樣例半开,K個(gè)樣品中哪個(gè)類別的訓(xùn)練樣例占多數(shù),則待分類樣品就屬于哪個(gè)類別赃份。
對(duì)于離散型因變量寂拆,從k個(gè)最近的已知類別樣本中挑選出頻率最高的類別用于未知樣本的判斷;對(duì)于連續(xù)型因變量抓韩,將k個(gè)最近的已知樣本均值用作未知樣本的預(yù)測(cè)纠永。
k值過(guò)小,模型過(guò)擬合谒拴,例如k=1尝江,未知樣本的類別將由最近的1個(gè)已知樣本點(diǎn)來(lái)決定,對(duì)于訓(xùn)練數(shù)據(jù)來(lái)說(shuō)英上,訓(xùn)練誤差幾乎為0炭序,對(duì)于測(cè)試數(shù)據(jù)來(lái)說(shuō),訓(xùn)練誤差可能會(huì)很大苍日,因?yàn)榫嚯x最近的1個(gè)已知樣本點(diǎn)可以是異常觀測(cè)值惭聂,也可以是正常觀測(cè)值。
k值過(guò)大相恃,模型欠擬合辜纲,例如k=N,未知樣本的類別將由所有已知樣本中頻數(shù)最高的類別決定,不管是訓(xùn)練集還是測(cè)試集被判為一種類別侨歉,易欠擬合屋摇。
一般利用多重交叉驗(yàn)證得到平均誤差最小的k值揩魂。還有一種方法是設(shè)置k近鄰樣本的投票權(quán)重幽邓,對(duì)已知樣本距離較遠(yuǎn)的設(shè)置權(quán)重低一些,較近的設(shè)置權(quán)重高一些火脉,通常將權(quán)重設(shè)置為距離的倒數(shù)牵舵。
點(diǎn)與點(diǎn)之間的距離即相似性,一般用歐氏距離倦挂,即L2范數(shù)
或者曼哈頓距離畸颅,即L1范數(shù)
或者余弦相似度cosα
或者杰卡德相似系數(shù),即J=|A∩B|/|A∪B|
在使用距離方法來(lái)度量相似性時(shí)方援,要使所有變量數(shù)值化(通過(guò)啞變量或者重編碼為0,1,2)没炒,而且采用標(biāo)準(zhǔn)化方法進(jìn)行歸一化,防止數(shù)值變量的量綱影響
近鄰搜尋方法包括:暴力搜尋法(全表掃描)犯戏,kd樹(shù)(k為訓(xùn)練集中包含的變量個(gè)數(shù)送火,而非KNN中的k個(gè)鄰近樣本,先用所有已知類別的樣本點(diǎn)構(gòu)造一棵樹(shù)先匪,再將未知類別應(yīng)用在樹(shù)上)种吸,球樹(shù)搜尋(將kd樹(shù)中的超矩形體換成了超球體)。
優(yōu)點(diǎn):
精度高呀非,對(duì)異常值不敏感坚俗,無(wú)數(shù)據(jù)輸入假定;
KNN 是一種在線技術(shù)岸裙,新數(shù)據(jù)可以直接加入數(shù)據(jù)集而不必進(jìn)行重新訓(xùn)練猖败;
KNN 理論簡(jiǎn)單,容易實(shí)現(xiàn)降允。
缺點(diǎn):
對(duì)于樣本容量大的數(shù)據(jù)集計(jì)算量比較大恩闻,即計(jì)算復(fù)雜度高;
必須保存全部數(shù)據(jù)集拟糕,即空間復(fù)雜度高判呕;
KNN 每一次分類都會(huì)重新進(jìn)行一次全局運(yùn)算;
樣本不平衡時(shí)送滞,預(yù)測(cè)偏差比較大侠草。如:某一類的樣本比較少,而其它類樣本比較多犁嗅;
K 值大小的選擇边涕;
KNN 無(wú)法給出基礎(chǔ)結(jié)構(gòu)信息,無(wú)法知曉平均實(shí)例樣本與典型實(shí)例樣本具有什么特征,即無(wú)法給出數(shù)據(jù)的內(nèi)在含義功蜓。
應(yīng)用領(lǐng)域:
文本分類园爷;模式識(shí)別;聚類分析式撼;多分類領(lǐng)域童社。
# 導(dǎo)入第三方包
import pandas as pd
# 導(dǎo)入數(shù)據(jù)
Knowledge = pd.read_excel(r'F:\Knowledge.xlsx')
# 返回前5行數(shù)據(jù)
Knowledge.head()
行表示每一個(gè)被觀測(cè)的學(xué)生,
STG:在目標(biāo)學(xué)科上的學(xué)習(xí)時(shí)長(zhǎng)著隆,
SCG:重復(fù)次數(shù)
STR:相關(guān)科目的學(xué)習(xí)時(shí)長(zhǎng)
LPR:相關(guān)科目的考試成績(jī)
PEG:目標(biāo)科目的考試成績(jī)
(以上指標(biāo)均已標(biāo)準(zhǔn)化)
UNG:對(duì)知識(shí)的掌握程度高低
# 構(gòu)造訓(xùn)練集和測(cè)試集
# 導(dǎo)入第三方模塊
from sklearn import model_selection
# 將數(shù)據(jù)集拆分為訓(xùn)練集和測(cè)試集
predictors = Knowledge.columns[:-1]
X_train, X_test, y_train, y_test = model_selection.train_test_split(Knowledge[predictors], Knowledge.UNS,
test_size = 0.25, random_state = 1234)
利用多重交叉驗(yàn)證獲取符合數(shù)據(jù)的理想k值
Knowledge.shape[0]
import numpy as np
np.log2(Knowledge.shape[0])
np.ceil(np.log2(Knowledge.shape[0]))
# 導(dǎo)入第三方模塊
from sklearn import neighbors
import matplotlib.pyplot as plt
# 設(shè)置待測(cè)試的不同k值
K = np.arange(1,np.ceil(np.log2(Knowledge.shape[0])))
K
# 構(gòu)建空的列表扰楼,用于存儲(chǔ)平均準(zhǔn)確率
accuracy = []
for k in K:
# 使用10重交叉驗(yàn)證的方法,比對(duì)每一個(gè)k值下KNN模型的預(yù)測(cè)準(zhǔn)確率
cv_result = model_selection.cross_val_score(neighbors.KNeighborsClassifier(n_neighbors = int(k), weights = 'distance'),
X_train, y_train, cv = 10, scoring='accuracy')
accuracy.append(cv_result.mean())
accuracy
# 從k個(gè)平均準(zhǔn)確率中挑選出最大值所對(duì)應(yīng)的下標(biāo)
arg_max = np.array(accuracy).argmax()
arg_max
# 中文和負(fù)號(hào)的正常顯示
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False
# 繪制不同K值與平均預(yù)測(cè)準(zhǔn)確率之間的折線圖
plt.plot(K, accuracy)
# 添加點(diǎn)圖
plt.scatter(K, accuracy)
# 添加文字說(shuō)明
plt.text(K[arg_max], accuracy[arg_max], '最佳k值為%s' %int(K[arg_max]))
# 顯示圖形
plt.show()
經(jīng)過(guò)10重交叉驗(yàn)證美浦,最佳的近鄰個(gè)數(shù)為6
# 導(dǎo)入第三方模塊
from sklearn import metrics
# 重新構(gòu)建模型弦赖,并將最佳的近鄰個(gè)數(shù)設(shè)置為6
knn_class = neighbors.KNeighborsClassifier(n_neighbors = 6, weights = 'distance')
# 模型擬合
knn_class.fit(X_train, y_train)
# 模型在測(cè)試數(shù)據(jù)集上的預(yù)測(cè)
predict = knn_class.predict(X_test)
# 構(gòu)建混淆矩陣
cm = pd.crosstab(predict,y_test)
cm
weights=uniform,表示投票權(quán)重一樣
=distance浦辨,表示投票權(quán)重與距離成反比
從主對(duì)角線看蹬竖,絕大多數(shù)樣本被正確分類
通過(guò)熱力圖可視化混淆矩陣
# 導(dǎo)入第三方模塊
import seaborn as sns
# 將混淆矩陣構(gòu)造成數(shù)據(jù)框,并加上字段名和行名稱流酬,用于行或列的含義說(shuō)明
cm = pd.DataFrame(cm)
# 繪制熱力圖
sns.heatmap(cm, annot = True,cmap = 'GnBu')
# 添加x軸和y軸的標(biāo)簽
plt.xlabel(' Real Lable')
plt.ylabel(' Predict Lable')
# 圖形顯示
plt.show()
行代表真實(shí)地币厕,列代表預(yù)測(cè)的,主對(duì)角線上的顏色比較深康吵,說(shuō)明絕大多數(shù)樣本是被正確分類的劈榨。
下面得到模型在測(cè)試集上的預(yù)測(cè)準(zhǔn)確率:
# 模型整體的預(yù)測(cè)準(zhǔn)確率
metrics.scorer.accuracy_score(y_test, predict)
整體預(yù)測(cè)準(zhǔn)確率為91.09%,要得到每個(gè)類別的準(zhǔn)確率:
# 分類模型的評(píng)估報(bào)告
print(metrics.classification_report(y_test, predict))
第一列為預(yù)測(cè)精度晦嵌,即”預(yù)測(cè)正確的類別個(gè)數(shù)/該類別預(yù)測(cè)的所有個(gè)數(shù)"
第二列為預(yù)測(cè)覆蓋率同辣,即”預(yù)測(cè)正確的類別個(gè)數(shù)/該類別實(shí)際的所有個(gè)數(shù)"
第三列為前兩列的加權(quán)結(jié)果
第四列為類別實(shí)際的樣本個(gè)數(shù)
對(duì)于預(yù)測(cè)問(wèn)題的解決同決策樹(shù)中一樣,用MSE衡量