knn演算法又稱為k近鄰分類(k-nearest neighbor classification)演算法,可以解決分類和回歸的問題。knn演算法主要是通過距離判定出訓練集中離待測樣本最近的k個樣本,然後統計這k個樣本的類別,次數最多的類別或加權後距離最小的點的類別為新資料的類別。距離越近,類別判定的準確度越高。
knn演算法有3個主要因素:訓練集、距離衡量、k值。
訓練集少且種類少的時候演算法有效,訓練集大的時候要使用kd樹和球樹的方法建立模型。
距離衡量的方法有多種,目的都是搜尋最近鄰,最常用的是歐氏距離。
k值決定了最後確定類別時所參考的樣本數量,k值過大則訓練誤差增大,選取的臨近點中包含錯誤種類的可能性增大,導致結果不準確;k值過小則泛化誤差增大,模型容易受到雜訊干擾,容易過度擬合。因此k值的選取非常重要,一般先選取乙個很小的值,再使用交叉檢驗確定最優的k值,一般都低於訓練樣本的平方根。
演算法步驟如下所示:
找k個最近樣本:給定k值,根據求出的距離選定距離最近的k個樣本
利用交叉檢驗確定最優的k值,即將資料臨時分為訓練集和測試集,從k=1開始測試,最大不能超過樣本資料的平方根,從中選出效果最好的k值。
定類別:根據最近的k個樣本的類別,確定待測樣本的類別
一般有兩種方法確定類別:第一,類別定為k個樣本**現次數最多的類別;第二,距離加權法,在k個樣本中,權重為距離平方的倒數,每個點都賦值為1,對相同種類的點進行加權求和,最後值最大的種類為待測樣本的種類。
當資料量非常大或特徵特別多時,一般使用kd樹或球樹法建模。
1、 優點
簡單易懂,易於實現,無需估計引數和反腐訓練;適合對稀有事件進行分類;
特別適合於多分類問題(multi-modal,物件具有多個類別標籤),例如根據基因特徵來判斷其功能分類,knn比svm的表現要好
2、缺點
knn是懶惰演算法,沒有提前訓練,輸入待測樣本時才選定k個最近樣本,對測試樣本分類時的計算量大,要從頭開始計算每個樣本離待測樣本的距離,速度慢;可解釋性較差,無法給出決策樹那樣的規則。
在檔案data111.txt中我們有40個點的座標,其分別屬於0,1,2,3類,類別資料儲存在檔案data2.txt中,先利用互動檢驗的方法,取其中三十組資料為訓練集,十組資料為測試集,比較結果的精確度,選出效果最好的k值,再對待測資料進行分析歸類。
使用程式如下所示:
輸出結果:# -
*- coding: utf-8-
*-import numpy as np
import operator as opt
def loaddata
(infile)
: dataset= np.
loadtxt
(infile)
return dataset
def loadtxt
(filename)
: labels= np.
loadtxt
(filename)
return labels
def normdata
(dataset)
: maxvals = dataset.
max(axis=0)
minvals = dataset.
min(axis=0)
ranges = maxvals - minvals
retdata =
(dataset - minvals)
/ ranges
return retdata, ranges, maxvals, minvals
def knn
(dataset, labels, testdata, k)
: #計算歐氏距離
distsquaremat =
(dataset - testdata)
**2 # 計算差值的平方
distsquaresums = distsquaremat.
sum(axis=
1) # 求每一行的差值平方和
distances = distsquaresums **
0.5 # 開根號,得出每個樣本到測試點的距離
#找最近鄰
sortedindices = distances.
argsort
() # 排序,得到排序後的下標
indices = sortedindices[
:k] # 取最小的k個 #sorted臨時排序
labelcount =
# 儲存每個label的出現次數 #count出現次數
for i in indices:
label = labels[i]
labelcount[label]
= labelcount.
get(label,0)
+1 # 次數加一
sortedcount =
sorted
(labelcount.
items()
, key=opt.
itemgetter(1
), reverse=true) # 對label出現的次數從大到小進行排序
return sortedcount[0]
[0] # 返回出現次數最大的label
if __name__ ==
"__main__"
: infile=
'c:/users/administrator/desktop'
dataset=np.
array
(loaddata
(infile)
) normdataset, retdata, ranges, minvals =
normdata
(dataset)
filename=
'c:/users/administrator/desktop'
labels= np.
loadtxt
(filename)
testdata = np.
array([
3.9,
5.5]
) normtestdata =
(testdata - minvals)
/ ranges
result =
knn(normdataset, labels, normtestdata,4)
('dataset='
,infile)
(dataset)
('類別:'
,result)
類別:3
Python實現KNN演算法
from numpy import import operator def creatdataset group array 1.0,1.1 1.0,1.0 0,0 0,0.1 lables a a b b return group,lables def classify0 inx,dataset,...
python實現knn演算法
importnumpyasnp importoperator defcreatedataset group np.array 1.0 1.1 1.0 1.0 0.0 0.0 0.0 0.1 labels a a b b returngroup,labels 分類演算法 inx待分類的點 defcla...
python實現KNN演算法
具體 如下 import numpy as np import matplotlib.pyplot as plt class myknn def init self,k self.k k def compute self,x train,y train,x test dist i 0 計算歐式距離 ...