器學(xué)習(xí)入門】K 近鄰 (KNN) 算法超詳細(xì)教程 —— 從原理到 sklearn 雙案例教學(xué))
文章目錄前言一、KNN 算法核心原理1.1 算法思想1.2 關(guān)鍵要素1.3 算法步驟二、案例一個(gè)人性格配對(duì)效果預(yù)測(cè)2.1 數(shù)據(jù)集介紹2.2 數(shù)據(jù)可視化3D 散點(diǎn)圖2.3 KNN 建模與預(yù)測(cè)三、案例二鳶尾花分類識(shí)別3.1 數(shù)據(jù)集介紹3.2 數(shù)據(jù)預(yù)處理Z-Score 標(biāo)準(zhǔn)化3.3 完整代碼實(shí)現(xiàn)總結(jié)前言K 近鄰K-Nearest Neighbors簡(jiǎn)稱 KNN算法是機(jī)器學(xué)習(xí)中最經(jīng)典、最易理解的分類算法之一核心思想就是 “近朱者赤近墨者黑”—— 一個(gè)樣本的類別由它周圍最近的 K 個(gè)鄰居投票決定。本文從原理出發(fā)帶你用 Python scikit-learn 完整實(shí)現(xiàn)案例鳶尾花分類識(shí)別。一、KNN 算法核心原理1.1 算法思想KNN 屬于有監(jiān)督學(xué)習(xí)的分類算法邏輯非常直觀給定一個(gè)待預(yù)測(cè)的新樣本在訓(xùn)練集中找到與它距離最近的 K 個(gè)樣本這 K 個(gè)樣本中出現(xiàn)次數(shù)最多的類別就是新樣本的預(yù)測(cè)類別。1.2 關(guān)鍵要素K 值選擇K 太小容易受噪聲影響過(guò)擬合K 太大容易忽略樣本差異欠擬合通常通過(guò)交叉驗(yàn)證選擇最優(yōu) K 值。距離度量常用歐氏距離計(jì)算樣本間相似度公式如下d ( x , y ) ∑ i 1 n ( x i ? y i ) 2 d(x,y) \sqrt{\sum_{i1}^{n}(x_i - y_i)^2}d(x,y)i1∑n?(xi??yi?)2?特征標(biāo)準(zhǔn)化不同特征量綱差異大時(shí)必須先做標(biāo)準(zhǔn)化否則數(shù)值大的特征會(huì)主導(dǎo)距離計(jì)算。1.3 算法步驟計(jì)算待預(yù)測(cè)樣本與所有訓(xùn)練樣本的距離按距離從小到大排序選取距離最小的前 K 個(gè)樣本統(tǒng)計(jì) K 個(gè)樣本中各類別的出現(xiàn)次數(shù)出現(xiàn)次數(shù)最多的類別即為預(yù)測(cè)結(jié)果二、案例一個(gè)人性格配對(duì)效果預(yù)測(cè)2.1 數(shù)據(jù)集介紹使用數(shù)據(jù)集datingTestSet2.txt共 1000 條樣本包含 3 個(gè)特征和 1 個(gè)標(biāo)簽第 1 列 : 每年旅行里程數(shù)第 2 列 : 玩游戲所耗時(shí)間百分比第 3 列 : 每周零食消耗數(shù)量第 4 列標(biāo)簽人物類型 1 好、2 中、3 差2.2 數(shù)據(jù)可視化3D 散點(diǎn)圖先對(duì)數(shù)據(jù)做三維可視化直觀觀察三類人群的分布importmatplotlib.pyplotaspltimportnumpyasnp# 加載數(shù)據(jù)datanp.loadtxt(datingTestSet2.txt)data_1data[data[:,-1]1]adata[:,-1]bdata[a1]data_2data[data[:,-1]2]data_3data[data[:,-1]3]# 繪制3D散點(diǎn)圖figplt.figure()axplt.axes(projection3d)ax.scatter(data_1[:,0],data_1[:,1],zsdata_1[:,2],c#00DDAA,markero)ax.scatter(data_2[:,0],data_2[:,1],zsdata_2[:,2],c#FF5511,marker^)ax.scatter(data_3[:,0],data_3[:,1],zsdata_3[:,2],c#000011,marker)ax.set(xlabelXaxes,ylabelYaxes,zlabelZaxes)plt.show()從圖中可以清晰看到三類人群在特征空間中呈現(xiàn)明顯的聚類分布非常適合用 KNN 做分類。2.3 KNN 建模與預(yù)測(cè)使用 scikit-learn 的KNeighborsClassifier快速搭建模型importnumpyasnpfromsklearn.neighborsimportKNeighborsClassifier# 加載數(shù)據(jù)datanp.loadtxt(datingTestSet2.txt)Xdata[:,:-1]# 特征前三列ydata[:,-1]# 標(biāo)簽最后一列# 創(chuàng)建KNN模型K25knnKNeighborsClassifier(n_neighbors25)knn.fit(X,y)# 單樣本預(yù)測(cè)resultknn.predict([[14459,4.458902,0.268444]])print(單樣本預(yù)測(cè)類別,result)# 批量預(yù)測(cè)predict_datas[[14254,5.946014,1.614244],[22220,5.297865,0.638306],[0,5.757140,1.062373],[16721,0.000000,0.242778]]print(批量預(yù)測(cè)結(jié)果,knn.predict(predict_datas))三、案例二鳶尾花分類識(shí)別3.1 數(shù)據(jù)集介紹使用鳶尾花數(shù)據(jù)集包含花的四個(gè)形態(tài)特征和對(duì)應(yīng)的類別標(biāo)簽萼片長(zhǎng) (cm) 花萼的長(zhǎng)度萼片寬 (cm) 花萼的寬度花瓣長(zhǎng) (cm) 花瓣的長(zhǎng)度花瓣寬 (cm) 花瓣的寬度類型_num 類別標(biāo)簽0 / 1 二分類訓(xùn)練集66 條樣本測(cè)試集9 條樣本3.2 數(shù)據(jù)預(yù)處理Z-Score 標(biāo)準(zhǔn)化由于四個(gè)特征的數(shù)值范圍不同需要先做標(biāo)準(zhǔn)化處理讓每個(gè)特征均值為 0、方差為 1避免數(shù)值大的特征主導(dǎo)距離計(jì)算。Z-Score 標(biāo)準(zhǔn)化公式x ′ x ? μ σ x \frac{x - \mu}{\sigma}x′σx?μ?其中μ \muμ是均值σ \sigmaσ是標(biāo)準(zhǔn)差。3.3 完整代碼實(shí)現(xiàn)importpandasaspd# 1. 加載數(shù)據(jù) train_datapd.read_excel(鳶尾花訓(xùn)練數(shù)據(jù).xlsx)test_datapd.read_excel(鳶尾花測(cè)試數(shù)據(jù).xlsx)train_Xtrain_data[[萼片長(zhǎng)(cm),萼片寬(cm),花瓣長(zhǎng)(cm),花瓣寬(cm)]]train_ytrain_data[類型_num]# 2. Z-Score標(biāo)準(zhǔn)化 fromsklearn.preprocessingimportscale datapd.DataFrame()data[萼片長(zhǎng)標(biāo)準(zhǔn)化]scale(train_X[萼片長(zhǎng)(cm)])data[萼片寬標(biāo)準(zhǔn)化]scale(train_X[萼片寬(cm)])data[花瓣長(zhǎng)標(biāo)準(zhǔn)化]scale(train_X[花瓣長(zhǎng)(cm)])data[花瓣寬標(biāo)準(zhǔn)化]scale(train_X[花瓣寬(cm)])test_Xtest_data[[萼片長(zhǎng)(cm),萼片寬(cm),花瓣長(zhǎng)(cm),花瓣寬(cm)]]test_ytest_data[類型_num]data_testpd.DataFrame()data_test[萼片長(zhǎng)標(biāo)準(zhǔn)化]scale(test_X[萼片長(zhǎng)(cm)])data_test[萼片寬標(biāo)準(zhǔn)化]scale(test_X[萼片寬(cm)])data_test[花瓣長(zhǎng)標(biāo)準(zhǔn)化]scale(test_X[花瓣長(zhǎng)(cm)])data_test[花瓣寬標(biāo)準(zhǔn)化]scale(test_X[花瓣寬(cm)])# 3. 構(gòu)建KNN模型 fromsklearn.neighborsimportKNeighborsClassifier knnKNeighborsClassifier(n_neighbors3)knn.fit(data,train_y)train_predictedknn.predict(data)score_trainknn.score(data,train_y)# 4. 模型評(píng)估 test_predictedknn.predict(data_test)score_testknn.score(data_test,test_y)print(score_test)# 0.8888888888888888代碼說(shuō)明數(shù)據(jù)加載用pandas.read_excel()讀取 Excel 訓(xùn)練集和測(cè)試集特征提取選取四個(gè)花的形態(tài)特征作為輸入類型標(biāo)簽作為輸出標(biāo)準(zhǔn)化使用sklearn.preprocessing.scale()做 Z-Score 標(biāo)準(zhǔn)化模型訓(xùn)練KNeighborsClassifier(n_neighbors3)創(chuàng)建 K3 的 KNN 分類器模型評(píng)估score()方法直接計(jì)算準(zhǔn)確率對(duì)比訓(xùn)練集和測(cè)試集效果總結(jié)KNN 核心是 “近朱者赤”通過(guò) K 個(gè)最近鄰居投票決定類別距離計(jì)算 K 值選擇 特征標(biāo)準(zhǔn)化 是 KNN 的三大關(guān)鍵特征量綱差異大時(shí)標(biāo)準(zhǔn)化是必不可少的預(yù)處理步驟scikit-learn 的KNeighborsClassifier可以快速搭建 KNN 模型KNN 適合小數(shù)據(jù)集、低維特征的分類場(chǎng)景大數(shù)據(jù)集下效率較低