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

目录

基础知识

实操

层次聚类

划分聚类

方法一: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.mzph.cn/news/642418.shtml

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

相关文章

Python基础之数据库操作

一、安装第三方库PyMySQL 1、在PyCharm中通过 【File】-【setting】-【Python Interpreter】搜索 PyMySQL进行安装 2、通过PyCharm中的 Terminal 命令行 输入: pip install PyMySQL 注&#xff1a;通过pip安装&#xff0c;可能会提示需要更新pip&#xff0c;这时可执行&#…

discuz论坛附件上传限制大小2MB

我遇到了这个问题&#xff0c;去修改了配置PHP.ini文件没有解决. 我把他变成2000M依旧没有用&#xff0c;然后我选择了用户组&#xff0c;附件部分。如图所示&#xff1a; 然后这个时候我还是没有好&#xff0c;我同事的却不限制大小了&#xff0c;我去清理缓存&#xff…

中文电码在历史关键时刻的作用

1. 中文电码&#xff1a;一段被遗忘的历史 中文电码是一种将汉字转换为电信号编码的方式&#xff0c;它的历史可以追溯到19世纪末。在当时&#xff0c;电报技术传入中国&#xff0c;为了实现汉字的电子传输&#xff0c;我国学者研究了一种将汉字转换为电码的方法。这种方法通过…

go语言(十七)----json

1、结构体转json package mainimport ("encoding/json""fmt" )type Movie struct{Title string json:"title"Year int json:"year"Price int json:"rmb"Actors []string json:"actors" }func main() {movie : Mo…

2024.1.23栈与队列总结篇

2024.1.23栈与队列总结篇 栈经典题目 栈在系统中的应用 如果还记得编译原理的话&#xff0c;编译器在词法分析的过程中处理括号、花括号等这个符号的逻辑&#xff0c;就是使用了栈这种数据结构。 再举个例子&#xff0c;linux系统中&#xff0c;cd这个进入目录的命令我们应该…

C#winform上位机开发学习笔记6-串口助手的断帧功能添加

1.功能描述 按照设定时间对接收数据进行断帧(换行) 应用于需要接收完整数据包的场景&#xff0c;例如下位机发送一包数据为1秒&#xff0c;每100ms发送一组数据 大部分用于接收十六进制数据时 2.代码部分 步骤1&#xff1a;添加计时器&#xff0c;设置默认时间为500ms 步骤…

Lingo数学建模基础

1.基本运算符 1.1算数运算符 1.2逻辑运算 #not# 否定操作数的逻辑值&#xff0c;一元运算符 #eq# 若两运算数相等&#xff0c;则为true,否则为false #ne# 若两运算数不相等&#xff0c;则为true,否则为false #gt# 若左边运算数严格大于右边&#xff0c;则为true,否则为…

了解云工作负载保护:技术和最佳实践

云工作负载是指云环境中的应用程序或存储元素&#xff0c;无论是公共云、私有云还是混合云。每个云工作负载都使用云的资源&#xff0c;包括计算、网络和存储。 云工作负载可以多种多样&#xff0c;例如运行应用程序、数据库或托管网站。它们可以是静态的或动态的&#xff0c;…

代码随想录刷题题Day41

刷题的第四十一天&#xff0c;希望自己能够不断坚持下去&#xff0c;迎来蜕变。&#x1f600;&#x1f600;&#x1f600; 刷题语言&#xff1a;C Day41 任务 ● 583. 两个字符串的删除操作 ● 72. 编辑距离 ● 编辑距离总结篇 1 两个字符串的删除操作 583. 两个字符串的删除…

UI自动化定位元素之js操作

前言 在UI自动化测试中&#xff0c;元素定位是一个至关重要的步骤。准确地定位到页面上的元素&#xff0c;是实现自动化测试的前提和保障。本文将介绍使用JavaScript进行元素定位的常见方法&#xff0c;并分析页面的组成&#xff0c;帮助读者更好地理解和应用元素定位技术。 页…

MongoDB系列之一文总结索引

概述 分类 索引的分类&#xff1a; 按照索引包含的字段数量&#xff0c;可分为单键索引&#xff08;单字段索引&#xff09;和组合索引&#xff08;联合索引、复合索引&#xff09;按照索引字段的类型&#xff0c;可以分为主键索引和非主键索引按照索引节点与物理记录的对应…

NQA网络质量分析

概念 网络质量分析是设备上集成网络测试功能,不仅可以实现对网络运行情况的准确测试,还可以输出统计信息,有效的节约成本。 NQA可以检测网络上运行的各种协议的性能,使运营商能够实时采集到各种网络运行指标。 例如:HTTP的总时延、TCP连接时延、DNS解析时延、文件传输速…

行测-判断:2.类比推理

行测-判断&#xff1a;2.类比推理 给出一组相关的词&#xff0c;要求通过观察分析&#xff0c;在备选答案中找出一组与之在逻辑关系上最为贴近或相似的词。 1. 语义关系★★ 1.1 近义关系&#xff0c;反义关系 C&#xff0c;反义词 B&#xff0c;BD 都是近义词&#xff0c;考…

如何用Python常用魔术方法阅读源码?13组代码轻松了解!

在看 python 源码的过程中我们会经常看到一些特殊方法&#xff0c;也就是双下划线方法。其实双下划线方法是特殊方法&#xff0c;是由 python 解释器提供的具有特殊意义的方法&#xff0c;主要是 python 源码程序员使用的&#xff0c;我们在开发中尽量不要使用双下方法&#xf…

Element中的el-input-number+SpringBoot+mysql

1、编写模板 <el-form ref"form" label-width"100px"><el-form-item label"商品id&#xff1a;"><el-input v-model"id" disabled></el-input></el-form-item><el-form-item label"商品名称&a…

java抽象工厂实战与总结

文章目录 一、工厂模式&#xff08;三种&#xff09;1.简单工厂模式1.1 概念&#xff1a;1.2 使用场景&#xff1a;1.3 模型图解&#xff1a;1.4 伪代码&#xff1a; 2.工厂方法模式2.1 概念&#xff1a;2.2 使用场景&#xff1a;2.3 模型图解&#xff1a;2.4 伪代码 3.抽象工厂…

用户反映在浏览器中使用AI工具 Copilot 遇到严重卡顿问题,微软官方给出初步解释

近日&#xff0c;多位用户反馈在使用Edge和Chrome浏览器中的Copilot时出现卡顿问题&#xff0c;甚至需要重启浏览器才能解决。对此&#xff0c;微软广告和网络服务部门CEO米哈伊尔帕拉欣表示&#xff0c;问题可能与Edge浏览器的“效率模式”有关。 微软中国官方网址链接&#x…

黑马——Java学生管理系统

一、学生管理系统 学生管理系统 需求&#xff1a; 采取控制台的方式去书写学生管理系统。 loop:while(true){ for(){ break loop;//给while循环取名loop&#xff0c;break loop;可以跳出while循环 } } 或者使用System.exit(0);停止虚拟机运行&#xff0c;相当于让所有代码停…

【表情识别阅读笔记】Towards Semi-Supervised Deep FER with An Adaptive Confidence Margin

论文名&#xff1a; Towards Semi-Supervised Deep Facial Expression Recognition with An Adaptive Confidence Margin 论文来源&#xff1a; CVPR 发表时间&#xff1a; 2022-04 研究背景&#xff1a; 对大量图片或视频进行手工标注表情是一件极其繁琐的事情&#xff0c;因此…

Python 自动化办公:一键批量生成 PPT

Stata and Python 数据分析 一、导读 在实际工作中&#xff0c;经常需要批量处理Office文件&#xff0c;比如需要制作一个几十页的PPT进行产品介绍时&#xff0c;一页一页地制作不仅麻烦而且格式可能不统一。那么有什么办法可以一键生成PPT呢&#xff1f;Python提供的pptx 包…