原理:已知樣本集中每一個數據與所屬分類的對應關係,輸入沒有標籤的新數據後,將新數據與訓練集的數據對應特徵進行比較,找出“距離”最近的k(通常k<20)數據,選擇這k個數據中出現最多的分類作爲新數據的分類。
算法描述:(1)計算已知類別數據及中的點與當前點的距離;
(2)按距離遞增次序排序
(3)選取與當前點距離最小的k個點
(4)確定前K個點所在類別出現的頻率
(5)返回頻率最高的類別作爲當前類別的預測
距離計算方法有"euclidean”(歐氏距離), “wski”(明科夫斯基距離),"maximum"(切比雪夫距離), "manhattan"(絕對值距離),"canberra"(蘭式距離), "minkowski"(馬氏距離)等。
最常見以歐氏距離作爲衡量標準,下文例子也以歐式距離爲標準。
R實現:
以鳶尾花數據集爲例來說明K-近鄰算法:
鳶尾花數據集包含150個數據,測量變量爲花瓣的長度與寬度,花萼的長度與寬度,以及種類分類爲setosa, versicolor, 和 virginica。
(1)爲了瞭解數據,應先通過作圖分析,相關分析來看看數據分類指標的合理性,這一點十分重要,有助於減少分類指標中的噪聲。
代碼爲:plot(Sepal.Width,Sepal.Length,col=Species)
plot(Petal.Width,Petal.Length,col=Species)
從上圖可以看出,Petal的長度和寬度2個變量大致是可以把鳶尾花分類的,也就是說分類的特徵變量選擇是合理的,而Sepal的長度和寬度分類效果不如Petal,但大致上還是能區分的,當然也可以選擇計算相關係數來看特徵變量的合理性。
(2)數據歸一化處理
容易發現,數值差最大的屬性對距離的影響最大,所以在特徵值等權重的假定下,我們先得歸一化特徵值,計算公式爲:
Newvalue=(oldvalue-min)/(max-min)
代碼爲:
autonorm<-function(data){
min<-min(data)
max<-max(data)
for(i in 1:length(data))
data[i]<-(data[i]-min)/(max-min)
return(data)
}
data<-apply(as.matrix(iris[,1:4]),2,autonorm)
(3)計算距離。
在這裏取三個數據作爲驗證集來看看分類的效果,首先將驗證集歸一化:
x<-iris[13,1:4]
y<-iris[79,1:4]
z<-iris[100,1:4]
x<-(x-apply(iris[c(-13,-79,-100),1:4],2,min))/(apply(iris[c(-13,-79,-100),1:4],2,max)-apply(iris[c(-13,-79,-100),1:4],2,min))
y<-(y-apply(iris[c(-13,-79,-100),1:4],2,min))/(apply(iris[c(-13,-79,-100),1:4],2,max)-apply(iris[c(-13,-79,-100),1:4],2,min))
z<-(z-apply(iris[c(-13,-79,-100),1:4],2,min))/(apply(iris[c(-13,-79,-100),1:4],2,max)-apply(iris[c(-13,-79,-100),1:4],2,min))
計算距離,僅以Z爲例,運行代碼:(k取5)
dis<-rep(0,length(data[,1]))
for(i in 1:length(data[,1]))
dis[i]<-sqrt(sum((z-data[i,1:4])^2))
table(iris[order(dis)[1:5],5])
結果如下:
從x,y,z的輸出結果可以看到,分類完全正確,沒有錯誤分類。
值得一提的是,我們用同樣的辦法計算K=3時的情形,會發現沒有出現誤分類。這也就引出了一個值得思考的問題:k應該如何選取?k過小,噪聲對分類的影響就會變得非常大,K過大,那麼包含錯誤就理所當然,誤分類也不足爲奇。雖然這裏我們對K的取值並未進行討論,但在實際中,我們應該通過交叉驗證的辦法來確定k值。
R語言內置函數kknn簡介
R語言裏的kknn包也可以實現最鄰近算法——使用kknn函數。
kknn(formula = formula(train),train, test, na.action = na.omit(), k= 7, distance = 2, kernel = "optimal", ykernel = NULL, scale=TRUE, contrasts= c('unordered' = "contr.dummy", ordered ="contr.ordinal"))
參數解釋:
formula 一個迴歸模型,具體爲:分類變量~特徵變量
train 訓練集
test 測試集
na.action 缺失值處理,默認爲去掉缺失值
k k值選擇,默認爲7
distance 這個是明科夫斯基距離,p=2時爲歐氏距離
其他參數 略
上面的鳶尾花例子使用kknn包可以實現(k=5):
library(kknn)
data(iris)
m <- dim(iris)[1]
val <- sample(1:m, size =round(m/3), replace = FALSE,prob= rep(1/m, m))
iris.learn <- iris[-val,]
iris.valid <- iris[val,]
iris.kknn <- kknn(Species~.,iris.learn, iris.valid, distance = 5,kernel= "triangular")
summary(iris.kknn)
fit <- fitted(iris.kknn)
table(iris.valid$Species, fit)
運行結果爲: