iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 28
5
Big Data

R語言與機器學習見面會系列 第 28

Day28 R語言機器學習之K-NN、SVM、貝氏分類

第28天了!今天豪邁的把鐵人賽前備用的分類演算法題目一次乾了,喉嚨借我過一下。

  • k最近鄰居分類法(k-Nearest Neighbour Classification)
  • 支持向量機(Support Vector Machines, SVM)
  • 樸素貝氏分類器(Naive Bayes Classifier)

先準備今天的環境,專案新增一支Day28.R
http://ithelp.ithome.com.tw/upload/images/20161228/20103434UQAsuSZ8yA.png

載入鳶尾花(iris)資料集,分成訓練組及測試組

#(1)載入iris資料
data(iris)

#(2)畫散佈圖
library(ggplot2)
#花萼長寬分佈
ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) + geom_point(aes(color = Species))
#花瓣長寬分佈
ggplot(iris, aes(x = Petal.Length, y = Petal.Width)) + geom_point(aes(color = Species))
#(3)切分訓練及測試樣本
#設定亂數種子
set.seed(1111)
#樣本筆數
n <- nrow(iris)
#取出樣本數的idx
t_idx <- sample(seq_len(n), size = round(0.7 * n))
#訓練資料與測試資料比例: 70%建模,30%驗證
traindata <- iris[t_idx,]
testdata <- iris[ - t_idx,]

花萼長寬分佈
http://ithelp.ithome.com.tw/upload/images/20161228/20103434lmUIo0OHJp.png

花瓣長寬分佈
http://ithelp.ithome.com.tw/upload/images/20161228/20103434kNFreVCFtB.png

如果我們知道亞種(上圖中的顏色)的標準答案,不管用花萼或是花瓣好像都可以肉眼分辨出來,但如果我們不知道標準答案時:

http://ithelp.ithome.com.tw/upload/images/20161228/201034345KrywXECsn.png

前面兩天複習到的決策樹與類神經(Artificial neural network)都可以幫助我們完成分類問題,我們今天來試試其他分類演算法。

k最近鄰居分類法(k-Nearest Neighbour Classification)


K-NN使用點間的距離為分類標準,當新的觀測值準備預測時,演算法會計算出和她接近最多的類目標點,比方說,k值=5,觀測值比較靠近其中3個目標點時,演算法就會採用多數票來決定分類結果。

#安裝並載入class套件
library(class)
library(dplyr)
#(參數1)準備訓練樣本組答案
trainLabels <- traindata$Species

#(參數2)(參數3)去除兩個樣本組答案
knnTrain <- traindata[, - c(5)]
knnTest <- testdata[, - c(5)]

#計算k值(幾個鄰居)通常可以用資料數的平方根
kv <- round(sqrt(n))
kv

#(4)建立模型 
prediction <- knn(train = knnTrain, test = knnTest, cl = trainLabels, k = kv)

#(5)評估正確性
cm <- table(x = testdata$Species, y = prediction, dnn = c("實際", "預測"))
cm

knnaccuracy <- sum(diag(cm)) / sum(cm)
knnaccuracy

http://ithelp.ithome.com.tw/upload/images/20161228/20103434vwgANkaVLk.jpg

當k值=12時,準確度大約95.5%,已經是相當高的預測了。

分別使用knn結果對訓練組資料及測試資料畫散佈圖加上密度2D圖

#利用knn結果畫圖
#訓練組
knnTrain$Species <- trainLabels
ggplot(knnTrain, aes(x = Petal.Length, y = Petal.Width)) + geom_point(aes(color = Species)) +
stat_density2d(aes(color = Species))

#測試組
knnTest$Species <- prediction
ggplot(knnTest, aes(x = Petal.Length, y = Petal.Width), n = 10) + geom_point(aes(color = Species)) +
stat_density2d(aes(color = Species), h = 0.6)

訓練組

http://ithelp.ithome.com.tw/upload/images/20161228/20103434CbQQH6j8s8.png

測試組

http://ithelp.ithome.com.tw/upload/images/20161228/20103434U6Fj8hWEcz.png

Knn這次預測的問題在virginica和versicolor兩個亞種同時位在DMZ時(分佈太接近),會有誤判。

選擇k value


除了用訓練組平方根計算K值,另外一種方式就是比較k值的準確度(accuracy),作法就是用剛剛平方根算出來的k值微調(tuning)到k+k的距離,然後重新跑模型測試各種k值準確度(accuracy),最後取取最佳值出來。

k值太小會有overfitting的問題,思考了一下1-nn的概念,如果每個訓練用的觀測值都自成一格,在分類上的效果好像就失去了,所以也許比較的範圍可以從2-2k

# 選擇k value
klist <- seq(1:(kv + kv))
knnFunction <- function(x, knnTrain, knnTest, trainLabels, testLabels) {
    prediction <- knn(train = knnTrain, test = knnTest, cl = trainLabels, k = x)
    cm <- table(x = testLabels, y = prediction)
    accuracy <- sum(diag(cm)) / sum(cm)
}
accuracies <- sapply(klist, knnFunction, knnTrain = knnTrain, knnTest = knnTest, trainLabels = trainLabels, testLabels = testdata$Species)

# k value與準確度視覺化
df <- data.frame(
       kv = klist, accuracy = accuracies)

ggplot(df, aes(x = kv, y = accuracy, label = kv, color = accuracy)) +
geom_point(size = 5) + geom_text(vjust = 2)

http://ithelp.ithome.com.tw/upload/images/20161228/20103434EPEn9Dzhdn.png

這樣的概念也可以用在幾種分類器間的選擇,像是同時跑決策樹、類神經及knn取最佳解或是幾種演算法的結果再機器學習一次。

支持向量機(Support Vector Machines, SVM)


使用SVM及樸素貝氏分類器之前,我們需要載入套件e1071:Misc Functions of the Department of Statistics。

SVM WIKI

分類資料是機器學習中的一項常見任務。 假設某些給定的資料點各自屬於兩個類之一,而目標是確定新資料點將在哪個類中。對於支援向量機來說,資料點被視為 p 維向量,而我們想知道是否可以用 (p-1)維超平面來分開這些點。這就是所謂的線性分類器。可能有許多超平面可以把資料分類。最佳超平面的一個合理選擇是以最大間隔把兩個類分開的超平面。因此,我們要選擇能夠讓到每邊最近的資料點的距離最大化的超平面。如果存在這樣的超平面,則稱為最大間隔超平面,而其定義的線性分類器被稱為最大間隔分類器,或者叫做最佳穩定性感知器。

#載入套件 
library(e1071)

# 建立模型
svmM <- svm(Species ~ ., data = traindata, probability = TRUE)

# 預測
results <- predict(svmM, testdata, probability = TRUE)

# 評估
cm <- table(x = testdata$Species, y = results)
cm
SVMaccuracy <- sum(diag(cm)) / sum(cm)
SVMaccuracy

http://ithelp.ithome.com.tw/upload/images/20161228/20103434dyU92jlkyc.png

準確度(accuracy):91%

樸素貝氏分類器(Naive Bayes Classifier)


樸素貝氏分類器(Naive Bayes Classifier),也看過有人翻譯樸素貝葉斯算法。
如果觀測資料具有條件獨立,樸素貝氏分類收斂速度非常過速,貝氏分類器可以直接使用條件機率相乘計算出分佈。
不過樸素貝氏分類也有缺點,她沒辦法學習到x變數間共同出現的機率。

nbcm <- naiveBayes(Species ~ ., data = traindata)
results <- predict(nbcm, testdata)

# 評估
cm <- table(x = testdata$Species, y = results)
cm
naiveBayesaccuracy <- sum(diag(cm)) / sum(cm)
naiveBayesaccuracy

http://ithelp.ithome.com.tw/upload/images/20161228/20103434VDswT2gaVy.png

準確度(accuracy):91%,不知道是不是都來自e1071套件,所以和svm英雄所見相同。

漢堡王之今日我最大


今天的預測結果

df <- data.frame(perf = c(knnaccuracy, SVMaccuracy, naiveBayesaccuracy), name = c("KNN", "SVM", "naiveBay"));

ggplot(df, aes(x = name, y = perf, color = name, label = perf)) +
geom_point(size = 5) + geom_text(vjust = 2)

http://ithelp.ithome.com.tw/upload/images/20161228/20103434cDfuRX610G.png

只有今天喔!

參考:

支持向量機 wiki
https://zh.wikipedia.org/wiki/%E6%94%AF%E6%8C%81%E5%90%91%E9%87%8F%E6%9C%BA

樸素貝式分類器wiki
https://zh.wikipedia.org/wiki/%E6%9C%B4%E7%B4%A0%E8%B4%9D%E5%8F%B6%E6%96%AF%E5%88%86%E7%B1%BB%E5%99%A8

無限期支持向量機
https://www.facebook.com/unlimitedsvm/posts/753660647998775
http://www.csie.ntu.edu.tw/~cjlin/libsvm/


選擇鄰居:

庫倫諾夫
http://ithelp.ithome.com.tw/upload/images/20161228/201034345OeCiLtKHw.jpg
2013.05攝於Český Krumlov,Czech

帖契
http://ithelp.ithome.com.tw/upload/images/20161228/20103434XdZ2Niy8q2.jpg
2013.05攝於telc,Czech


上一篇
Day27 R語言機器學習之類神經網路
下一篇
Day29 R語言機器學習之 K-Means 分群演算法
系列文
R語言與機器學習見面會30

尚未有邦友留言

立即登入留言