当前位置:首页 > 代码 > 正文

层次聚类c代码讲解(层次聚类算法基本原理)

admin 发布:2022-12-19 16:17 107


本篇文章给大家谈谈层次聚类c代码讲解,以及层次聚类算法基本原理对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

数量生态学笔记||层次聚类

本周开始我们的《数量生态学笔记》的第四章:聚类分析。聚类分析又称群分析,它是研究(样品或指标)分类问题的一种统计分析方法,同时也是数据挖掘的一个重要算法。在生态学研究当中,聚类的目的是识别环境中不连续对象的子集。实际上,聚类分析是所研究对象集合的分组。

需要注意大部分聚类方法都是基于 关联矩阵 进行计算,这也说明选择恰当的关联系数非常重要。

如图所示,我们需要识别不同类型的聚类方法及其应用的条件。

单连接聚合聚类也称作最近临体聚类,该方法聚合对象的依据是最短的成对距离。每个对象或簇首次连接的 列表 成为主链接,也成为最小拓展树。

允许一个对象或簇与另一组聚合的依据是最远距离对。

单一连接是一个对象很容易聚合到一个分组,因为单次连接足以导致融合。因此单连接聚类也被称为 最亲密朋友法 。虽然产生的分类组不清晰,但容易识别梯度。相反,完全连接聚类产生的分类之间差异比较明显。完全连接聚类更倾向与产生很多小的分离的组,更适合于寻找和识别数据的间断分布。

平均聚合聚类是一类基于对象平均相异性或聚类簇中心的聚类方法。此类聚类有4种,不同的方法区别在于组的位置计算方式和计算融合时是否包含对象数量作为权重。

最著名的当属UPGMA方法,一个对象加入一个组的依据是这个对象与该组的每个成员之间的平均距离。

需要注意的是 UPGMC和WPGMC有时会导致树的翻转,分类结果难以解读。

这是一种基于最小二乘法线性模型准则的聚类方法,分组依据是是组内平方和(即方差分析的方差)最小化。

需要牢记的是聚类分析是一种探索分析,而非统计检验。影响聚类结果的因素包括聚类方法本省和用于聚类分析的关联系数。

对已经完成层次聚类任意两个对象,在聚类树上从一个对象向上走,到达与另一个对象交回节点向下走,势必会到达第二个对象。交汇节点所在的层次水平即是两个对象的同表型距离 。

为了描述一个距离矩阵与通过不同聚类方法得到的同表型矩阵之间的相关性,可以绘制原始距离对阵同表型距离的Shepard

图。

原始距离与同表型距离之间的差值平方和

为了解读和比较聚类的结果,通常需要寻找可解读的聚类簇,这意味着需要决定聚类树裁剪到哪个水平。

聚类树的融合水平值是聚类树中两个分支融合处的相异性的数值。

使用cutree()函数设定分类组的数量,并使用列联表比较分类差异。

轮廓宽度是描述一个对象与所属聚类归属程度的测度,是一个对象同组内其他对象的平均距离与该对象同最邻近聚类簇内所有对象的平均距离比较。

参考:

常用聚类算法有哪些?六大类聚类算法详细介绍

无监督学习-- 聚类(Clustering)

百科||聚类算法

聚类分析

聚类算法 - 凝聚层次聚类

层次聚类 就是通过对数据集按照某种方法进行层次分解,直到满足某种条件为止。按照分类原理的不同,可以分为凝聚和分裂两种方法。

层次聚类方法对给定的数据集进行层次的分解,直到某种条件满足为止。具体又可分为 凝聚 和 分裂 的两种方案:

凝聚的层次聚类是一种自底向上的策略,首先将每个对象作为一个簇,然后合并这些原子簇为越来越大的簇,直到所有的对象都在一个簇中,或者某个终结条件被满足,绝大多数层次聚类方法属于这一类,它们只是在簇间相似度的定义上有所不同。.

分裂的层次聚类与凝聚的层次聚类相反,采用自顶向下的策略,它首先将所有对象置于同一个簇中,然后逐渐细分为越来越小的簇,直到每个对象自成一簇,或者达到了某个终止条件。

本篇主要讨论凝聚的层次聚类。

第一步 ,将训练样本集中的每个数据点都当做一个聚类

第二步 ,计算每两个聚类之间的距离,将距离最近的或最相似的两个聚类进行合并,如同下图中的p1和p2、p5和p6

第三步 ,重复上述步骤,依旧计算每个聚类的距离,当然这次因为已经有聚合起来的簇了因此距离的计算方式有多种: 【单链】簇内的最近的点的距离、【全链】簇内的最远的点的距离、【组平均】簇的平均距离、簇的相似度等

第四步 ,直到得到的当前聚类数是合并前聚类数的10%,即90%的聚类都被合并了;当然还可以设置其他终止条件,这样设置是为了防止过度合并,此时需要几个簇,那么就可以用一条横线去截取分出的簇,如下图分出3类、4类、5类的横线截止

ps:距离在通常的情况下可以计算欧几里得距离,就是普通的直线距离,还可以计算余弦相似度

具体的动画效果可以参考视频,这是---- 传送门

1)距离和规则的相似度容易定义,限制少

2)不像kmeans,不需要预先制定聚类数

3)可以发现类的层次关系

1)计算复杂度太高

2)奇异值也能产生很大影响

3)由于根据距离来聚合数据,算法很可能聚类成链状

三种聚类方法:层次、K均值、密度

一、层次聚类

1)距离和相似系数

r语言中使用dist(x, method = "euclidean",diag = FALSE, upper = FALSE, p = 2) 来计算距离。其中x是样本矩阵或者数据框。method表示计算哪种距离。method的取值有:

euclidean                欧几里德距离,就是平方再开方。

maximum                切比雪夫距离

manhattan 绝对值距离

canberra Lance 距离

minkowski            明科夫斯基距离,使用时要指定p值

binary                    定性变量距离.

定性变量距离: 记m个项目里面的 0:0配对数为m0 ,1:1配对数为m1,不能配对数为m2,距离=m1/(m1+m2);

diag 为TRUE的时候给出对角线上的距离。upper为TURE的时候给出上三角矩阵上的值。

r语言中使用scale(x, center = TRUE, scale = TRUE) 对数据矩阵做中心化和标准化变换。

如只中心化 scale(x,scale=F) ,

r语言中使用sweep(x, MARGIN, STATS, FUN="-", ...) 对矩阵进行运算。MARGIN为1,表示行的方向上进行运算,为2表示列的方向上运算。STATS是运算的参数。FUN为运算函数,默认是减法。下面利用sweep对矩阵x进行极差标准化变换

?

1

2

3

center -sweep(x, 2, apply(x, 2, mean)) #在列的方向上减去均值。

R -apply(x, 2, max) -apply(x,2,min)   #算出极差,即列上的最大值-最小值

x_star -sweep(center, 2, R, "/")        #把减去均值后的矩阵在列的方向上除以极差向量

?

1

2

3

center -sweep(x, 2, apply(x, 2, min)) #极差正规化变换

R -apply(x, 2, max) -apply(x,2,min)

x_star -sweep(center, 2, R, "/")

有时候我们不是对样本进行分类,而是对变量进行分类。这时候,我们不计算距离,而是计算变量间的相似系数。常用的有夹角和相关系数。

r语言计算两向量的夹角余弦:

?

1

2

y -scale(x, center =F, scale =T)/sqrt(nrow(x)-1)

C -t(y) %*%y

相关系数用cor函数

2)层次聚类法

层次聚类法。先计算样本之间的距离。每次将距离最近的点合并到同一个类。然后,再计算类与类之间的距离,将距离最近的类合并为一个大类。不停的合并,直到合成了一个类。其中类与类的距离的计算方法有:最短距离法,最长距离法,中间距离法,类平均法等。比如最短距离法,将类与类的距离定义为类与类之间样本的最段距离。。。

r语言中使用hclust(d, method = "complete", members=NULL) 来进行层次聚类。

其中d为距离矩阵。

method表示类的合并方法,有:

single            最短距离法

complete        最长距离法

median        中间距离法

mcquitty        相似法

average        类平均法

centroid        重心法

ward            离差平方和法

?

1

2

3

4

5

6

7

8

 x -c(1,2,6,8,11)      #试用一下

 dim(x) -c(5,1)

 d -dist(x)

 hc1 -hclust(d,"single")

 plot(hc1)

 plot(hc1,hang=-1,type="tirangle")             #hang小于0时,树将从底部画起。

#type = c("rectangle", "triangle"),默认树形图是方形的。另一个是三角形。

#horiz  TRUE 表示竖着放,FALSE表示横着放。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

 z -scan()

1: 1.0000.8460.8050.8590.4730.3980.3010.382

9: 0.8461.0000.8810.8260.3760.3260.2770.277

17: 0.8050.8811.0000.8010.3800.3190.2370.345

25: 0.8590.8260.8011.0000.4360.3290.3270.365

33: 0.4730.3760.3800.4361.0000.7620.7300.629

41: 0.3980.3260.3190.3290.7621.0000.5830.577

49: 0.3010.2770.2370.3270.7300.5831.0000.539

57: 0.3820.4150.3450.3650.6290.5770.5391.000

65: 

Read 64items

 names

[1] "shengao""shoubi""shangzhi""xiazhi""tizhong"

[6] "jingwei""xiongwei""xiongkuang"

 r -matrix(z,nrow=8,dimnames=list(names,names))

 d -as.dist(1-r)

 hc -hclust(d)

 plot(hc)

然后可以用rect.hclust(tree, k = NULL, which = NULL, x = NULL, h = NULL,border = 2, cluster = NULL)来确定类的个数。 tree就是求出来的对象。k为分类的个数,h为类间距离的阈值。border是画出来的颜色,用来分类的。

?

1

2

3

 plot(hc)

 rect.hclust(hc,k=2)

 rect.hclust(hc,h=0.5)

result=cutree(model,k=3) 该函数可以用来提取每个样本的所属类别

二、动态聚类k-means

层次聚类,在类形成之后就不再改变。而且数据比较大的时候更占内存。

动态聚类,先抽几个点,把周围的点聚集起来。然后算每个类的重心或平均值什么的,以算出来的结果为分类点,不断的重复。直到分类的结果收敛为止。r语言中主要使用kmeans(x, centers, iter.max = 10, nstart = 1, algorithm  =c("Hartigan-Wong", "Lloyd","Forgy", "MacQueen"))来进行聚类。centers是初始类的个数或者初始类的中心。iter.max是最大迭代次数。nstart是当centers是数字的时候,随机集合的个数。algorithm是算法,默认是第一个。

?

使用knn包进行Kmean聚类分析

将数据集进行备份,将列newiris$Species置为空,将此数据集作为测试数据集

newiris - iris

newiris$Species - NULL

在数据集newiris上运行Kmean聚类分析, 将聚类结果保存在kc中。在kmean函数中,将需要生成聚类数设置为3

(kc - kmeans(newiris, 3)) 

K-means clustering with 3 clusters of sizes 38, 50, 62: K-means算法产生了3个聚类,大小分别为38,50,62. 

Cluster means: 每个聚类中各个列值生成的最终平均值

  Sepal.Length Sepal.Width Petal.Length Petal.Width

1     5.006000    3.428000     1.462000    0.246000

2     5.901613    2.748387     4.393548    1.433871

3     6.850000    3.073684     5.742105    2.071053

Clustering vector: 每行记录所属的聚类(2代表属于第二个聚类,1代表属于第一个聚类,3代表属于第三个聚类)

  [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

[37] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2

[73] 2 2 2 2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 2 3 3 3 3 2 3

[109] 3 3 3 3 3 2 2 3 3 3 3 2 3 2 3 2 3 3 2 2 3 3 3 3 3 2 3 3 3 3 2 3 3 3 2 3

[145] 3 3 2 3 3 2

Within cluster sum of squares by cluster: 每个聚类内部的距离平方和   

[1] 15.15100 39.82097 23.87947

(between_SS / total_SS =  88.4 %) 组间的距离平方和占了整体距离平方和的的88.4%,也就是说各个聚类间的距离做到了最大

Available components: 运行kmeans函数返回的对象所包含的各个组成部分

[1] "cluster"      "centers"      "totss"        "withinss"    

[5] "tot.withinss" "betweenss"    "size"  

("cluster"是一个整数向量,用于表示记录所属的聚类  

"centers"是一个矩阵,表示每聚类中各个变量的中心点

"totss"表示所生成聚类的总体距离平方和

"withinss"表示各个聚类组内的距离平方和

"tot.withinss"表示聚类组内的距离平方和总量

"betweenss"表示聚类组间的聚类平方和总量

"size"表示每个聚类组中成员的数量)

创建一个连续表,在三个聚类中分别统计各种花出现的次数

table(iris$Species, kc$cluster)           

              1  2  3

  setosa      0 50  0

  versicolor  2  0 48

  virginica  36  0 14

根据最后的聚类结果画出散点图,数据为结果集中的列"Sepal.Length"和"Sepal.Width",颜色为用1,2,3表示的缺省颜色

plot(newiris[c("Sepal.Length", "Sepal.Width")], col = kc$cluster)

在图上标出每个聚类的中心点

〉points(kc$centers[,c("Sepal.Length", "Sepal.Width")], col = 1:3, pch = 8, cex=2)

三、DBSCAN

动态聚类往往聚出来的类有点圆形或者椭圆形。基于密度扫描的算法能够解决这个问题。思路就是定一个距离半径,定最少有多少个点,然后把可以到达的点都连起来,判定为同类。在r中的实现

dbscan(data, eps, MinPts, scale, method, seeds, showplot, countmode)

其中eps是距离的半径,minpts是最少多少个点。 scale是否标准化(我猜) ,method 有三个值raw,dist,hybird,分别表示,数据是原始数据避免计算距离矩阵,数据就是距离矩阵,数据是原始数据但计算部分距离矩阵。showplot画不画图,0不画,1和2都画。countmode,可以填个向量,用来显示计算进度。用鸢尾花试一试

?

1

2

3

4

5

6

7

8

9

10

11

 install.packages("fpc", dependencies=T)

 library(fpc)

 newiris -iris[1:4]

 model -dbscan(newiris,1.5,5,scale=T,showplot=T,method="raw")# 画出来明显不对 把距离调小了一点

 model -dbscan(newiris,0.5,5,scale=T,showplot=T,method="raw")

 model #还是不太理想……

dbscan Pts=150MinPts=5eps=0.5

        012

border 34518

seed    04053

total  344571

层次聚类分析案例(一)

关于聚类分析的介绍,可参见本人之前的笔记: 聚类分析

案例一:世界银行样本数据集

创建世界银行的一个主要目标是对抗和消除贫困。在这个不断发展的世界中,世界银行持续的发展并精细地调整它的政策,已经帮助这个机构逐渐实现了消除贫困的目标。消除贫困的成果以下指标的改进衡量,这些指标包括健康、教育、卫生、基础设施以及其他需要用于改进穷人生活的服务。与此同时,发展成果必须保证以一种环保的、全社会的、经济可持续的方式达成。

准备工作

为了进行层次聚类,我们需要使用从世界银行收集的数据集。

第1步:收集和描述数据

该任务使用名为WBClust2013的数据集。该数据以标准格式存储在名为WBClust2013.csv的CSV格式的文件中。其有80行数据和14个变量。 点我获取数据

第一列Country为非数值型变量,其他列均为数值型变量。

第2步:探索数据

让我们探索数据并理解变量间的关系。我们通过导入名为WBClust2013.csv的CSV文件开始。存储数据到wbclust数据框中:

下一步输出wbclust数据框,head()函数返回wbclust数据框。wbclust数据框作为一个输入参数传入:

结果如下:

第3步:转换数据

中心化变量和创建z值是两个常见的用于归一化数据的数据分析手段。上面提到的数值型变量需要创建z值。scale()函数是一个通用的函数,其默认方法中心化并比例缩放一个数值化矩阵的列。数据框wbclust被传给该比例函数。只有数据框中数值化的变量会被缩放。结果存储在wbnorm数据框中。

结果如下:

所有的数据框都有rownames属性。rownames()函数用来获取或设置矩阵类变量的行名或列名。数据框wbclust以及第一列被传递给rownames()函数。

调用rownames(wbnorm)方法显示第一列的数值。结果如下:

第4步:训练并评估模型效果

下一步是训练模型。首先使用dist()函数计算距离矩阵。使用特定的距离度量方法计算数据矩阵行间的距离。使用的距离度量可以是欧式距离、最大距离、曼哈顿距离、堪培拉距离、二进制距离,或闵可夫斯基距离。这里的距离度量使用欧式距离。使用欧式距离计算两个向量间的距离为sqrt(sum((x_i-y_i)^2))。结果被存储在一个新的数据框dist1中。

下一步是使用Ward方法进行聚类。hclust()函数对一组不同的n个对象进行聚类分析。第一阶段,每个对象被指派给它自己的簇。之后每个阶段,算法迭代聚合两个最相似的簇。这个过程不断持续直到只剩一个簇。hclust()函数要求我们以距离矩阵的形式提供数据。dist1数据框被作为输入传入。默认使用全链接算法。此外还可以使用不同的聚集方法,包括ward.D、ward.D2、single、complete和average。

输入clust1命令可显示所使用的聚集方法,计算距离的方法,以及数据对象的数量。结果如下:

第5步:绘制模型

plot()函数是一个通用的绘制R语言对象的函数。这里plot()函数用来绘制系统树图:

结果如下:

rect.hclust()函数强调不同的簇,并在系统树图的枝干处绘制长方形。系统树图首先在某个等级上被剪切,之后在选定的枝干上绘制长方形。

clust1对象以及需要形成的簇的数量作为输入变量传入函数。

结果如下:

cuts()函数基于期望的簇数量或者切割高度将树中的元素切割到不同的簇中。这里,clust1对象以及需要形成的簇的数量作为输入变量传入函数。

结果如下:

得到每个簇的国家列表:

结果如下:

层次聚类

层次聚类算法分为:自底向上的AGNES算法和自上而下的DIANA算法

讲一下AGNES算法,没有最仔细,只有更仔细!!!

1,将每个数据点归为一类, 共得到N类, 每类仅包含一个数据点,类与类之间的距离就是它们所包含的数据点之间的距离。

2,找到最接近的两个类并合并成一类, 于是总的类数少了一个。

3,重新计算新的类与所有旧类之间的距离。

4,重复第2步和第3步, 直到最后达到某个要求以后停止(如当前簇类数为初始簇类数10%时停止)

下面给个具体步骤图,不喜勿喷。

①给定如下数据集:每个对象归为一类。

②找到所有数据中距离最近的两个点,如下图

③将该两点横纵坐标取均值得到新的簇类点(在这儿这两个点即分为一类)

④对新得到的数据继续遍历找出距离最小的两个点如下:

⑤继续合并得到新的簇类点。

1.层次聚类

层次聚类(hierarchical clustering) 基于簇间的相似度在不同层次上分析数据,从而形成树形的聚类结构,

层次聚类一般有两种划分策略:自底向上的聚合(agglomerative)策略和自顶向下的分拆(divisive)策略

将每个对象看作一类,计算两两之间的最小距离;

将距离最小的两个类合并成一个新类;

重新计算新类与所有类之间的距离;

重复1、2,直到所有类最后合并成一类。

层次聚类优点:(1)不需要知道有多少个簇

(2)对于距离度量标准的选择并不敏感

缺点:效率低

层次聚类c代码讲解的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于层次聚类算法基本原理、层次聚类c代码讲解的信息别忘了在本站进行查找喔。

版权说明:如非注明,本站文章均为 AH站长 原创,转载请注明出处和附带本文链接;

本文地址:http://ahzz.com.cn/post/12471.html


取消回复欢迎 发表评论:

分享到

温馨提示

下载成功了么?或者链接失效了?

联系我们反馈

立即下载