關卡 1

這門課程要介紹R裡面的kNN演算法。

關卡 2

為了準備接下來的說明,我們準備了以下的物件。X.train是trainingdataset的covariates,而y.train則是trainingdataset的label;X.test是testingdataset的covariates,而y.test則是testingdataset的label。

關卡 3

請同學輸入:X.train看看trainingdataset的covariates

X.train

關卡 4

接著我們計算X.train與X.test,列與列之間的EuclideanDistance。之前的Cluster章節,我們介紹過dist函數可以計算一個矩陣之間,所有列與列之間的距離。所以一種做法就是將X.train與X.test合併成一個矩陣,然後運用dist做計算。

關卡 5

請問同學,X.train有多少列?

nrow(X.train)

關卡 6

請問同學,X.test有多少列?

nrow(X.test)

關卡 7

請輸入X<-rbind(X.train,X.test)將X合併

X <- rbind(X.train, X.test)

關卡 8

請輸入d<-dist(X)計算出X列與列之間的距離

d <- dist(X)

關卡 9

由於我們需要從距離矩陣之中,抽出需要的部分(X.train與X.test的列與列之間的距離),所以需要先把距離物件轉換為矩陣。請同學輸入:m<-as.matrix(d)

m <- as.matrix(d)

關卡 10

接著,我們抽出X.train與X.test的距離的部分。請同學輸入:m2<-m[1:75,76:150]。這裡是選出X的前75列,也就是X.train與其他資料的距離;以及X的後75欄,代表X.test與其他資料的距離。

m2 <- m[1:75,76:150]

關卡 11

R的which.min可以找出一個向量中,數值最小的位置。apply則可以對一個矩陣的每一列或每一欄做相同的動作。apply的第二個參數如果是1,代表是對每一列做;如果是2代表對每一欄做相同的動作。動作則是定義在第三個參數。所以輸入:i.1nn<-apply(m2,2,which.min)就可以取得每個欄位中,數字最小的列的位置。

i.1nn <- apply(m2, 2, which.min)

關卡 12

接著,利用y.train[i.1nn],我們就可以取得對應的trainingdatapoint的類別。也就是說,y.train[i.1nn]就是1NN的分類結果。請同學輸入:mean(y.train[i.1nn]==y.test)來看看1NN的分類結果與實際答案相比,正確的機率有多少。

mean(y.train[i.1nn] == y.test)

關卡 13

以上是用R的基礎函數所拼湊出來的計算1NN的方法。我們也可以用同樣的脈絡來計算其他資料的1NN分類結果。請同學試試看。

# 使用 ML 習題用的 Ionosphere 資料集
check_then_install("mlbench", "2.1.1")
library(mlbench)

data(Ionosphere)
test.i <- c(4L, 6L, 9L, 13L, 14L, 22L, 31L, 33L, 50L, 52L, 61L, 63L, 68L, 
  79L, 91L, 99L, 119L, 135L, 154L, 155L, 160L, 162L, 166L, 194L, 
  200L, 219L, 233L, 236L, 237L, 242L, 244L, 248L, 250L, 257L, 261L, 
  276L, 278L, 283L, 292L, 310L, 312L, 315L, 319L, 323L, 325L, 327L, 
  335L, 337L, 338L, 344L)
df.test <- Ionosphere[test.i,-2] # remove V2
X.test <- df.test[,-34]
y.test <- df.test$Class
train.i <- setdiff(seq_len(nrow(Ionosphere)), test.i)
df.train <- Ionosphere[train.i,-2]
X.train <- df.train[,-34]
y.train <- df.train$Class

# 以下程式碼示範用euclidean distance來計算1NN的分類結果。
df <- rbind(X.train, X.test)
d <- dist(df, method = "manhattan")
m <- as.matrix(d)
i <- seq_len(nrow(df.train))
j <- nrow(df.train) + seq_len(nrow(df.test))
m2 <- m[i,j]
i.1nn <- apply(m2, 2, which.min)
answer1 <- mean(y.test == y.train[i.1nn])

# 請同學修改上述程式碼中,dist函數的參數
# 讓R使用其他的「距離定義」,找出讓answer1的準確度超過0.95的結果
# 細節可以參考 ?dist 的說明文件
# 完成後請存檔後輸入`submit()`

關卡 14

上述的方法,要計算kNN是比較不方便的。因此,我們使用class這個套件來計算kNN的結果。請同學先安裝套件class

check_then_install("class", "7.3")

關卡 15

接著請同學載入class套件

library(class)

關卡 16

我們利用knn函數即可快速計算knn的結果。請同學先輸入?knn打開說明文件。

?knn

關卡 17

根據說明文件,我們只要輸入:knn(X.train,X.test,y.train,k=1)即可取得1NN的計算結果。請同學試試看。

knn(X.train, X.test, y.train, k = 1)

關卡 18

以上就是在R中計算kNN演算法的方式。