1. 程式人生 > >R聚類演算法-DBSCAN演算法

R聚類演算法-DBSCAN演算法

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)

這裡寫圖片描述