一 . K-近鄰算法(KNN)概述
最簡單最初級的分類器是將全部的訓練數據所對應的類別都記錄下來,當測試對象的屬性和某個訓練對象的屬性完全匹配時,便可以對其進行分類。但是怎麼可能所有測試對象都會找到與之完全匹配的訓練對象呢,其次就是存在一個測試對象同時與多個訓練對象匹配,導致一個訓練對象被分到了多個類的問題,基於這些問題呢,就產生了KNN。
KNN是通過測量不同特徵值之間的距離進行分類。它的思路是:如果一個樣本在特徵空間中的k個最相似(即特徵空間中最鄰近)的樣本中的大多數屬於某一個類別,則該樣本也屬於這個類別,其中K通常是不大於20的整數。KNN算法中,所選擇的鄰居都是已經正確分類的對象。該方法在定類決策上只依據最鄰近的一個或者幾個樣本的類別來決定待分樣本所屬的類別。
下面通過一個簡單的例子說明一下:如下圖,綠色圓要被決定賦予哪個類,是紅色三角形還是藍色四方形?如果K=3,由於紅色三角形所佔比例爲2/3,綠色圓將被賦予紅色三角形那個類,如果K=5,由於藍色四方形比例爲3/5,因此綠色圓被賦予藍色四方形類。
由此也說明了KNN算法的結果很大程度取決於K的選擇。
在KNN中,通過計算對象間距離來作爲各個對象之間的非相似性指標,避免了對象之間的匹配問題,在這裏距離一般使用歐氏距離或曼哈頓距離:
歐氏距離:,
曼哈頓距離:
同時,KNN通過依據k個對象中佔優的類別進行決策,而不是單一的對象類別決策。這兩點就是KNN算法的優勢。
接下來對KNN算法的思想總結一下:就是在訓練集中數據和標籤已知的情況下,輸入測試數據,將測試數據的特徵與訓練集中對應的特徵進行相互比較,找到訓練集中與之最爲相似的前K個數據,則該測試數據對應的類別就是K個數據中出現次數最多的那個分類,其算法的描述爲:
- 計算測試數據與各個訓練數據之間的距離;
- 按照距離的遞增關係進行排序;
- 選取距離最小的K個點;
- 確定前K個點所在類別的出現頻率;
- 返回前K個點中出現頻率最高的類別作爲測試數據的預測分類.
二 .python實現
建立一個KNN.py文件對算法的可行性進行驗證,如下:
#coding:utf-8
from numpy import *
import operator
##給出訓練數據以及對應的類別
def createDataSet():
group = array([[1.0,2.0],[1.2,0.1],[0.1,1.4],[0.3,3.5]])
labels = ['A','A','B','B']
return group,labels
###通過KNN進行分類
def classify(input,dataSe t,label,k):
dataSize = dataSet.shape[0]
####計算歐式距離
diff = tile(input,(dataSize,1)) - dataSet
sqdiff = diff ** 2
squareDist = sum(sqdiff,axis = 1)###行向量分別相加,從而得到新的一個行向量
dist = squareDist ** 0.5
##對距離進行排序
sortedDistIndex = argsort(dist)##argsort()根據元素的值從大到小對元素進行排序,返回下標
classCount={}
for i in range(k):
voteLabel = label[sortedDistIndex[i]]
###對選取的K個樣本所屬的類別個數進行統計
classCount[voteLabel] = classCount.get(voteLabel,0) + 1
###選取出現的類別次數最多的類別
maxCount = 0
for key,value in classCount.items():
if value > maxCount:
maxCount = value
classes = key
return classes
接下來,在命令行窗口輸入如下代碼:
#-*-coding:utf-8 -*-
import sys
sys.path.append("...文件路徑...")
import KNN
from numpy import *
dataSet,labels = KNN.createDataSet()
input = array([1.1,0.3])
K = 3
output = KNN.classify(input,dataSet,labels,K)
print("測試數據爲:",input,"分類結果爲:",output)
回車之後的結果爲:
測試數據爲: [ 1.1 0.3] 分類爲: A
答案符合我們的預期.