1. 程式人生 > >資料分析 第十篇:分類(kNN)

資料分析 第十篇:分類(kNN)

K最近鄰(kNN,k-NearestNeighbor)演算法是一種監督式的分類方法,但是,它並不存在單獨的訓練過程,在分類方法中屬於惰性學習法,也就是說,當給定一個訓練資料集時,惰性學習法簡單地儲存或稍加處理,並一直等待,直到給定一個檢驗資料集時,才開始構造模型,以便根據已儲存的訓練資料集的相似性對檢驗資料集進行分類。惰性學習法在提供訓練資料集時,只做少量的計算,而在進行分類或數值預測時做更多的計算。kNN演算法主要用於模式識別,對於隨機分佈的資料集分類效果較差,對於類內間距小,類間間距大的資料集分類效果好,而且對於邊界不規則的資料效果好於線性分類器。常用於推薦系統:推薦受眾喜歡電影、美食和娛樂等。

一,kNN演算法邏輯

kNN演算法的核心思想是:如果一個數據在特徵空間中最相鄰的k個數據中的大多數屬於某一個類別,則該樣本也屬於這個類別(類似投票),並具有這個類別上樣本的特性。通俗地說,對於給定的測試樣本和基於某種度量距離的方式,通過最靠近的k個訓練樣本來預測當前樣本的分類結果。

例如,借用百度的一張圖來說明kNN演算法過程,要預測圖中Xu的分類結果,先預設一個距離值,只考慮以Xu為圓心以這個距離值為半徑的圓內的已知訓練樣本,然後根據這些樣本的投票結果來預測Xu屬於w1類別,投票結果是4:1。

kNN演算法在確定分類決策上只依據最鄰近的一個或者幾個樣本的類別來決定待分樣本所屬的類別。
kNN演算法在類別決策時,只與極少量的相鄰樣本有關。
由於kNN演算法主要靠周圍有限的鄰近的樣本,而不是靠判別類域的方法來確定所屬類別的,因此對於類域的交叉或重疊較多的待分樣本集來說,kNN方法較其他方法更為適合。

1,kNN演算法的計算步驟

kNN演算法就是根據距離待分類樣本A最近的k個樣本資料的分類來預測A可能屬於的類別,基本的計算步驟如下:

  • 對資料進行標準化,通常是進行歸一化,避免量綱對計算距離的影響;
  • 計算待分類資料與訓練集中每一個樣本之間的距離;
  • 找出與待分類樣本距離最近的k個樣本;
  • 觀測這k個樣本的分類情況;
  • 把出現次數最多的類別作為待分類資料的類別。

計算距離的方法有:"euclidean"(歐氏距離),”minkowski”(明科夫斯基距離), "maximum"(切比雪夫距離), "manhattan"(絕對值距離),"canberra"(蘭式距離), 或 "minkowski"(馬氏距離)等。

2,kNN演算法如何計算距離?

在計算距離之前,需要對每個數值屬性進行規範化,這有助於避免較大初始值域的屬性比具有較小初始值域的屬性的權重過大。

  • 對於數值屬性,kNN演算法使用距離公式來計算任意兩個樣本資料之間的距離。
  • 對於標稱屬性(如類別),kNN演算法使用比較法,當兩個樣本資料相等時,距離為0;當兩個樣本資料不等時,距離是1。
  • 對於缺失值,通常取最大的差值,假設每個屬性都已經對映到[0,1]區間,對於標稱屬性,設定差值為1;對於數值屬性,如果兩個元組都缺失值,那麼設定差值為1;如果只有一個值缺失,另一個規範化的值是v,則取差值為 1-v 和 v 的較大者。

3,kNN演算法如何確定k的值?

k的最優值,需要通過實驗來確定。從k=1開始,使用檢驗資料集來估計分類器的錯誤率。重複該過程,每次k增加1,允許增加一個近鄰,選取產生最小錯誤率的k。一般而言,訓練資料集越多,k的值越大,使得分類預測可以基於訓練資料集的較大比例。在應用中,一般選擇較小k並且k是奇數。通常採用交叉驗證的方法來選取合適的k值。

R的kknn包中包含兩個自動選擇最優引數的函式:train.kknn和cv.kknn,前者採用留一交叉驗證做引數選擇,後者採用交叉驗證做引數選擇(可以自己選擇折數):

train.kknn(formula, data, kmax = 11, ks = NULL, distance = 2, kernel = "optimal",
    ykernel = NULL, scale = TRUE, contrasts = c('unordered' = "contr.dummy",
    ordered = "contr.ordinal"), ...)
cv.kknn(formula, data, kcv = 10, ...)

引數註釋:

kmax:最大的k值

  • ks:向量,用於指定k值,如果非null,那麼ks覆蓋kmax的值。
  • distince:Minkowski距離的引數
  • kernel:有效值是:"rectangular" (which is standard unweighted knn), "triangular", "epanechnikov" (or beta(2,2)), "biweight" (or beta(3,3)), "triweight" (or beta(4,4)), "cos", "inv", "gaussian" and "optimal".
  • kcv:k-fold交叉驗證的分割槽數量

函式的返回值:

best.parameters:列出最佳的k和kernel

fitted.values:核心和k的所有組合的預測列表。

MISCLASS:分類錯誤的矩陣,用於檢視錯誤率

二,kNN演算法的R實現

R語言實現kNN演算法的函式包主要有:

  • class函式包中的knn、knn.cv函式;
  • caret函式包中的knn3函式;
  • kknn函式包中的kknn函式;
class包是比較基礎的,kknn是優化之後的演算法。
例如,使用kknn包執行kNN演算法,對檢驗資料集進行分類:
mydata <- read.csv(file='C:/BlackFriday.csv',header=TRUE,stringsAsFactors = TRUE)
dt <- mydata[,c('Gender','Age', 'Occupation','City_Category','Stay_In_Current_City_Years', 'Marital_Status','Product_Category')]

dt$Occupation <- factor(as.character(dt$Occupation))
dt$Product_Category=factor(as.character(dt$Product_Category))

mydt <- dt[1:10000,]

library(kknn)

m <- dim(mydt)[1]
val <- sample(1:m,round(m/10),replace = TRUE)

dt.learn <- mydt[-val,]
dt.test <- mydt[val,]

myk <- train.kknn(Product_Category~.,dt.learn)
k <- myk$best.parameters # get best parameters of kNN

myknn <- kknn(Product_Category ~.,dt.learn,dt.test,k=11)

summary(myknn)

fit <- fitted(myknn)
table(fit,dt.test$Product_Category)

 

     

 

參考文件:

KNN演算法的R語言實現