R语言聚类分析

2023-11-19


本文首发于公众号:医学和生信笔记,完美观看体验请至公众号查看本文。



主要介绍使用R语言进行层次聚类、划分聚类(K均值聚类和PAM)。

系统聚类(层次聚类,Hierarchical clustering)

使用nutrient数据集进行演示,这个数据集包含不同食物中的营养物质含量。

# 没安装flexclust包的需要先安装
data(nutrient, package = "flexclust")
row.names(nutrient) <- tolower(row.names(nutrient))

dim(nutrient) # 27行5列
## [1] 27  5

psych::headTail(nutrient)
##                 energy protein fat calcium iron
## beef braised       340      20  28       9  2.6
## hamburger          245      21  17       9  2.7
## beef roast         420      15  39       7    2
## beef steak         375      19  32       9  2.6
## ...                ...     ... ...     ...  ...
## salmon canned      120      17   5     159  0.7
## sardines canned    180      22   9     367  2.5
## tuna canned        170      25   7       7  1.2
## shrimp canned      110      23   1      98  2.6

层次聚类在R语言中非常简单,通过hclust实现。

# 聚类前先进行标准化
nutrient.scaled <- scale(nutrient)
h.clust <- hclust(dist(nutrient.scaled,method = "euclidean"), # 计算距离有不同方法
                  method = "average" # 层次聚类有不同方法
                  )

下面就是画图,简单点可以直接用plot()

plot(h.clust,hang = -1,main = "层次聚类", sub="", 
     xlab="", cex.lab = 1.0, cex.axis = 1.0, cex.main = 2)

plot of chunk unnamed-chunk-3

关于更加精细化的细节修改,下次再介绍。或者可以借助其他R包快速绘制好看的聚类分析图形。
xxxxxxx
xxxxxxx
xxxxxxxx
xxxxxxxx

如何选择聚类的个数呢?

可以通过R包NbClust实现。

library(NbClust)

nc <- NbClust(nutrient.scaled, distance = "euclidean",
              min.nc = 2, # 最小聚类数
              max.nc = 10, # 最大聚类树
              method = "average"
              )

plot of chunk unnamed-chunk-4

## *** : The Hubert index is a graphical method of determining the number of clusters.
##                 In the plot of Hubert index, we seek a significant knee that corresponds to a 
##                 significant increase of the value of the measure i.e the significant peak in Hubert
##                 index second differences plot. 
## 

plot of chunk unnamed-chunk-4

## *** : The D index is a graphical method of determining the number of clusters. 
##                 In the plot of D index, we seek a significant knee (the significant peak in Dindex
##                 second differences plot) that corresponds to a significant increase of the value of
##                 the measure. 
##  
## ******************************************************************* 
## * Among all indices:                                                
## * 5 proposed 2 as the best number of clusters 
## * 5 proposed 3 as the best number of clusters 
## * 2 proposed 4 as the best number of clusters 
## * 4 proposed 5 as the best number of clusters 
## * 1 proposed 8 as the best number of clusters 
## * 1 proposed 9 as the best number of clusters 
## * 5 proposed 10 as the best number of clusters 
## 
##                    ***** Conclusion *****                            
##  
## * According to the majority rule, the best number of clusters is  2 
##  
##  
## *******************************************************************

输出日志里给出了评判准则以及最终结果:Hubert index和D index使用图形的方式判断最佳聚类个数,拐点明显的可视作最佳聚类个数。

它给出的结论是最佳聚类数是2。我们也可以通过条形图查看这些评判准则的具体数量。

barplot(table(nc$Best.nc[1,]),
        xlab = "聚类数目",
        ylab = "评判准则个数"
        )

plot of chunk unnamed-chunk-5

从条形图中可以看出,聚类数目为2,3,5,10时,评判准则个数最多,为5个,这里我们可以选择5个。

# 把聚类树划分为5类
cluster <- cutree(h.clust, k=5)

# 查看每一类有多少例
table(cluster)
## cluster
##  1  2  3  4  5 
##  7 16  1  2  1

把最终结果画出来:

plot(h.clust, hang = -1,main = "",xlab = "")
rect.hclust(h.clust, k=5) # 添加矩形,方便观察

plot of chunk unnamed-chunk-7

快速聚类(划分聚类,partitioning clustering)

K-means聚类

K-means聚类,K均值聚类,是快速聚类的一种。比层次聚类更适合大样本的数据。在R语言中可以通过kmeans()实现K均值聚类。

使用K均值聚类处理178种葡萄酒中13种化学成分的数据集。

data(wine, package = "rattle")
df <- scale(wine[,-1])

psych::headTail(df)
##     Alcohol Malic   Ash Alcalinity Magnesium Phenols Flavanoids Nonflavanoids
## 1      1.51 -0.56  0.23      -1.17      1.91    0.81       1.03         -0.66
## 2      0.25  -0.5 -0.83      -2.48      0.02    0.57       0.73         -0.82
## 3       0.2  0.02  1.11      -0.27      0.09    0.81       1.21          -0.5
## 4      1.69 -0.35  0.49      -0.81      0.93    2.48       1.46         -0.98
## ...     ...   ...   ...        ...       ...     ...        ...           ...
## 175    0.49  1.41  0.41       1.05      0.16   -0.79      -1.28          0.55
## 176    0.33  1.74 -0.39       0.15      1.42   -1.13      -1.34          0.55
## 177    0.21  0.23  0.01       0.15      1.42   -1.03      -1.35          1.35
## 178    1.39  1.58  1.36        1.5     -0.26   -0.39      -1.27          1.59
##     Proanthocyanins Color   Hue Dilution Proline
## 1              1.22  0.25  0.36     1.84    1.01
## 2             -0.54 -0.29   0.4     1.11    0.96
## 3              2.13  0.27  0.32     0.79    1.39
## 4              1.03  1.18 -0.43     1.18    2.33
## ...             ...   ...   ...      ...     ...
## 175           -0.32  0.97 -1.13    -1.48    0.01
## 176           -0.42  2.22 -1.61    -1.48    0.28
## 177           -0.23  1.83 -1.56     -1.4     0.3
## 178           -0.42  1.79 -1.52    -1.42   -0.59

进行K均值聚类时,需要在一开始就指定聚类的个数,我们也可以通过NbClust包实现这个过程。

library(NbClust)

set.seed(123)
nc <- NbClust(df, min.nc = 2, max.nc = 15, method = "kmeans")# 方法选择kmeans

plot of chunk unnamed-chunk-13

## *** : The Hubert index is a graphical method of determining the number of clusters.
##                 In the plot of Hubert index, we seek a significant knee that corresponds to a 
##                 significant increase of the value of the measure i.e the significant peak in Hubert
##                 index second differences plot. 
## 

plot of chunk unnamed-chunk-13

## *** : The D index is a graphical method of determining the number of clusters. 
##                 In the plot of D index, we seek a significant knee (the significant peak in Dindex
##                 second differences plot) that corresponds to a significant increase of the value of
##                 the measure. 
##  
## ******************************************************************* 
## * Among all indices:                                                
## * 2 proposed 2 as the best number of clusters 
## * 19 proposed 3 as the best number of clusters 
## * 1 proposed 14 as the best number of clusters 
## * 1 proposed 15 as the best number of clusters 
## 
##                    ***** Conclusion *****                            
##  
## * According to the majority rule, the best number of clusters is  3 
##  
##  
## *******************************************************************

结果中给出了划分依据以及最佳的聚类数目为3个,可以画图查看结果:

table(nc$Best.nc[1,])
## 
##  0  1  2  3 14 15 
##  2  1  2 19  1  1

barplot(table(nc$Best.nc[1,]),
        xlab = "聚类数目",
        ylab = "评判准则个数"
        )

plot of chunk unnamed-chunk-14

可以看到聚类数目为3是最佳的选择。

确定最佳聚类个数过程也可以通过非常好用的R包factoextra实现。

library(factoextra)
## Loading required package: ggplot2
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa

set.seed(123)
fviz_nbclust(df, kmeans, k.max = 15)

plot of chunk unnamed-chunk-15

这个结果给出的最佳聚类个数也是3个。

下面进行K均值聚类,聚类数目设为3.

set.seed(123)
fit.km <- kmeans(df, centers = 3, nstart = 25)
fit.km
## K-means clustering with 3 clusters of sizes 51, 62, 65
## 
## Cluster means:
##      Alcohol      Malic        Ash Alcalinity   Magnesium     Phenols
## 1  0.1644436  0.8690954  0.1863726  0.5228924 -0.07526047 -0.97657548
## 2  0.8328826 -0.3029551  0.3636801 -0.6084749  0.57596208  0.88274724
## 3 -0.9234669 -0.3929331 -0.4931257  0.1701220 -0.49032869 -0.07576891
##    Flavanoids Nonflavanoids Proanthocyanins      Color        Hue   Dilution
## 1 -1.21182921    0.72402116     -0.77751312  0.9388902 -1.1615122 -1.2887761
## 2  0.97506900   -0.56050853      0.57865427  0.1705823  0.4726504  0.7770551
## 3  0.02075402   -0.03343924      0.05810161 -0.8993770  0.4605046  0.2700025
##      Proline
## 1 -0.4059428
## 2  1.1220202
## 3 -0.7517257
## 
## Clustering vector:
##   [1] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
##  [38] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 1 3 3 3 3 3 3 3 3 3 3 3 2
##  [75] 3 3 3 3 3 3 3 3 3 1 3 3 3 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
## [112] 3 3 3 3 3 3 3 1 3 3 2 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
## [149] 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
## 
## Within cluster sum of squares by cluster:
## [1] 326.3537 385.6983 558.6971
##  (between_SS / total_SS =  44.8 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"

结果很详细,K均值聚类聚为3类,每一类数量分别是51,62,65。然后还给出了聚类中心,每一个观测分别属于哪一个类。

不管是哪一种聚类方法,factoextra配合factomineR都可以给出非常好看的可视化结果。

fviz_cluster(fit.km, data = df)

plot of chunk unnamed-chunk-17

有非常多的细节可以调整,大家在使用的时候可以自己尝试,和之前推文中介绍的PCA美化一样,也是支持ggplot2语法的。

fviz_cluster(fit.km, data = df, 
             ellipse = T, # 增加椭圆
             ellipse.type = "t", # 椭圆类型
             geom = "point", # 只显示点不要文字
             palette = "lancet", # 支持超多配色方案
             ggtheme = theme_bw() # 支持更换主题
             )

plot of chunk unnamed-chunk-18

围绕中心点的划分PAM

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

我们还是用葡萄酒数据进行演示。PAM聚类可以通过cluster包中的pam()实现。

library(cluster)

set.seed(123)
fit.pam <- pam(wine[-1,], k=3 # 聚为3类
               , stand = T # 聚类前进行标准化
               )
fit.pam
## Medoids:
##      ID Type Alcohol Malic  Ash Alcalinity Magnesium Phenols Flavanoids
## 36   35    1   13.48  1.81 2.41       20.5       100    2.70       2.98
## 107 106    2   12.25  1.73 2.12       19.0        80    1.65       2.03
## 149 148    3   13.32  3.24 2.38       21.5        92    1.93       0.76
##     Nonflavanoids Proanthocyanins Color  Hue Dilution Proline
## 36           0.26            1.86  5.10 1.04     3.47     920
## 107          0.37            1.63  3.40 1.00     3.17     510
## 149          0.45            1.25  8.42 0.55     1.62     650
## Clustering vector:
##   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21 
##   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1 
##  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41 
##   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1 
##  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60  61 
##   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   2   2 
##  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80  81 
##   2   2   1   2   1   2   2   2   1   2   1   2   1   1   2   2   2   2   1   2 
##  82  83  84  85  86  87  88  89  90  91  92  93  94  95  96  97  98  99 100 101 
##   2   2   3   2   2   2   2   2   2   2   2   2   2   2   1   1   2   1   2   2 
## 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 
##   2   2   2   2   2   2   2   2   1   2   2   2   2   2   2   2   2   2   2   2 
## 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 
##   1   2   2   2   2   2   2   2   2   3   3   3   3   3   3   3   3   3   3   3 
## 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 
##   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3 
## 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 
##   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3 
## Objective function:
##    build     swap 
## 3.537365 3.504175 
## 
## Available components:
##  [1] "medoids"    "id.med"     "clustering" "objective"  "isolation" 
##  [6] "clusinfo"   "silinfo"    "diss"       "call"       "data"

Medoids给出了中心点,用第35个观测代表第1类,第107个观测代表第2类,第149个观测代表第3类。Clustering vector给出了每一个观测分别属于哪一个类。结果可以画出来:

clusplot(fit.pam, main = "PAM cluster")

plot of chunk unnamed-chunk-20

同样也可以用factoextra包实现可视化。

fviz_cluster(fit.pam, 
             ellipse = T, # 增加椭圆
             ellipse.type = "t", # 椭圆类型
             geom = "point", # 只显示点不要文字
             palette = "aaas", # 支持超多配色方案
             ggtheme = theme_bw() # 支持更换主题
             )

plot of chunk unnamed-chunk-21

以后会给大家带来factoextrafactomineR包的详细介绍。


本文首发于公众号:医学和生信笔记,完美观看体验请至公众号查看本文。


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

R语言聚类分析 的相关文章

  • BrokenPipeError: [Errno 32] Broken pipe

    运行Pytorch tutorial代码报错 BrokenPipeError Errno 32 Broken pipe 源代码地址 Training a classifier CIFAR10 该问题的产生是由于windows下多线程的问题

随机推荐

  • QMap遍历(修改)

    方法一 STL风格的遍历器 个人较常用 直观易读 方便修改值 QMap
  • 解决 MDK keil 注册中出现 TOOLS.INI TOOLCHAIN NOT INSTALLED 办法

    MDK Keil 兼容 C51 Keil 我们的电脑有32位系统和64位系统 当keil出现这个错误时 可以按以下办法解决 有两种解决办法 第一种 同时安装MDK Keil 和 C51 Keil 有可能解决此问题 安装必须路径相同 第二种
  • leetcode-合并两个有序链表(详解)

    合并两个有序链表 前言 一 题链接 题意 题思路 题思路图解 题代码 总结 前言 路漫漫及修远兮 一 题链接 题意 将两个升序链表合并为一个新的 升序 链表并返回 新链表是通过拼接给定的两个链表的所有节点组成的 输入 l1 1 2 4 l2
  • 【车道线】TwinLiteNet 复现过程全纪录

    码字不易 喜欢的请点赞收藏 论文全文翻译 freespace TwinLiteNet An Efficient and Lightweight Model for Driveable Area and Lane Segmentation 莫
  • 虹软人脸识别 - ArcFace SDK介绍及使用注意事项

    很多朋友在开发人脸识别系统的时候 会遇到各种各样的问题 现在我们以安卓平台使用虹软的免费离线人脸识别SDK开发为例 给大家介绍一下如何开发一个带有图片的人脸检测 视频画面的人脸属性检测 人脸注册识别等功能的人脸识别系统 一 获取SDK 1
  • [rk3588]多种wifi模组兼容

    硬件部分 M 2接口 使用的wifi模组是PCIE接口的RTL8852BE和SDIO接口的AP6256 软件部分 M 2接口介绍 M 2接口是一种用于连接各种扩展设备的接口标准 它最初设计用于连接固态硬盘 SSD 但也广泛用于连接其他设备
  • spark hadoop环境及运行

    hadoop配置 在Ubuntu20 04里安装Hadoop详细步骤 图文 亲测成功 ubuntu20 04安装hadoop 菜鸡的学习之路的博客 CSDN博客 启动hadoop root ubuntu usr local hadoop s
  • 服务器处理发生异常:java.text.ParseException: Unparseable date

    测试上传报文的时候遇见报错 服务器处理发生异常 java text ParseException Unparseable date 2023 03 03 错误报文 实际需要的报文 错误原因 上传时间字段 与Date字段数据位数不匹配 Jav
  • python贝叶斯网络预测模型_高效灵活的概率建模方法基于Python

    前言 在今天给大家介绍一个研究工具 pomegranate 它比其他软件包更加灵活 更快 直观易用 并且可以在多线程中并行完成 The API 主要模型介绍一般混合模型 隐马尔可夫模型 贝叶斯网络 贝叶斯分类器 所有模型使用做多的方法 mo
  • 迪杰斯特拉(Dijkstra)算法求最短路径

    文章目录 一 最短路径 二 基本思想 三 步骤图解 步骤 S中存放的是已经求得的最短路径的终点的集合 v s集合包含其他点 i代表第i条最短路径 及可能路径走法 邻接矩阵表示弧 一 最短路径 从某顶点 源点 出发到另一顶点 目的地 的路径中
  • 【数据挖掘】数据挖掘比赛项目-kaggle泰坦尼克号

    数据挖掘实战项目 kaggle泰坦尼克号生还者预测 ing kaggle泰坦尼克号生还者预测 泰坦尼克号 从灾难中学习机器 kaggle网站连接 链接 https www kaggle com c titanic 一 实战项目描述 1 项目
  • uniapp判断h5运行环境(微信、pc、移动端)

    isOpenMode 平台 设备和操作系统 var system win false mac false xll false ipad false 检测平台 var p navigator platform system win p ind
  • 文件内存映射mmap解决大文件快速读写问题

    转自 http blog csdn net gulaizi article details 6325726 mmap函数主要用途有三个 1 将一个普通文件映射到内存中 通常在需要对文件进行频繁读写时使用 这样用内存读写取代I O读写 以获得
  • 5、Ubuntu20常用操作_进程管理&重定向和管道&常用命令&网络管理&构建web静态服务器nginx

    进程管理 进程的概念 大家比较熟悉 Windows 下的可执行文件 就是那些扩展名为exe的文件 大家知道 只需要鼠标双击这些程序 就可以运行了 程序运行起来后 我们把这个程序正在运行的 实例 称之为 进程 操作系统对每个进程都分配一个数字
  • 小程序添加本地图片

    写背景图片的时候用了本地的图片 报错说是不能直接使用本地图片 只能使用
  • 为什么振荡电路晶体旁要放22pF电容?

    振荡电路用于实时时钟RTC 对于这种振荡电路只能用32 768KHZ 的晶体 晶体被连接在OSC3 与OSC4 之间而且为了获得稳定的频率必须外加两个带外部电阻的电容以构成振荡电路 32 768KHZ的时钟晶振产生的振荡信号经过石英钟内部分
  • (ps2019)Photoshop 2019 最新破解版下载

    Photoshop CC 2019新增功能 下载地址点我 新功能介绍 https helpx adobe com cn photoshop using whats new html 经过改良设计的内容识别填充 借助 Adobe Sensei
  • 设计简单算数表达式语法分析器算法(LR来实现)

    include
  • 高通平台中gpio简单操作和调试

    做底层驱动免不了gpio打交道 所以对其操作和调试进行了一下简单的梳理 一 gpio的调试方法 在Linux下 通过sysfs 获取gpio状态 也可以操作gpio 1 获取gpio状态 cd sys kernel debug cat gp
  • R语言聚类分析

    本文首发于公众号 医学和生信笔记 完美观看体验请至公众号查看本文 文章目录 系统聚类 层次聚类 Hierarchical clustering 快速聚类 划分聚类 partitioning clustering K means聚类 围绕中心