机器学习:k近邻算法(KNN)介绍
k近鄰算法是一種最簡單最經典的機器學習算法之一。該算法的原理為:當對測試樣本進行分類時,首先通過掃描訓練樣本集,找到與該測試樣本最相似的k個訓練樣本,根據這個樣本的類別進行投票確定測試樣本的類別。也可以通過個樣本與測試樣本的相似程度進行加權投票。如果需要以測試樣本對應每類的概率的形式輸出,可以通過個樣本中不同類別的樣本數量分布來進行估計。
以下通過一個例子了解k近鄰算法。
?利用k近鄰算法確認紫圓為哪個類別。若k=1,則找到離圖中紫圓最近的1個樣本,這個樣本為紅色正方形,故紫圓屬于紅色正方形類別;若k=7,則找到離紫圓最近的7個樣本,這7個樣本中有5個綠色三角形和兩個紅色正方形,其中類數三角形數量比紅色正方形多,故紫圓屬于綠色三角形。由以上例子可知k近鄰算法對樣本的分類及其依賴于k的取值。
?當然k近鄰算法對距離的計算方式有多種,其中以Manhattan 距離與Euclidean 距離為主。
我們一般采用Euclidean 距離。
?
在上述介紹中我們得知k近鄰算法對樣本的分類及其依賴于k的取值。k值不可取過大或過小。
- k值越大,模型的偏差越大,對噪聲數據越不敏感,當k值很大時,可能造成欠擬合;
- k值越小,模型的方差就會越大,當k值太小,就會造成過擬合。?
以下為k值取值過大或過小時的例子。
?如圖當k=1時在圖中紫色圖層中夾雜了參差不齊的綠色圖層,該訓練結果并非很好的劃分了紅綠紫三個區(qū)域,造成了過擬合現(xiàn)象。
如圖當k=150時由于無論取圖上哪個點都是紫色點投票最多,故該點必被分類為紫色一類,造成了欠擬合現(xiàn)象。
因此k的取值因滿足以下兩個條件:
1.近鄰點要有相同/相近的類別
2.特征維度的尺度(范圍)要具備一致性
接下來看一例子:
?如上圖,若我們用傳統(tǒng)的Euclidean 距離作為k近鄰算法判斷距離的標準,我們會驚訝的發(fā)現(xiàn)每年獲得的飛行常客里程數將占到距離的絕大部分比重,也就是說樣本的分類基本上只與每年獲得的飛行常客里程數相關聯(lián)了。所以我們要進行數值歸一化的處理,使得上圖中三個特征的權重相等。
數據歸一化的處理方法有很多種,比如0-1標準化、Z-score標準化、Sigmoid壓縮法等等,在這里我們使用最簡單的0-1標準化,公式如下:?
?
?接下來調用鳶尾花Iris數據集,利用k近鄰算法訓練該數據集并評估模型準確率。
1.鳶尾花Iris數據集介紹
· Iris (/?a?r?s/) 數據集是機器學習任務中常用的分類實驗數據集,由Fisher在1936年整理。
· Iris :Anderson’s Iris data set, 中文名稱:安德森鳶尾花數據集
· Iris 數據集一共包含150個樣本,分3類,每類50個數據,每個數據包含4個特征。4個特征分別為: Sepal.Length(花萼長度)、Sepal.Width(花萼寬度)、Petal.Length(花瓣長度)、Petal.Width(花瓣寬度),特征值都為正浮點數,單位為厘米。根據4個特征預測鳶尾花屬于 Iris Setosa(山鳶尾)、Iris Versicolour(雜色鳶尾),Iris Virginica(維吉尼亞鳶尾)
數據集結構與數據大致如下:
?
?其中前部分為特征: Sepal.Length(花萼長度)、Sepal.Width(花萼寬度)、Petal.Length(花瓣長度)、Petal.Width(花瓣寬度)后部分為標簽:Iris Setosa(山鳶尾)、Iris Versicolour(雜色鳶尾),Iris Virginica(維吉尼亞鳶尾)(分別利用0,1,2代替原有標簽名)。
2.sklearn中 neighbors.KNeighborsClassifier參數說明
在sklearn庫中,KNeighborsClassifier是實現(xiàn)K近鄰算法的一個類,一般都使用歐式距離進行測量。
KNeighborsClassifier(n_neighbors=5,weights=’uniform’,algorithm=’auto’,leaf_size=30,p=2,metric=’minkowski’,metric_params=None,n_jobs=1,**kwargs)
n_neighbors: int, 可選參數(默認為 5)用于kneighbors查詢的默認鄰居的數量;
weights(權重): str or callable(自定義類型), 可選參數(默認為 ‘uniform’)用于預測的權重函數;
algorithm(算法): {‘auto’, ‘ball_tree’, ‘kd_tree’, ‘brute’}, 可選參數(默認為 ‘auto’)計算最近鄰居用的算法;
leaf_size(葉子數量): int, 可選參數(默認為 30),傳入BallTree或者KDTree算法的葉子數量;
p: integer, 可選參數(默認為 2)用于Minkowski metric(閔可夫斯基空間)的超參數。p = 1, 相當于使用曼哈頓距離 (l1),p = 2, 相當于使用歐幾里得距離(l2);
metric(矩陣): string or callable, 默認為 ‘minkowski’用于樹的距離矩陣。默認為閔可夫斯基空間,如果和p=2一塊使用相當于使用標準歐幾里得矩陣;
metric_params(矩陣參數): dict, 可選參數(默認為 None),給矩陣方法使用的其他的關鍵詞參數;
n_jobs: int, 可選參數(默認為 1)用于搜索鄰居的,可并行運行的任務數量。如果為-1, 任務數量設置為CPU核的數量。不會影響fit方法.
- 方法:
?
3.?編寫代碼,實現(xiàn)對iris數據集的k近鄰算法分類及預測
一:引入庫
from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifier import numpy as np二:加載數據集,定義區(qū)分特征與標記
iris = load_iris() #date為特征數據集 data = iris.get("data") #target為標記數據集 target = iris.get("target")三:劃分測試集與訓練集
#劃分測試集占20% x_train, x_test, y_train, y_test = train_test_split(data, target, test_size=0.2, random_state=0)四:定義k值
#定義k值 KNN = KNeighborsClassifier(n_neighbors=5)五:評價模型的準確率
test_score = KNN.score(x_test, y_test) print("模型的準確率:", test_score)
六:使用模型預測未知種類樣本
#定義三個測試數據
X1 = np.array([[1.9, 2.8, 4.7, 1.1], [5.8, 2.7, 4.1, 1.5], [3.6, 2.5, 3.1, 2.1]])
prediction = KNN.predict(X1)
#根據預測值找出對應花名
a = iris.get("target_names")[prediction]
print("第一朵花的種類為:", a[0])
print("第二朵花的種類為:", a[1])
print("第三朵花的種類為:", a[2])
?完整代碼
from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifier import numpy as np if __name__ == '__main__':iris = load_iris()#date為特征數據集data = iris.get("data")#target為標記數據集target = iris.get("target")#劃分測試集占20%x_train, x_test, y_train, y_test = train_test_split(data, target, test_size=0.2, random_state=0)#定義k值KNN = KNeighborsClassifier(n_neighbors=5)KNN.fit(x_train, y_train)train_score = KNN.score(x_train, y_train)test_score = KNN.score(x_test, y_test)print("模型的準確率:", test_score)#定義三個測試數據X1 = np.array([[1.9, 2.8, 4.7, 1.1], [5.8, 2.7, 4.1, 1.5], [3.6, 2.5, 3.1, 2.1]])prediction = KNN.predict(X1)#根據預測值找出對應花名a = iris.get("target_names")[prediction]print("第一朵花的種類為:", a[0])print("第二朵花的種類為:", a[1])print("第三朵花的種類為:", a[2])結果
?接下來改變k值觀察模型準確率。
當k=100時:
當 k=50時:
當k=120時:
?
可以看出當k值越來越高至接近樣本總數150時它的準確率越來越低,這吻合了上文介紹的k值過大造成的欠擬合現(xiàn)象。?
?k近鄰算法優(yōu)缺點
優(yōu)點:
1.?簡單有效
2.重新訓練的代價低(沒有構建模型)
3.適合類域交叉樣本:KNN方法主要靠周圍有限的鄰近的樣本,而不是靠判別類域的方法來確定所屬類別的,因此對于類域的交叉或重疊較多的待分樣本集來說,KNN方法較其他方法更為適合。
4.適合大樣本自動分類:該算法比較適用于樣本容量比較大的類域的自動分類,而那些樣本容量較小的類域采用這種算法比較容易產生誤分。
?
缺點:
1.惰性學習:KNN算法是懶散學習方法(lazy learning,基本上不學習),一些積極學習的算法要快很多
2.類別評分不是規(guī)格化:不像一些通過概率評分的分類
3.輸出可解釋性不強:例如決策樹的輸出可解釋性就較強
4.對不均衡的樣本不擅長:當樣本不平衡時,如一個類的樣本容量很大,而其他類樣本容量很小時,有可能導致當輸入一個新樣本時,該樣本的K個鄰居中大容量類的樣本占多數。該算法只計算“最近的”鄰居樣本,某一類的樣本數量很大,那么或者這類樣本并不接近目標樣本,或者這類樣本很靠近目標樣本。無論怎樣,數量并不能影響運行結果。可以采用權值的方法(和該樣本距離小的鄰居權值大)來改進。
5.計算量較大:目前常用的解決方法是事先對已知樣本點進行剪輯,事先去除對分類作用不大的樣本。
總結
以上是生活随笔為你收集整理的机器学习:k近邻算法(KNN)介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux != Windows( Li
- 下一篇: BUUCTF Misc 隐藏的钥匙