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