01. KNN 算法詳解

     

       

       kNN算法的核心思想是如果一個樣本在特徵空間中的k個最相鄰的樣本中的大多數屬於某一個類別,則該樣本也屬於這個類別,並具有這個類別上樣本的特性。該方法在確定分類決策上只依據最鄰近的一個或者幾個樣本的類別來決定待分樣本所屬的類別。 kNN方法在類別決策時,只與極少量的相鄰樣本有關。由於kNN方法主要靠周圍有限的鄰近的樣本,而不是靠判別類域的方法來確定所屬類別的,因此對於類域的交叉或重疊較多的待分樣本集來說,kNN方法較其他方法更爲適合

       

1、k-近鄰法簡介

       k近鄰法(k-nearest neighbor, k-NN)是1967年由Cover T和Hart P提出的一種基本分類與迴歸方法。它的工作原理是:存在一個樣本數據集合,也稱作爲訓練樣本集,並且樣本集中每個數據都存在標籤,即我們知道樣本集中每一個數據與所屬分類的對應關係。輸入沒有標籤的新數據後,將新的數據的每個特徵與樣本集中數據對應的特徵進行比較,然後算法提取樣本最相似數據(最近鄰)的分類標籤。一般來說,我們只選擇樣本數據集中前k個最相似的數據,這就是k-近鄰算法中k的出處,通常k是不大於20的整數。最後,選擇k個最相似數據中出現次數最多的分類,作爲新數據的分類。

 

2、距離度量

            距離的定義是一個寬泛的概念:只要滿足非負、自反、三角不等式就可以稱之爲距離。其中非負是指任意兩個相異點的         距離爲正;自反是Dis(y,x)=Dis(x,y);三角不等式是Dis(x,z)<=Dis(x,y)+Dis(y,z)

      1) 馬氏距離(閔可夫斯基距離)

                   其中d是維數,p是階數,也稱爲p範數。
                   當p=1時,是曼哈頓距離
                   當p=2時,是歐氏距離
                   當p→∞時,是切比雪夫距離
                   當p=0時,是海明距離

      2) 歐氏距離

              兩點間的直線距離(一般用兩條豎線||w||代表w的2範數)代入公式:

      3) 曼哈頓距離(城市街區距離)

              各座標數值差的和,就像汽車只能行駛在橫平豎直的街道上,代入公式:

      4) 切比雪夫距離

            各座標數值差的最大值,當馬氏距離的p→∞時,最終的結果取決於距離最大的維度上的距離:
                                   Dis∞=maxj|xj-yj|
            在二維的情況下:c=max(a,b)

       5) 海明距離

                L0範數並不是一個真正的範數,它主要被用來度量向量中非零元素的個數。

      6) 總結

                   圖片從上到下依次顯示a與b點的三種距離:歐氏距離(藍色),切比雪夫距離(紅色),曼哈頓距離(綠色)

 

3、k-近鄰法算法思想

      算法步驟如下:

  1. 計算已知類別數據集中的點與當前點之間的距離;
  2. 按照距離遞增次序排序;
  3. 選取與當前點距離最小的k個點;
  4. 確定前k個點所在類別的出現頻率;
  5. 返回前k個點所出現頻率最高的類別作爲當前點的預測分類。

 

4、k-近鄰法算法實戰

      

import matplotlib.pyplot as plt  
import numpy as np  
from sklearn.cluster import KMeans
from sklearn import datasets 
 
iris = datasets.load_iris() 
X = iris.data[:, :4]   #表示我們取特徵空間中的4個維度
print(X.shape)
 
# 繪製數據分佈圖
plt.scatter(X[:, 0], X[:, 1], c="red", marker='o', label='see')  
plt.xlabel('petal length')  
plt.ylabel('petal width')  
plt.legend(loc=2)  
plt.show()  
 
estimator = KMeans(n_clusters=3)  # 構造聚類器
estimator.fit(X)  # 聚類
label_pred = estimator.labels_  # 獲取聚類標籤

# 繪製k-means結果
x0 = X[label_pred == 0]
x1 = X[label_pred == 1]
x2 = X[label_pred == 2]
plt.scatter(x0[:, 0], x0[:, 1], c="red", marker='o', label='label0')  
plt.scatter(x1[:, 0], x1[:, 1], c="green", marker='*', label='label1')  
plt.scatter(x2[:, 0], x2[:, 1], c="blue", marker='+', label='label2')  
plt.xlabel('petal length')  
plt.ylabel('petal width')  
plt.legend(loc=2)  
plt.show()

 

5、k-近鄰法算法優缺點分析

   優點:

  • 簡單好用,容易理解,精度高,理論成熟,既可以用來做分類也可以用來做迴歸;
  • 可用於數值型數據和離散型數據;
  • 訓練時間複雜度爲O(n);無數據輸入假定;
  • 對異常值不敏感

   缺點

  • 計算複雜性高;空間複雜性高;
  • 樣本不平衡問題(即有些類別的樣本數量很多,而其它樣本的數量很少);
  • 一般數值很大的時候不用這個,計算量太大。但是單個樣本又不能太少,否則容易發生誤分。
  • 最大的缺點是無法給出數據的內在含義

 

6、k-means處理過程

     k-近鄰算法的一般流程:

  1. 收集數據:可以使用爬蟲進行數據的收集,也可以使用第三方提供的免費或收費的數據。一般來講,數據放在txt文本文件中,按照一定的格式進行存儲,便於解析及處理。
  2. 準備數據:使用Python解析、預處理數據。
  3. 分析數據:可以使用很多方法對數據進行分析,例如使用Matplotlib將數據可視化。
  4. 測試算法:計算錯誤率。
  5. 使用算法:錯誤率在可接受範圍內,就可以運行k-近鄰算法進行分類。

 

7、k-means 和 KNN

       初學者很容易把K-Means和KNN搞混,兩者其實差別還是很大的。

  K-Means是無監督學習的聚類算法,沒有樣本輸出;而KNN是監督學習的分類算法,有對應的類別輸出。KNN基本不需要訓練,對測試集裏面的點,只需要找到在訓練集中最近的k個點,用這最近的k個點的類別來決定測試點的類別。而K-Means則有明顯的訓練過程,找到k個類別的最佳質心,從而決定樣本的簇類別。

  當然,兩者也有一些相似點,兩個算法都包含一個過程,即找出和某一個點最近的點。兩者都利用了最近鄰(nearest neighbors)的思想

 

引用:

https://en.wikipedia.org/wiki/K-means_clustering

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章