前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >R聚类算法-DBSCAN算法

R聚类算法-DBSCAN算法

作者头像
Erin
发布2022-05-09 14:11:22
5480
发布2022-05-09 14:11:22
举报
文章被收录于专栏:大数据风控大数据风控

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

算法实现:

代码语言:javascript
复制
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函数进行密度聚类。 很简单!

代码语言:javascript
复制
#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)
这里写图片描述
这里写图片描述
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-07-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档