R聚类算法-DBSCAN算法

来源:互联网 发布:手机淘宝搭配套餐模块 编辑:程序博客网 时间:2024/05/20 00:35

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)

这里写图片描述