KNN算法介紹


KNN算法全名為k-Nearest Neighbor,就是K最近鄰的意思。

算法描述

KNN是一種分類算法,其基本思想是采用測量不同特征值之間的距離方法進行分類。

算法過程如下:

1、准備樣本數據集(樣本中每個數據都已經分好類,並具有分類標簽);
2、使用樣本數據進行訓練;
3、輸入測試數據A;
4、計算A與樣本集的每一個數據之間的距離;
5、按照距離遞增次序排序;
6、選取與A距離最小的k個點;
7、計算前k個點所在類別的出現頻率;
8、返回前k個點出現頻率最高的類別作為A的預測分類。

主要因素

訓練集(或樣本數據)

訓練集太小會誤判,訓練集太大時對測試數據分類的系統開銷會非常大。

距離(或相似的衡量算法)

什么是合適的距離衡量?距離越近應該意味着這兩個點屬於一個分類的可能性越大。

距離衡量包括:

1、歐氏距離

歐幾里得度量(euclidean metric)(也稱歐氏距離)是一個通常采用的距離定義,指在m維空間中兩個點之間的真實距離,或者向量的自然長度(即該點到原點的距離)。在二維和三維空間中的歐氏距離就是兩點之間的實際距離。

適用於空間問題。

2、曼哈頓距離

出租車幾何或曼哈頓距離(Manhattan Distance)是由十九世紀的赫爾曼·閔可夫斯基所創詞匯 ,是種使用在幾何度量空間的幾何學用語,用以標明兩個點在標准坐標系上的絕對軸距總和。 曼哈頓距離是歐氏距離在歐幾里得空間的固定直角坐標系上所形成的線段對軸產生的投影的距離總和。

圖中紅線代表曼哈頓距離,綠色代表歐氏距離,也就是直線距離,而藍色和黃色代表等價的曼哈頓距離。 曼哈頓距離——兩點在南北方向上的距離加上在東西方向上的距離,即d(i,j)=|xi-xj|+|yi-yj|。

適用於路徑問題。

3、切比雪夫距離

在數學中,切比雪夫距離是向量空間中的一種度量,二個點之間的距離定義是其各坐標數值差絕對值的最大值。

切比雪夫距離會用在計算法網格中兩點之間的距離,比如:棋盤、倉儲物流等應用。

對一個網格,和一個點的切比雪夫距離為1的點為此點的Moore型鄰居(英語:Moore neighborhood)。

使用於在網格中計算距離的問題。

4、閔可夫斯基距離(Minkowski Distance)

閔氏距離不是一種距離,而是一組距離的定義。

根據變參數的不同,閔氏距離可以表示一類的距離。

其公式中有一個變參p:
當p=1時,是曼哈頓距離;
當p=2時,是歐氏距離;
當p→∞時,就是切比雪夫距離。

5、標准化歐氏距離 (Standardized Euclidean distance )

標准化歐氏距離是針對簡單歐氏距離的缺點而作的一種改進方案,可以看成是一種加權歐氏距離。

標准歐氏距離的思路: 既然數據各維分量的分布不一樣,那先將各個分量都“標准化”到均值、方差相等。

6、馬氏距離(Mahalanobis Distance)

表示數據的協方差距離。

它是一種有效的計算兩個未知樣本集的相似度的方法。

量綱無關,可以排除變量之間的相關性的干擾。

7、巴氏距離(Bhattacharyya Distance) 在統計學中,巴氏距離用於測量兩離散概率分布。它常在分類中測量類之間的可分離性。

8、漢明距離(Hamming distance)

兩個等長字符串s1與s2之間的漢明距離定義為將其中一個變為另外一個所需要作的最小替換次數。

例如字符串“1111”與“1001”之間的漢明距離為2。

應用:
信息編碼(為了增強容錯性,應使得編碼間的最小漢明距離盡可能大)。

9、夾角余弦(Cosine)

幾何中夾角余弦可用來衡量兩個向量方向的差異,數據挖掘中可用來衡量樣本向量之間的差異。

10、傑卡德相似系數(Jaccard similarity coefficient)

傑卡德距離用兩個集合中不同元素占所有元素的比例來衡量兩個集合的區分度。
可將傑卡德相似系數用在衡量樣本的相似度上。

11、皮爾森相關系數(Pearson Correlation Coefficient)

皮爾森相關系數,也稱皮爾森積矩相關系數(Pearson product-moment correlation coefficient) ,是一種線性相關系數。 皮爾森相關系數是用來反映兩個變量線性相關程度的統計量。

高維度對距離衡量的影響:
當變量數越多,歐式距離的區分能力就越差。

變量值域對距離的影響:
值域越大的變量常常會在距離計算中占據主導作用,因此應先對變量進行標准化。

k的大小

k太小,分類結果易受噪聲點影響,誤差會增大;
k太大,近鄰中又可能包含太多的其它類別的點(對距離加權,可以降低k值設定的影響);
k=N(樣本數),則完全不足取,因為此時無論輸入實例是什么,都只是簡單的預測它屬於在訓練實例中最多的類,模型過於簡單,忽略了訓練實例中大量有用信息。

在實際應用中,K值一般取一個比較小的數值,例如采用交叉驗證法(簡單來說,就是一部分樣本做訓練集,一部分做測試集)來選擇最優的K值。

經驗規則:k一般低於訓練樣本數的平方根。

優缺點

1、優點
簡單,易於理解,易於實現,精度高,對異常值不敏感。

2、缺點

KNN是一種懶惰算法,構造模型很簡單,但在對測試數據分類的系統開銷大(計算量大,內存開銷大),因為要掃描全部訓練樣本並計算距離。

適用范圍

數值型和標稱型(具有有窮多個不同值,值之間無序)。
比如客戶流失預測、欺詐偵測等。

算法實現

這里以python為例描述下基於歐氏距離的KNN算法實現。

歐氏距離公式:

以歐氏距離為例的示例代碼:

#! /usr/bin/env python
#-*- coding:utf-8 -*-
# E-Mail : Mike_Zhang@live.com

import math

class KNN:    
    def __init__(self,trainData,trainLabel,k):
        self.trainData = trainData
        self.trainLabel = trainLabel
        self.k = k       

    def predict(self,inputPoint):
        retLable = "None"
        arr=[]
        for vector,lable in zip(self.trainData,self.trainLabel):
            s = 0
            for i,n in enumerate(vector) :
                s += (n-inputPoint[i]) ** 2
            arr.append([math.sqrt(s),lable])
        arr = sorted(arr,key=lambda x:x[0])[:self.k]           
        dtmp = {}
        for k,v in arr :
            if not v in dtmp : dtmp[v]=0
            dtmp[v] += 1
        retLable,_ = sorted(dtmp.items(),key=lambda x:x[1],reverse=True)[0]        
        return retLable

data = [
    [1.0, 1.1],
    [1.0, 1.0],
    [0.0, 0.0],
    [0.0, 0.1],
    [1.3, 1.1],
]

labels = ['A','A','B','B','A']
knn = KNN(data,labels,3)

print knn.predict([1.2, 1.1])  
print knn.predict([0.2, 0.1])  

上面的實現比較簡單,在開發中可以使用現成的庫,比如scikit-learn :

https://github.com/mike-zhang/pyExamples/blob/master/algorithm/dataMining_KNN/knn_sklearn_test1.py

算法應用

  • 識別手寫數字

http://www.cnblogs.com/chenbjin/p/3869745.html

好,就這些了,希望對你有幫助。

本文github地址:

https://github.com/mike-zhang/mikeBlogEssays/blob/master/2017/20170616_KNN算法介紹.md

歡迎補充 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM