R聚類演算法-DBSCAN演算法
阿新 • • 發佈:2019-01-04
DBSCAN演算法(Density-Based Spatial Clustering of Application
with Noise)密度聚類演算法
基於密度的聚類演算法,K-means和層次聚類對於球狀的簇聚類效果很好,DBSCAN可以用於更多複雜形狀簇的聚類。
R中實現DBSCAN演算法的API
“fpc”包
install.packages(“fpc”)
dbscan(data,eps,MinPts)
- data 樣本資料 eps
- 領域的大小,使用圓的半徑表示
- Minpts 領域內,點的個數的閾值
理解概念:
密度(Density)
空間中任意一點的密度是以該點為圓心,以EPS為半徑的圓區域內包含的點數目
N的密度為1,B、C的密度為2,A的密度為4
鄰域(Neighborhood)
空間中任意一點的鄰域是以該點為圓心、以EPS為半徑的圓區域內包含的點集合
核心點(Core Points)
空間中某一點的密度,如果大於某一給定閾值MinPts,則稱該點為核心點
設MinPts為3,則核心點為A
邊界點(Border Points)
空間中某一點的密度>1並且小於MinPts
圖中的邊界點為B、C
噪聲點(Noise Points)
資料集中不屬於核心點,也不屬於邊界點的點,密度值為1
圖中噪聲點為N
演算法實現:
data <- read.csv('data.csv')
plot(data[, 1 ], data[, 2])
eps <- 0.2;
MinPts <- 5;
d <- as.matrix(dist(data))
#將所有點標記為核心點、邊界點或噪聲點
ps <- data.frame(index=c(NA), density=c(NA), type=c(NA))
for(i in 1:nrow(data)) {
#i <- 1;
index <- which(d[i, ]<eps)
#密度,空間中任意一點的密度是以該點為圓心、以 Eps 為半徑的圓區域內包含的點數
density <- length(index);
if (density>MinPts) {
#核心點(Core Points)
#空間中某一點的密度,如果大於某一給定閾值MinPts,則稱該為核心點
ps[i, ] <- c(i, density, 1)
} else if(density>1) {
#邊界點(Border Points)
#空間中某一點的密度,如果小於某一給定閾值MinPts,則稱該為邊界點
ps[i, ] <- c(i, density, 2)
} else {
#噪聲點(Noise Points)
#資料集中不屬於核心點,也不屬於邊界點的點,也就是密度值為1的點
ps[i, ] <- c(i, density, 0)
}
}
#把噪聲點過濾掉,因為噪聲點無法聚類,它們獨自一類
corePoints <- data[which(ps$type!=0), ]
coreDists <- as.matrix(dist(corePoints))
#首先,把每個點的領域都作為一類
#鄰域(Neighborhood)
#空間中任意一點的鄰域是以該點為圓心、以 Eps 為半徑的圓區域內包含的點集合
cluster <- list();
for(i in 1:nrow(coreDists)) {
cluster[[i]] <- names(which(coreDists[i, ]<eps));
}
#然後,將有交集的領域,都合併為新的領域
for(i in 1:length(cluster)) {
for(j in 1:length(cluster)) {
if(any(cluster[[j]] %in% cluster[[i]]) && i!=j) {
if(ps[cluster[[i]][1], ]$type==1 && ps[cluster[[i]][2], ]$type==1) {
cluster[[i]] <- unique(append(cluster[[i]], cluster[[j]]))
cluster[[j]] <- list();
}
}
}
}
#最後,找出獨立(也就是沒有交集)的領域,就是我們最後的聚類的結果了
result <- list();
for(i in 1:length(cluster)) {
if(length(cluster[[i]])>0) {
result[[length(result)+1]] <- cluster[[i]]
}
}
#找出每個點所在領域的序號,作為他們最後聚類的結果標記
for(i in 1:length(result)) {
for(j in result[[i]]) {
data[j, 3] <- i
}
}
plot(data[, 1], data[, 2], col=data[,3])
如何使用”fpc”包中的dbscan函式進行密度聚類。
很簡單!
#install.packages('fpc')
library('fpc')
data <- read.csv('data.csv')
plot(data[, 1], data[, 2])
# 用fpc包中的dbscan函式進行密度聚類
model2 <- dbscan(data, eps=0.2, MinPts=5)
plot(data[, 1], data[, 2], col=model2$cluster)