這門課程會跟同學介紹在R中常用的三種Clustering算法。第一種是HierarchicalClustering,第二種是K-means,第三種是套件fpc提供的DensityBasedClustering演算法。
我們第一個要介紹的是hclust
這個算法。請同學先輸入?hclust
打開hclust
的說明頁面。
?hclust
hclust這個函數是用來計算HierarchicalClustring。它的參數共有三個。而第一個參數d則是用來接受用dist
指令建立的距離矩陣。請同學先輸入:d<-dist(iris[c(1:2,51:52,101:102),1:4])
用iris的資料建立6筆量測數據間的距離。
d <- dist(iris[c(1:2, 51:52, 101:102),1:4])
我們先請同學試試看輸入:cl<-hclust(d)
cl <- hclust(d)
接著請同學輸入plot(cl)
來簡單看看hclust的結果。
plot(cl)
由圖中可以看到,最下方的地方,hclust把每個資料點都當成是單獨的Cluster。然後依照距離,挑出兩個距離最近的Cluster,合併成一個Cluster。然後一直重複做出同樣的動作。由下往上看,我們可以看出iris的第1和第2筆資料最像,所以被先合併成一個Cluster。接下來是第51和第52,然後是101和102筆資料。接著,51、52、101和102合併成一個Cluster,最後是所有的資料合併成一個單一的Cluster。
請問同學,iris的第51和52,以及101和102筆資料,何者比較相近?1)51和52,2)101和102。
1
如果我們希望把這六筆資料分成三群,可以輸入:cl2<-cutree(cl,k=3)
,請同學試試看。
cl2 <- cutree(cl, k = 3)
rect.hclust會由上而下,依照距離,分出在計算hclust時最後三個才合併的cluster。請同學輸入:rect.hclust(cl,k=3)
,就可以在圖上看到結果。
rect.hclust(cl, k = 3)
接下來我們來看一下cl2
的型態。請同學輸入class(cl2)
。
class(cl2)
每個cl2
的element,就代表是對應資料所分配到的cluster編號。請同學把cl2印出來看看。
cl2
同學應該會看到,cl2這個整數向量中包含了三個cluster,並且R透過cl2告訴我們每一筆資料被分配到第幾個cluster。
請問第一筆資料,被分第幾個cluster?
1
在使用許多R提供的Cluster演算法,常常最終目標就是要拿到一個類似cl2的整數向量。
接著我們來試試看R提供的kmeans
函數。請同學打開kmeans
的說明文件。
?kmeans
請同學輸入:cl3<-kmeans(iris[,1:4],centers=3)
cl3 <- kmeans(iris[,1:4], centers = 3)
請同學參閱說明文件中的Value的段落。請問哪一個cl3的元素會包含各筆資料的分群結果,也就是類似cl2這樣的整數向量呢?
cluster
透過說明文件,同學應該也能查閱到R中的kmeans
所支援的演算法,以及提供的各種計算數據。
最後我們請同學安裝fpc套件。
check_then_install("fpc", "2.1.10")
接著,我們載入fpc套件。
library(fpc)
請同學打開dbscan
函數的說明文件。
?dbscan
請問dbscan的第一個參數,「不能」接受以下哪一種物件?請同學參考Arguments章節的說明作答。
numeric vector
請問參數data
使用哪一種型態的物件時,需要額外設定method
參數為"dist"
?
dissimilarity matrix or dist-object
這裡提到的dist-object
就是之前在介紹hclust函數時提到的dist
函數。
同學也可以趁機認知一見事情:Cluster的核心之一,就是如何計算資料點之間的距離。除了常用的歐式距離(Euclideandistance)之外,我們也能用dist搭配其他計算距離的演算法來建構dist-object
,再使用Cluster演算法。
回到主題。dbscan中最重要的兩個參數就是eps
和MinPts
。同學可以參考https://en.wikipedia.org/wiki/DBSCAN#Preliminary理解eps(圖中的圓圈半徑)和MinPts(要多少點聚集在一起才能成為一個Cluster的一部分)
請同學輸入:cl4<-dbscan(iris[,1:4],0.42)
cl4 <- dbscan(iris[,1:4], 0.42)
請同學回答:「哪一個cl4的element,會是每一筆資料被分配的Cluster結果(一個整數向量)」。同學可以參考說明文件中的Value段的說明。
cluster
讓我們輸入cl4$cluster
,看看分群結果。
cl4$cluster
除了數字1,2,和3之外,同學還會看到數字0。在dbscan的輸出中,0的意義是?A)一種clusterB)雜訊。請同學依照說明文件中的解釋作答。
B
我們對分群演算法的使用就介紹就到這了。最後請同學完成一個練習,結束之後請輸入submit()
檢查正確性。
#' 請同學先安裝 mlbench 這個套件後進行這份作業
check_then_install <- function(pkg_name, pkg_version) {
if (!require(pkg_name, character.only = TRUE)) utils::install.packages(pkg_name, repos = "http://cran.r-project.org") else {
if (packageVersion(pkg_name) < package_version(pkg_version)) utils::install.packages(pkg_name, repos = "http://cran.r-project.org")
}
}
check_then_install("mlbench", "2.1.1")
library(mlbench)
set.seed(1)
shapes <- mlbench.shapes(500)
table(shapes$classes)
d.shapes <- dist(shapes$x)
#' 請使用hclust 的預設參數,建立一個Hierarchical Clustering的結果
#' 再從上述結果產生一個有4群的Cluster結果
cl1 <- {
NULL #' 請在這邊輸入你的程式碼
}
cl1 <- {
tmp <- hclust(d.shapes)
cutree(tmp, 4)
}
#' 結果應該是一個integer vector
stopifnot(class(cl1)[1] == "integer")
#' 請使用k.means 和以下參數得到第二個cluster的結果
#' centers = shapes$x[c(1,126,251, 376),]
cl2 <- {
NULL #' 請在這邊輸入你的程式碼
}
cl2 <- {
kmeans(shapes$x, centers = shapes$x[c(1,126,251, 376),])$cluster
}
#' 結果應該是一個integer vector
stopifnot(class(cl2)[1] == "integer")
cl3 <- {
NULL #' 請在這邊輸入你的程式碼
}
cl3 <- {
as.integer(dbscan(d.shapes, eps = 0.5, method = "dist")$cluster)
}
#' 結果應該是一個integer vector
stopifnot(class(cl3)[1] == "integer")