用R语言实现密度聚类dbscan (下)

欢迎关注天善智能,我们是专注于商业智能BI,人工智能AI,大数据分析与挖掘领域的垂直社区,学习,问答、求职一站式搞定!

对商业智能BI、大数据分析挖掘、机器学习,python,R等数据领域感兴趣的同学加微信:tstoutiao,邀请你进入数据爱好者交流群,数据爱好者们都在这儿。

作者:张丹,R语言中文社区专栏特邀作者,《R的极客理想》系列图书作者,民生银行大数据中心数据分析师,前况客创始人兼CTO。

个人博客 http://fens.me, Alexa全球排名70k。

下面我们通过绘制k-距离曲线,寻找knee,即明显拐点位置为对应较好的参数,找到适合的eps值。使用kNNdistplot()函数,让参数k=dim + 1,dim为数据集列的个数,iris2是4列,那么设置k=5。

1# 画出最近距离图
2> kNNdistplot(iris2, k = 5)
3> abline(h=0.5, col = "red", lty=2)


用R语言实现密度聚类dbscan (下)


kNNdistplot()会计算点矩阵中的k=5的最近邻的距离,然后按距离从小到大排序后,以图形进行展示。x轴为距离的序号,y轴为距离的值。图中黑色的线,从左到右y值越来越大。

通过人眼识别,k-距离曲线上有明显拐点,我们以y=0.5平行于x轴画一条红色线,突出标识。所以,最后确认的eps为0.5。

调用dbscan()函数,进行对iris2数据集进行聚类,eps=0.5,minPts=5。

 1> res  2> res
3DBSCAN clustering for 150 objects.
4Parameters: eps = 0.5, minPts = 5
5The clustering contains 2 cluster(s) and 17 noise points.
6
7 0 1 2
817 49 84
9
10Available fields: cluster, eps, minPts

聚类后,一共分成了2组,第1组49个值,第2组84个值,另外,第0组17个值为噪声点。把聚类的结果画图展示。

1> pairs(iris, col = res$cluster + 1L)


用R语言实现密度聚类dbscan (下)


数据集是多列的,把每2列组合形成的二维平面,都进行输出。红色点表示第1组,绿色点表示为第2组,黑色点表示噪声点。这样就完成了有噪声的基于密度的dbscan聚类。

五、hdbscan()函数使用

hdbscan(),快速实现了分层DBSCAN算法,与stats包中的hclust()方法形成的传统分层聚类方法类似。

函数定义:

1hdbscan(x, minPts, xdist = NULL,gen_hdbscan_tree = FALSE, gen_simplified_tree = FALSE)

参数解释:

  • x,矩阵或者距离对象
  • minPts,区域中的最小点数量
  • xdist,dist对象,可以提前算出来,当参数传入
  • gen_hdbscan_tree,生成一个hdbscan树
  • gen_simplified_tree,生成一个简化的树结构

3.1 iris鸢尾花的数据集

以iris鸢尾花的数据集,做为样本,去掉种属列。设置minPts =5让当前群集中最小的数量为5,开始聚类。

1> hcl2HDBSCAN clustering for 150 objects.
3Parameters: minPts = 5
4The clustering contains 2 cluster(s) and 0 noise points.
5
6 1 2
7100 50
8
9Available fields: cluster, minPts, cluster_scores, membership_prob, outlier_scores, hc


聚类后,一共分成了2组,第1组100个值,第2组50个值,没有噪声点。生成的hcl对象包括6个属性。

属性解释

  • cluster,表明属性哪个群集,零表示噪声点。
  • minPts,群集中最小的数量
  • cluster_scores,每个突出(“平坦”)群集的稳定性分数之和。
  • membership_prob,群集内某点的“概率”或个体稳定性
  • outlier_scores,每个点的异常值
  • hc,层次结构对象

把聚类的结果画图展示。

1> plot(iris2, col=hcl$cluster+1, pch=20)


用R语言实现密度聚类dbscan (下)


数据集是多列的,把每2列组合形成的二维平面,都进行输出。红色点表示第1组,绿色点表示为第2组,这样就完成了hdbscan聚类。

打印hcl对象层次结构,包括150个数据,聚法方法是健壮单一的,距离是相互可达。

1> hcl$hc
2
3Call:
4hdbscan(x = iris2, minPts = 5)
5
6Cluster method : robust single
7Distance : mutual reachability
8Number of objects: 150


画出层次的合并过程图

1> plot(hcl$hc, main="HDBSCAN* Hierarchy")


用R语言实现密度聚类dbscan (下)


从图可以清楚的看出,主要的2类的分支,区分度比较高。

3.2 moons数据集

由于iris数据集用hdbscan聚类获得的结果,与真实的数据分类结果不一致。我们再用dbscan包自带的数据集moons做一下测试。

先准备数据,加载moons数据集,了解数据基本情况,画出散点图。

 1# 加载dbscan自带数据集
2> data("moons")
3> head(moons)
4 X Y
51 -0.41520756 1.0357347
62 0.05878098 0.3043343
73 1.10937860 -0.5097378
84 1.54094828 -0.4275496
95 0.92909498 -0.5323878
106 -0.86932470 0.5471548
11
12# 画出散点图
13> plot(moons, pch=20)


用R语言实现密度聚类dbscan (下)


用hdbscan()函数,实现层次dbscan算法。

 1> cl  2> cl
3HDBSCAN clustering for 100 objects.
4Parameters: minPts = 5
5The clustering contains 3 cluster(s) and 0 noise points.
6
7 1 2 3
825 25 50
9
10Available fields: cluster, minPts, cluster_scores, membership_prob, outlier_scores, hc


一共100条数据,被分成了3类,没有噪声。把聚类的结果画图展示。

1# 画图
2> plot(moons, col=cl$cluster+1, pch=20)



用R语言实现密度聚类dbscan (下)


打印层次结构

1> cl$hc
2Call:
3hdbscan(x = moons, minPts = 5)
4
5Cluster method : robust single
6Distance : mutual reachability
7Number of objects: 100


画出层次的合并过程图

1> plot(cl$hc, main="HDBSCAN* Hierarchy")


用R语言实现密度聚类dbscan (下)


从图可以清楚的看出,主要的3类的分支,区分度比较高。

如果我们想省略分层的细节,我们可以只画出主要分支,并标识类别。

1plot(cl, gradient = c("purple", "blue", "green", "yellow"), show_flat = T)


用R语言实现密度聚类dbscan (下)



接下来,我们要对群集的稳定性做一些优化,cluster_scores属性可以查看集群的得分。

1> cl$cluster_scores
2 1 2 3
3110.70613 90.86559 45.62762


通过membership_prob属性,画图表示个体的稳定性。

 1# 打印membership_prob
2> head(cl$membership_prob)
3[1] 0.4354753 0.2893287 0.4778663 0.4035933 0.4574012 0.4904582
4
5# 计算群集的数量
6> num 7
8# 从彩虹色中取得对应数量的颜色
9> rains10> cols11> cols[which(cols==1)]12> cols[which(cols==2)]13> cols[which(cols==3)]14
15# 设置透明度,表示个体的稳定性
16> plot(moons, col=alpha(cols,cl$membership_prob), pch=19)



用R语言实现密度聚类dbscan (下)


最后,我们可以在图中,在标记出异常值得分最高的前6个点。

1# 对异常值进行排序,取得分最高的
2> top_outliers % head
3> plot(moons, col=alpha(cols,cl$outlier_scores), pch=19)
4> text(moons[top_outliers, ], labels = top_outliers, pos=3)


用R语言实现密度聚类dbscan (下)


从图中看到,异常得分高的点(outlier_scores)与个体的稳定性(membership_prob),并不是同一类点。异常值通常被认为是,偏离其假定的基础分布的离群点。

在最后

通过上面3个函数的使用案例,我们了解了如何用dbscan包实现基于密度的聚类方法。真实世界的数据是复杂的,我们用来分析数据的工具也是多样的,多掌握一种工具、多一些知识积累,让我们迎接真实世界数据的挑战吧。



用R语言实现密度聚类dbscan (下)


往期精彩:

  • R语言实现46种距离算法
  • R语言中文社区2018年终文章整理(作者篇)
  • R语言中文社区2018年终文章整理(类型篇)
用R语言实现密度聚类dbscan (下)

回复 爬虫 爬虫三大案例实战

回复 Python 1小时破冰入门

回复 数据挖掘 R语言入门及数据挖掘

回复 人工智能 三个月入门人工智能

回复 数据分析师 数据分析师成长之路

回复 机器学习 机器学习的商业应用

回复 数据科学 数据科学实战

回复 常用算法 常用数据挖掘算法


分享到:


相關文章: