12.常用统计分析方法——聚类分析

news2024/9/26 5:14:01

目录

基础知识

实操

层次聚类

划分聚类

方法一:K均值聚类(最常见)

方法二:基于中心点的划分(PAM)

避免不存在的类


基础知识

概念

聚类分析是一种数据归约技术,旨在揭露一个数据集中观测值的子集。例如:对DNA微阵列数据进行聚类分析获得基因表达模型,从而帮助更好的理解疾病的原因;基于抑郁症病人的症状和人口学统计数据对病人进行聚类,试图得出抑郁症的亚型。

聚类的分类

1.层次聚类:每一个观测值自成一类,这些类每次两两合并,知道所有类被聚成一类。

常用的算法: 单联动(single linkage)、全联动(complete linkage)、平均联动(average linkage)、质心(centroid)和Ward 方法。

2.划分聚类:首先指定类的个数K,然后观测值随机分成K类,再重新形成聚合的类。

常用的算法:K均值(K-means)和围绕中心的划分(PAM)

聚类的步骤:

(1)选择合适的变量

选择你感觉可能对识别和理解数据中不同观测值分组有重要影响的变量

(2)缩放数据

分析中如果选择的变量变化范围很大,那么该变量对结果的影响也是最大的,这是不可取的。最常用的缩放数据的方法是将每个变量的标准化为均值为0标准差为1的变量。其他方法:每个变量被其最大值相除或该变量减去它的平均值并除以变量的平均绝对偏差。

三种方法代码:

df1 <- apply(mydata,2,function(x)((x-mean(x))/sd(x)))
df2 <- apply(mydata,2,function(x)(x/max(x)))
df3 <- apply(mydata,2,function(x)((x-mean(x))/mad(x)))

(3)寻找异常点

聚类分析对异常值非常敏感,可以通过outlier包中的函数筛选和删除异常单变量离群点。mvoutlier包中包含了能识别多元变量的离群点的函数。围绕中心的划分是一种对异常值稳健的聚类方法。

(4)计算距离

需要计算被聚类的实体之间的距离。两个观测值之间最常用的距离量度是欧几里得距离,其他可以选择的量度包括曼哈顿距离、兰氏距离、非对称二元距离、最大距离和闵可夫斯基距离。

(5)选择聚类算法

层次聚类对于小样本来说很实用(如150个观测值或更少),划分的方法能处理更大的数据量,但需要先确定聚类的个数。

(6)获得一种或多种聚类方法

(7)确定类的数目

常用的方法:尝试不同的类数并比较解的质量,NbClust包中NbClust()函数提供30个不同的指标来帮助进行选择。

(8)获得最终的聚类解决方案

(9)结果可视化

层次聚类的结果通常表示为一个树状图,划分聚类的结果通常利用可视化双变量聚类图来表示。

(10)解读类

(11)验证结果

实操

层次聚类

案例:flexclust包中营养数据nutrient作为层次聚类,以期望回答以下问题:

  • 基于五种营养标准的27种鱼,禽、肉的相同点和不同点是什么?
  • 是否有一种方法将这些食物分成若干个有意义的类?

载入数据:

#install.packages("flexclust")
data(nutrient,package = "flexclust")
head(nutrient)

计算距离:

欧几里得距离:

在图上是用点的 N 个属性构成两个 N 维向量并计算欧几里得距离。

其中,xi1 表示第一个点的第 i 维坐标,xi2 表示第二个点的第 i 维坐标。

欧几里得距离的取值范围是 [0,+∞],数值越小越相似。

dist()函数能用来计算矩阵或数据框的中所有行之间的距离,格式为dist(x,method=),x表示输入数据,默认欧几里得距离。

d <- dist(nutrient)
as.matrix(d)[1:4,1:4]

观测值之间的距离越大,说明异质性越大。观测值和它自己之间的距离为0。

注意:

欧几里得距离通常作为连续型数据的距离度量。但是如果存在其他类型的数据,则需要相异的替代措施。使用cluster包中的display()函数来获得包含任意二元(binary)、名义(nominal)、有序(ordinal)、连续(continunous)属性组合的相异矩阵。cluster包中agnes()函数可以进行层次聚类,pam()函数可以进行围绕中心点的划分的方法。

缩放数据:

从数据中可以看到energy这个变量变化范围比较大,对距离的影响大。所以缩放数据有利于平衡各变量的影响。

nutrient1 <- apply(nutrient,2,function(x)((x-mean(x))/sd(x)))
d1 <- dist(nutrient1)
as.matrix(d1)[1:4,1:4]

 将每个变量标准化为均值为0,标准差为1的变量。

层次聚类:

该案例为27个样本,5个变量,属于小样本数据。因此使用层次聚类

思想:每一个实例或观测值属于一类,聚类就是每一次把两类聚成新的一类,直到所有的类聚完成为一个单个类为止。

算法步骤:

  1. 定义每个观测值(行或单元)为一类;
  2. 计算每类和其他类的距离;
  3. 把距离最短的两类合并为一类,这样类的个数就减少一个;
  4. 重复步骤2和3,直到包含所有的观测值的类合并成为单个的类为止。
层次聚类方法
聚类方法两类之间的距离定义
单联动一个类中的点和另一个类中的点的最小距离
全联动一类中的点和另一个类中的点的最大距离
平均联动一类中的电荷另一类中的点的平均距离(UPGMA,非加权对组平均)
质心两类中质心(变量均值向量)之间的距离。对于单个的观测值来说,质心就是变量的值
Ward法两个类之间所有变量的方差分析的平方和

单联动倾向于发现细长的、雪茄型的类;全联动聚类倾向于发现大致相等的直径紧凑类,对异常值敏感。平均联动折中,倾向于把方差小的类聚合。ward法倾向于将少数观测值的类聚合在一起,倾向于产生跟观测值个数大致相等的类,对异常值敏感。质心法对异常值不是很敏感,但不如ward法和平均联动表现好。

层次聚类使用函数hclust()实现,hclust(d,method=),d是dist()函数产生的距离矩阵,method包括以上五种,"single", "complete", "average", "centroid", "ward"

fit.average <- hclust(d1,method = "average")
plot(fit.average,hang=-1,cex=0.8,main = "Average Linkage Clustering")

hang的意义是展示观测值标签,让他们挂在0的下面

高度表示该高度之间合并的判定值。对于平均联动来说,标准就是一类中点和其他类中点的距离平均值。

结果解读:

可以从图中看到食物之间的相似性/异质性,比如tuna canned和chicken canned是相似的,但都和clams canned有很大的不同。

确定类的数目:

NbClust包中提供了众多的指数来确定一个聚类分析中类的最佳数目。

library(NbClust)
nc <- NbClust(nutrient1,distance = "euclidean",
              min.nc = 2,max.nc = 15,
              method = "average")

需要做聚类的矩阵或数据框,distance指定距离测度,method指定聚类方法,min.nc和max.nc最小最大的聚类个数。他返回每一个聚类指数,建议聚类的最佳数目。

四个人赞同2,四个判定准则赞同聚类个数为3,4个赞同5,4个赞同15,选择其中一个解释其中意义。

#将聚类结果分成5类
clusters <- cutree(fit.average,k=5)
#查看每一类的数目。
table(cluster)
#原始数据每一类的变量特征
aggregate(nutrient,by=list(cluster=clusters),median)
#缩放数据每一类的变量特征
aggregate(nutrient1,by=list(cluster=clusters),median)

 获取每一类的中位数

绘制聚类图:

plot(fit.average,hang=-1,cex=.8,
     main = "Average Linkage Clustering\n5 Cluster Solution")
rect.hclust(fit.average,k=5)

 sardines canned自己形成一类,因为钙含量比其他组高了很多。beef heart也单独成为一类,因为富含蛋白质和铁。clams类的是低蛋白和高铁。

划分聚类

划分方法中,观测值被分为K组并根据给定的规则改组成为最有粘性的类。

案例:178种意大利葡萄酒样品的13种化学成分。这些意大利葡萄酒中样品能继续分成为更细的组吗?如果能,分多少组?他们的特征是什么?

方法一:K均值聚类(最常见)

思想:

  1. 随机选择K行,即K个中心点;
  2. 把每个数据点分配到离它最近的中心点;
  3. 重新计算每类中的点到该类中心点距离的平均值;
  4. 分配每个数据到它最近的中心点;
  5. 重复步骤3和4直到所有的观测点不再被分配,或是达到最大的迭代次数(R把10作为默认迭代次数)

优势:K均值聚类能处理比层次聚类更大的数据集。观测值不会永远被分到一类中。

格式:Kmeans(X,centers),X表示数值数据集(矩阵或数据框),centers是要提取的聚类数目。函数返回类的成员,类中心,平方和,和类大小

聚类方法对初始中心值的选择也非常敏感,nstart选项尝试多种初始配置并输出最好的一个。例如nstart=25会生成25个初始配置。

#install.packages("rattle")
data(wine,package = "rattle")
head(wine)

在数据集中,观测值代表三种葡萄酒的品种,Type则是表示三种不同类型。因为聚类,看看是否能识别出三种不同的类型。

缩放数据:

df <- scale(wine[-1])

变量值变化比较大,所以在聚类前进行标准化。

确定聚类的个数:

library(NbClust)
set.seed(1234)
devAskNewPage(ask=T)
nc <- NbClust(df,min.nc = 2,max.nc = 15,method = "kmeans")
table(nc$Best.nc[1,])

barplot(table(nc$Best.nc[1,]),
        xlab = "Number of Clusters",ylab = "Number of Criteria",
        main = "Number of Clusters Chosen by 26 Criteria")

在NbCluster包中26个指标中有19个指标建议使用类别为3的聚类方案。,并非30个指标都可以计算每个数据集。

进行K均值聚类分析

set.seed(1234)
fit.km <- kmeans(df,3,nstart = 25)
fit.km$size
fit.km$centers

第一个是每一个分类中的样本数,第二个是每一类中每个指标的标准化均值,如果计算原始均值,可以使用aggregate()函数

aggregate(wine[-1],by=list(cluster=fit.km$cluster),mean)

评价

K均值很好的反映了类型变量中真正的数据结构吗?交叉列联表和类别进行比较

#为了区别分类结果和实际的类型,重新赋值
wine$Type <- ifelse(wine$Type==1,"A",
                    ifelse(wine$Type==2,"B","C"))
table(wine$Type,fit.km$cluster)

量化类型变量与类之间的协议:flexclust包中兰德指数Rank index

library(flexclust)
randIndex(table(wine$Type,fit.km$cluster))

调整的兰德指数为两种划分提供了一种衡量两个分区之间的协定,即调整后机会的量度。它的变化范围是从-1(不同意)到1(完全同意)。

方法二:基于中心点的划分(PAM)

因为K-means聚类方法是基于均值的,所以它对异常值是敏感的。一个更稳健的方法是围绕中心点的划分(PAM)。K-means聚类一般使用欧几里得距离,而PAM可以使用任意的距离来计算。因此,PAM可以容纳混合数据类型,并且不仅限于连续变量。

PAM算法如下:

  1.  随机选择K个观测值(每个都称为中心点);
  2. 计算观测值到各个中心的距离/相异性;
  3. 把每个观测值分配到最近的中心点;
  4. 计算每个中心点到每个观测值的距离的总和(总成本);
  5. 选择一个该类中不是中心的点,并和中心点互换;
  6. 重新把每个点分配到距它最近的中心点;
  7. 再次计算总成本;
  8. 如果总成本比步骤(4)计算的总成本少,把新的点作为中心点;
  9. 重复步骤(5)~(8)直到中心点不再改变。

可以使用cluster包中的pam()函数使用基于中心点的划分方法。格式如下:

pam(x, k, metric="euclidean", stand=FALSE)

x表示数据矩阵或数据框,k表示聚类的个数,metric表示使用的相似性/相异性的度量,而stand是一个逻辑值,表示是否有变量应该在计算该指标之前被标准化。

library(cluster)
set.seed(1234)
fit.pam <- pam(wine[-1],k=3,stand = T)
fit.pam$medoids

这里得到的中心点是葡萄酒数据集中实际的观测值。

这里分别选择了36,107,175观测值来代表三类。

ct.pam <- table(wine$Type,fit.pam$clustering)
randIndex(ct.pam)

但是,PAM在本例中的表现不如K均值,函数randIndex()结果下降为了0.699。

避免不存在的类

聚类分析是一种旨在识别数据集子组的方法,并且 在此方面十分擅长。事实上,它甚至能发现不存在的类。 代码中提供一个对完全随机数据进行PAM聚类的例子。图展示了这个数据集的分布情况。其中并不存在聚类。

#install.packages("fMultivar")
library(fMultivar)
set.seed(1234)
df <- rnorm2d(1000,rho = 0.5)
df <- as.data.frame(df)
plot(df,main="Bivariate Normal Distribution with rho=0.5")

library(NbClust)
nc <- NbClust(df, min.nc=2, max.nc=15, method="kmeans")
dev.new()
barplot(table(nc$Best.n[1,]),
        xlab="Numer of Clusters", ylab="Number of Criteria",
        main  ="Number of Clusters Chosen by 26 Criteria")

 NbClust的结果都建议分类为2或3。利用PAM方法进行双聚类结果

library(ggplot2)
library(cluster)
fit <- pam(df,k=2)
df$clustering <- factor(fit$clustering)
ggplot(data=df,
       aes(x=V1,y=V2,
           color=clustering,shape=clustering))+
  geom_point()+
  ggtitle("Clustering of Bivariate Normal Data")

很明显划分是人为的。实际上在这里没有真实的类。NbClust包中的立方聚类规则(Cubic Cluster Criteria,CCC)往往可以帮助我们揭示不存在的结构。当CCC的值为负并且对于两类或是更多的类递减时,就是典型的单峰分布(如图)。

plot(nc$All.index[,4],type="o",ylab="CCC",
     xlab="Number of clusters",col="blue")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1408357.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

prometheus监控RabbitMQ策略

一般用官方的rabbitmq_exporter采取数据即可&#xff0c;然后在普米配置。但如果rabbitmq节点的队列数超过了5000&#xff0c;往往rabbitmq_exporter就会瘫痪&#xff0c;因为rabbitmq_exporter采集的信息太多&#xff0c;尤其是那些队列的细节&#xff0c;所以队列多了&#x…

vue3-深入组件-组件注册和props更多细节

组件注册 定义好的组件需要注册才能被使用。 注册方式有两种 全局注册 局部注册 全局注册 .component() 方法&#xff0c;让组件在当前 Vue 应用中全局可用。 在 main.ts 中 import ./assets/main.cssimport { createApp } from vue import { createPinia } from pinia i…

无人机航迹规划(五):七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划(提供MATLAB代码)

一、七种算法&#xff08;DBO、LO、SWO、COA、LSO、KOA、GRO&#xff09;简介 1、蜣螂优化算法DBO 蜣螂优化算法&#xff08;Dung beetle optimizer&#xff0c;DBO&#xff09;由Jiankai Xue和Bo Shen于2022年提出&#xff0c;该算法主要受蜣螂的滚球、跳舞、觅食、偷窃和繁…

10. UE5 RPG使用GameEffect创建血瓶修改角色属性

前面我们通过代码实现了UI显示角色的血量和蓝量&#xff0c;并实现了初始化和在数值变动时实时更新。为了测试方便&#xff0c;没有使用GameEffect去修改角色的属性&#xff0c;而是通过代码直接修改的数值。 对于GameEffect的基础&#xff0c;这里不再讲解&#xff0c;如果需要…

微机原理常考填空以及注意事项第(三)弹~

前面已经总结了200个常考题注意事项&#xff0c;可以翻阅查看。 以下仅个人总结的易错以及注意事项&#xff1a; 1&#xff0c;汇编语言源程序的基本格式&#xff1a; DATA SEGMENT;存放数据项的数据段 DATA ENDS EXTRA SEGMENT;存放数据项的附加段 EXTRA ENDS STACK1 SEGM…

Mybatis四大组件

一、Mybatis四大组件 SqlSessionFactoryBuild、SqlSessionFactory、SqlSession、Mapper。 二、SqlSession四大对象 Executor、StatementHandler、ParameterHandler、ResultSetHandler。 这里阐述一下上图的流程 Exeutor发起sql执行任务 1、先调用statementHandler中的pre…

输入某年某月某日,判断这一天是这一年的第几天?(Java)

思路&#xff1a; 1&#xff0c;分别定义三个变量来接收 年 月 日 2&#xff0c;累加已经过完的月份的天数 日期 3&#xff0c;二月份的天数要根据是否是闰年&#xff0c;随之改变 1 3 5 7 8 10 12 ---> 31天 4 6 9 11 ---> 30天 2 ---> 闰…

【bioinfo】收藏生信常用网址

文章目录 文件格式文档SAM/VCF工具手册bwa/samtools基因组统计学wikisam flag值查询序列反向互补TransVar 变异注释UCSC-blat在线比对常用数据库 NCBI/nsembl/HGNC论坛 biostars/SEQanswers查询文献影响因子假设检验查询生信软件查询在线可视化工具Proksee 文件格式文档SAM/VCF…

阿里云国外服务器价格购买与使用策略

阿里云国外服务器优惠活动「全球云服务器精选特惠」&#xff0c;国外服务器租用价格24元一个月起&#xff0c;免备案适合搭建网站&#xff0c;部署独立站等业务场景&#xff0c;阿里云服务器网aliyunfuwuqi.com分享阿里云国外服务器优惠活动&#xff1a; 全球云服务器精选特惠…

为什么JDK1.7的HashMap会出现扩容死链

为什么JDK1.7的HashMap会出现扩容死链&#xff1f; JDK1.7版本的HashMap在多线程的情况下扩容出现死循环&#xff08;扩容死链&#xff09;&#xff0c;根本原因是&#xff1a;HashMap在进行扩容时需要进行数据转移&#xff0c;jdk1.7的版本数据转移使用的是头插法&#xff08…

【每日一题】最大交换

文章目录 Tag题目来源解题思路方法一&#xff1a;暴力法方法二&#xff1a;贪心 写在最后 Tag 【暴力法】【贪心法】【数组】【2024-01-22】 题目来源 670. 最大交换 解题思路 本题的数据规模比较小&#xff0c;暴力法也可以通过。以下将会介绍暴力法和本题最优法。 方法一…

【AIGC】Diffusers:扩散模型的开发手册说明1

主要组件 最先进的扩散管道 diffusion pipelines&#xff0c;只需几行代码即可进行推理。可交替使用的各种噪声调度器 noise schedulers&#xff0c;用于平衡生成速度和质量。预训练模型 models&#xff0c;可作为构建模块&#xff0c;并与调度程序结合使用&#xff0c;来创建…

阿赵UE学习笔记——12、植物系统

阿赵UE学习笔记目录 大家好&#xff0c;我是阿赵。   继续学习虚幻引擎的用法。这次需要使用植物系统在地形上添加一些草和石头的装饰。 一、素材准备 之前介绍过&#xff0c;可以在Quixel上面获取免费的资源&#xff0c;所以我这里就下载了一些资源&#xff0c;有草和石头的…

基于springboot家政服务管理平台源码和论文

随着家政服务行业的不断发展&#xff0c;家政服务在现实生活中的使用和普及&#xff0c;家政服务行业成为近年内出现的一个新行业&#xff0c;并且能够成为大众广为认可和接受的行为和选择。设计家政服务管理平台的目的就是借助计算机让复杂的销售操作变简单&#xff0c;变高效…

代码随想录刷题笔记 DAY12 | 二叉树的理论基础 | 二叉树的三种递归遍历 | 二叉树的非递归遍历 | 二叉树的广度优先搜索

Day 12 01. 二叉树的理论基础 1.1 二叉树的种类 满二叉树&#xff1a;除了叶子节点以外&#xff0c;每个节点都有两个子节点&#xff0c;整个树是被完全填满的完全二叉树&#xff1a;除了底层以外&#xff0c;其他部分是满的&#xff0c;底部可以不是满的但是必须是从左到右连…

Java 设计者模式以及与Spring关系(六) 装饰和模版方法模式

简介: 本文是个系列一次会出两个设计者模式作用&#xff0c;如果有关联就三个&#xff0c;除此外还会讲解在spring中作用。 23设计者模式以及重点模式 我们都知道设计者模式有3类23种设计模式&#xff0c;标红是特别重要的设计者模式建议都会&#xff0c;而且熟读于心&#…

41.while语句

目录 一.什么是while语句 二.语法 三.执行流程图 四.举例 五.视频教程 一.什么是while语句 只要条件为真&#xff0c;while循环中的语句会一直重复执行。 二.语法 while&#xff08;表达式&#xff09;{//代码块 } 三.执行流程图 从流程图可以看出&#xff0c;while循环…

【JAVA语言-第14话】集合框架(一)——Collection集合,迭代器,增强for,泛型

目录 集合框架 1.1 概述 1.2 集合和数组的区别 1.3 Collection集合 1.3.1 概述 1.3.2 常用方法 1.4 迭代器 1.4.1 概述 1.4.2 常用方法 1.4.3 使用步骤 1.5 增强for循环 1.5.1 概述 1.5.2 使用 1.6 泛型 1.6.1 概述 1.6.2 使用泛型的利弊 1.6.2.1 好处 1…

基于TriDet的时序动作检测算法训练自己的slowfast数据

最近一直在研究时序动作识别和检测&#xff0c;也一直关注着目前的最新进展&#xff0c;有好的算法&#xff0c;我都会在我自己的数据集上运行看看&#xff0c;一方面是为自己累积相关算法&#xff0c;另一方面也是想看看&#xff0c;目前最新的算法是否可以应用到一些项目上。…

leetcode刷题(剑指offer) 240.搜索二维矩阵Ⅱ

240.搜索二维矩阵Ⅱ 编写一个高效的算法来搜索 *m* x *n* 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,4,7,11,15],[2,5,8,12,19],[3,…