Advertisement

R语言--聚类分析

阅读量:

聚类分析是在样本个体的类别归属未知的情况下的分类方法,根据目的聚类分析可以分为:指标聚类,指标降维从而选择有代表性的指标;样品聚类,找出样品间的共性。
聚类算法:

  • K-均值聚类(K-Means)
  • K-中心点聚类(K-Medoids)
  • 密度聚类(Densit-based Spatial Clustering of Application with Noise,DBSCAN)
  • 系谱聚类(Hierarchical Clustering)
  • 期望最大化聚类(Expectation Maximization,EM)
  • 其他算法

K-均值聚类算法

算法原理

K-均值聚类算法,是一种迭代算法,其采用距离作为判断对象之间相似性的指标,距离越近即相似度越高。这里的距离是欧式距离:m维空间中两点之间的真实距离。如二维空间中点(x1,y1)和点(x2,y2)的欧式距离为: \sqrt{(x_{2}-x_{1})^{2}+(y_{2}-y_{1})^{2}} 。三维空间两点之间欧式距离为 \sqrt{(x_{2}-x_{1})^{2}+(y_{2}-y_{1})^{2}+(z_{2}-z_{1})^{2}} 。多维数据可以通过PCA(主成分分析)降维,或者直接计算欧式距离。
算法过程:

  1. 随机选取的K(簇个数,如游戏分为:顶级、高级、中级、低级,则k = 4)个样本作为起始中心点(簇)。
  2. 计算每个样本的点与各起始中心点的距离,将其余样本归入距离最近的簇,这就将所有样本完成了第一次分类。
  3. 确定当前类(簇)中样本坐标均值,作为新的起始中心点,然后计算各样本和各个新的起始中心点的距离,将样本按照距离归入距离最近的簇中。这是第二次分类。
  4. 确定新的起始中心点,把样本归类,依次循环迭代,直至所有样本归属类别不在变动(即最后确定了分类)。
    1614668-20190711164525371-1261516401.png
    上图中10个样本,想分为3类,首先随机选取了3个样本点(黑色标记样本:1,2,3)(图Ⅰ)。然后计算其余样本点与这三个样本点的距离,然后根据距离分类(图Ⅱ)。计算当前分类中样本坐标均值,作为新的起始中心点(图Ⅲ,黑色小方块),然后计算样本与各新的起始中心点的距离进行分类(图Ⅳ)。然后图Ⅳ分类中再计算各类中样本坐标均值作为新的起始中心点(图Ⅳ中的黑色小方块),计算各样本和各新的起始中心点的距离,进行分类(图Ⅴ),发现图Ⅳ和图Ⅴ相同,即分类不在变化,标志分类完成。
K-均值算法的优缺点

优点:

  • 简单、快速
  • 对处理大数据集,保持可伸缩性和高效性
  • 当簇接近高斯分布时,分类效果较好

缺点:

  • K值需事先给定,现实中难以估计
  • 对起始中心点的选择对聚类效果有较大影响,起始中心点难以确定
  • 算法需要不断迭代计算样本坐标均值作为新的起始中心点,对非常大的数据量比较费时
  • 对噪声和孤立点数据敏感,即当簇中包含异常点,将导致均值偏离严重
  • 不适用于发现大小差别很大的簇

R的实现

K-Means算法在R中的实现的核心函数为stats包中的kmeans()函数。

复制代码
 kmeans(x, centers, iter.max = 10, nstart = 1,

    
    algorithm = c("Hartigan-Wong", "Lloyd", "Forgy",
    
                  "MacQueen"), trace=FALSE)
    
 ## S3 method for class 'kmeans'
    
 fitted(object, method = c("centers", "classes"), ...)
    
    
    
    
  • x:待进行聚类分析的数据集
    • centers:预设分类(簇)数目,即K值
    • iter.max:最大迭代次数,默认值为10
    • nstart:选择随机起始中心点的次数,默认值为1
    • algorithm:该参数提供了四种参数选择,默认为Hartigan-Wong
    • trace:该参数仅用于默认算法(Hartigan-Wong),如果设定为正(或TRUE),则生成算法进程相关的进程信息,如果数据量大的可能生成会生成跟多的进程信息。

实例

以iris数据集进行聚类分析,iris数据集:安德森鸢尾花卉数据集,包含150个样本(行),每个样本的5中特征向量(花萼长度,花萼宽度,花瓣程度,花瓣宽度,品种)。
1614668-20190712105238440-1080754441.png
观察数据发现,有三个品种,每个品种为50个样本数据

复制代码
    kc <- kmeans(x = iris[1:4],centers = 3)     # 以前四个特征数据进行聚类,分成3类。
    

1614668-20190712111233670-585560669.png
分成3类,第一类:38个样本;第二类:62个样本;第三类:50个样本。根据源数据可知,只有一类分类完全正确,有12个样本分类错误。

复制代码
 fitted(kc)    # 查看最终分类后,各类的样本坐标均值,即该类的起始中心点

    
 # 结果:
    
  Sepal.Length Sepal.Width Petal.Length Petal.Width
    
 1     5.006000    3.428000     1.462000    0.246000
    
 3     5.901613    2.748387     4.393548    1.433871
    
 2     6.850000    3.073684     5.742105    2.071053
    
    
    
    

clustering vector:每个样本被分为哪一类
within cluster sum of squares by cluster:各类别的组内平方和(统计学),即各类别样本点之间的差异性。且组内平方和/总平方和=88.4%,这个比值可用于与K取不同数值时进行比较,从而找出最优聚类结果,该百分数越大表明组内差距越小、组间差距越大,即聚类效果越好

复制代码
 table(iris$Species,kc$cluster)    # table函数:通过交叉分类构建因子水平频数列联表。

    
 # 结果:
    
           1  2  3
    
   setosa     50  0  0
    
   versicolor  0  2 48
    
   virginica   0 36 14
    
    
    
    

列联表可以比较直观的看出分类的具体情况,从上面可以看出:setosa50个样本完全分类正确;把14个virginica样本分为versicolor,同时把2个versicolor分为virginica

可视化
复制代码
 ggplot(iris,aes(x=Sepal.Length,y=Sepal.Width, shape = Species, colour = kc$cluster))+

    
   geom_point(size = 5)+
    
   scale_shape_manual(values = c(1,2,3))   
    
    
    
    

1614668-20190712162042944-1409092347.png
因为每个species中有的样本的数据相同,所以图形上的点要少于50个,因为点重复了。

K-中心点算法聚类

算法原理

K-中心点聚类算法是针对K-均值聚类算法易受到极值影响这一缺点的改进算法。其原理与K-均值算法十分相近,区别在于选择各类起始中心点时,不取样本均值点,而在类别内选取到其他样本距离之和最小的样本为新的起始中心点。
算法过程:

  1. 随机选取K个样本作为起始中心点
  2. 计算其余样本与各起始中心点的距离,按照最近距离,将样本归入到最近的起始中心点(簇)
  3. 对各个簇中样本,选取到当前簇中其他样本距离之和最小的样本作为新的起始中心点,然后计算所有样本与各起始中心点的距离,按照最近距离,将样本归入到最近的起始中心点(簇)。
  4. 确定新的起始中心点,归类,如此迭代下去,直到所有样本归类不再变动

R的实现

k-中心点算法的R实现可以通过R中cluster包中的pam()函数以及clara()函数,这两个函数都需要先指定K值(聚类数),另外还有fpc包中的pamk()函数,该函数不需要不需要事先指定k值。

复制代码
 pam(x, k, diss = inherits(x, "dist"),

    
     metric = c("euclidean", "manhattan"), 
    
     medoids = NULL, stand = FALSE, cluster.only = FALSE,
    
     do.swap = TRUE,
    
     keep.diss = !diss && !cluster.only && n < 100,
    
     keep.data = !diss && !cluster.only,
    
     pamonce = FALSE, trace.lev = 0)
    
    
    
    
  • x:待聚类分析的数据
    • k:预设分类数目
    • diss:逻辑特征,当
    • metric:用于选择样本间距离计算方式,有"euclidean"和"manhattan"两种选择
    • medoids:由软件选择初始中心点的样本,也可以通过k构建一个样本向量,即指定哪几个样本作为最初的起始中心点
    • stand:表示对数据进行聚类前是否对数据进行标准化
    • cluster.only:是否仅获取各样本所归属的类别这一项聚类结果,若为TRUE,则聚类过程效率更高
    • keep.data:是否在聚类结果中保留数据集
复制代码
 >pam(iris[1:4],3)

    
 Medoids:
    
       ID Sepal.Length Sepal.Width Petal.Length Petal.Width
    
 [1,]   8          5.0         3.4          1.5         0.2
    
 [2,]  79          6.0         2.9          4.5         1.5
    
 [3,] 113          6.8         3.0          5.5         2.1
    
 Clustering vector:
    
   [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 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 2
    
  [74] 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 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 3 3
    
 [147] 2 3 3 2
    
 Objective function:
    
     build      swap 
    
 0.6709391 0.6542077 
    
  
    
 Available components:
    
  [1] "medoids"    "id.med"     "clustering" "objective"  "isolation"  "clusinfo"   "silinfo"    "diss"       "call"       "data"      
    
    
    
    

Medoids:聚类结束时,各类别的中心点样本
Objective function:目标方程项

复制代码
 table(iris$Species,c$clustering)    # 列联表

    
 # 结果:
    
           1  2  3
    
   setosa     50  0  0
    
   versicolor  0 48  2
    
   virginica   0 14 36
    
    
    
    

系谱聚类

算法原理

系谱聚类(hierarchical clustering,HC)又称为系统聚类,或分层聚类。其聚类过程是将相似的归为一个类别,而相似性的定义往往通过距离(或相关系数)进行数量化。通过距离数量化过程中我们需要注意数据的标准化和中心化,使得数据各个特征在聚类中的作用是相同的。
聚类步骤如下:

  1. 最初将各样品各自视为1个类,即多少样本为多少个类。然后计算类间相似性系数矩阵,矩阵元素为样品间的相似性系数。相似性系数矩阵为对称矩阵。
  2. 将相似性系数最大(距离最小或相关系数最大)的两类,合并成新类。计算各新类之间的相似性系数。
  3. 计算类间相似性系数,将相似性系数最大的两类合并成新类,如此迭代,直至所有样本被合并为一类

R的实现

系谱聚类在R中主要通过dist()函数和hclust()函数实现。
dist()函数相当于聚类步骤中的第一步,即将每个样品之间的相似性系数矩阵。
hclust()函数相当于第二步,即计算类(每个类中至少包含两个样本点)间相似性系数,不断迭代合并新类,直至所有样本合并为一类

复制代码
    dist(x, method = "euclidean", diag = FALSE, upper = FALSE, p = 2)
    
  • x:样本矩阵或数据框
    • method:计算相关系数的方法,包括:
      • euclidean:欧式距离,即向量模长,如点 (x_{1},p_{1}) 和点 (x_{2},p_{2}) ,则欧式距离为: \sqrt{(x_{1}-x_{2})+(y_{1}-y_{2})}
      • maximum:切比雪夫距离,坐标数值差的最大值,如点 和点 ,则欧式距离为: max(|x_{1}-x_{2}|,|y_{1}-y_{2}|)
      • manhattan:绝对距离
      • canberra:Lance距离
      • binary:定性变量距离
      • minkowski:明可夫斯基距离
      • 其他距离
    • diag:逻辑值,为TRUE给出对角线上距离
    • upper:逻辑值,为TRUE时,给出上三角矩阵的值
    • p:明可夫斯基距离计算中的一个参数,当P=1时,就是曼哈顿距离;当p=2时,就是欧式距离
复制代码
 # 系统聚类

    
 hclust(d, method = "complete", members = NULL)
    
  
    
 # 系统聚类谱系图
    
 plot(x, labels = NULL, hang = 0.1, check = TRUE,
    
      axes = TRUE, frame.plot = FALSE, ann = TRUE,
    
      main = "Cluster Dendrogram",
    
      sub = NULL, xlab = NULL, ylab = "Height", ...)
    
    
    
    
  • d:通过dist()函数计算得到的相关系数矩阵
    • method:类(没一类至少包含两个样品点)与类之间距离的计算方法
      • ward.D:离差平方和法,方差分析思想,即类内离差平方和最小,类间平方和最大
      • single:最短距离法,即一个类中的样品点和另一个类中的样品点之间的最小距离
      • complete:最长距离法,即一个类中的样品点和另一个类中的样品点之间的最大距离
      • average:类平均法
      • mcquitty:相似分析法,
      • median:中间距离法,即一个类中的样品点和另一个类中的样品点之间的平均距离
      • centroid:重心法

实例

复制代码
 hc <- hclust(dist(iris[1:4]))

    
 plot(hc,cex = 0.55)
    
    
    
    
1614668-20190714180405540-1463984233.png

另外还可以通过rect.hclust()函数,和cutree()函数,以及factoextra包中的fviz_dend()函数对聚类树进行分组。
rect.hclust()函数,首先将聚类树形图根据k或h进行分割,然后在每一类周围绘制矩形,突出显示相应的集群。
cutree函数,通过指定的分组数目(k)或者高度(h)分割聚类树形图,也就是这个相当于cluster vector

复制代码
 hc <- hclust(dist(iris[1:4]))

    
 plot(hc,cex = 0.55)
    
 rect.hclust(hc,k = 3)
    
 cu <- cutree(hc,k =3)    # 每个样本的分类情况
    
    
    
    

1614668-20190714194823621-516607409.png
fviz_dend()函数,使用R基本绘图或者ggplot2可以轻松绘制漂亮的树形图。

复制代码
    fviz_dend(hc,k = 3,cex = 0.55,k_colors = c("#2E9FDF","#E7B800", "#FC4E07"),color_labels_by_k = TRUE,rect = TRUE)
    
1614668-20190714195741375-139801656.png

密度聚类

算法原理

DBSCAN算法是密度聚类中的经典算法,该类算法基于密度来聚类,可以在具有噪声的数据空间中发现任意形状的簇。簇看作是数据空间中被低密度区域(样本点少、稀疏)分隔开的稠密区域(样本点集中、密集)。主要是范围和密度两个参数,即选择一个样本点以r构成的圆内(邻域)包含minPts个样本(密度阈值),则该样本点称为核心对象,同时便构建了一个簇。接着就是簇的扩展,即遍历该簇的每个样本点,判断每个样本点是否为核心样本点,如果样本点为核心对象,则将该核心对象并入该簇。最后看构建该类的过程中,所有的邻域范围,范围内的核心样本归为一个类,非核心样本归为另一个类。
以一下列子作说明:
1614668-20190715111028347-1336408868.png

  1. 图Ⅰ,从待分类数据集中选择一个样本点——黑色点1,以半径E构建邻域,minPts为3,即黑色点1为圆心,E为半径构成的圆(邻域)内至少包含3个样本点(灰色点),则认为黑色点1为核心对象
  2. 确定1为核心对象后,则点1为一个簇(类),然后遍历点1邻域内的样本点(3个灰色的样本点),判断其是否为核心对象,如果是核心对象,则并入点簇类;如图Ⅱ中的黑色点2,判定黑色点2为核心对象(邻域内包含3个点),则点2与点1是同类。
  3. 扩展:如图Ⅲ,样本点3,它是点1邻域内的样本点,对其进行判定,它包含4个样本点,是核心对象,所以归入点1的类中;然后对其邻域内其余样本点进行判定,也就是说其邻域内的样本点为核心对象,则与其为同一类,这样不断迭代下去,直至不能该类无法扩展。
  4. 一直迭代下去,直至该类无法在扩展,如图Ⅶ、Ⅷ。此时看构建这个类过程所有的邻域范围,如图Ⅶ中的虚线,所有虚线内区域均为构建该类过程的邻域范围;然后确定范围内所有样本,如图Ⅷ,即黑色圈内样本,核心样本归为一类,非核心样本(边界点)归为另一类。
    5.这样一个类的建立和拓展便完成了(该类已经无法扩展了),然后接着在剩余未归类的样本中,继续按照以上的步骤,将其他样本继续分类。在分类过程中,邻域内不包含样本的点(即与其他样本点的距离大于E半径),如图Ⅸ中的 \bigotimes 的两个样本,这些样本点未噪声点(异常值)。这样就将样本分为4类,和两个异常值了。

R的实现

复制代码
 dbscan(data, eps, MinPts = 5, scale = FALSE, method = c("hybrid", "raw",

    
     "dist"), seeds = TRUE, showplot = FALSE, countmode = NULL)
    
   ## S3 method for class 'dbscan'
    
 print(x, ...)
    
   ## S3 method for class 'dbscan'
    
 plot(x, data, ...)
    
   ## S3 method for class 'dbscan'
    
 predict(object, data, newdata = NULL,
    
 predict.max=1000, ...)
    
    
    
    
  • data:待聚类数据集或距离矩阵
    • eps:划分邻域的半径
    • Minpts:最小密度阈值
    • scale:是否在聚类前对数据进行标准化
    • method:hybrid表示data是距离矩阵;raw表示data是原始数据集;dist表示data是原始数据集,但是计算局部聚类矩阵。
    • showplot:是否输出聚类结果示意图。0:不绘图;1:每次迭代都绘图;2:仅对子迭代过程绘图

实例

复制代码
 library(fpc)

    
 library(factoextra)
    
 data("multishapes")
    
 data <- multishapes[,1:2]
    
 d1 <- dbscan(data,eps = 0.15,MinPts = 5)
    
 fviz_cluster(d1,data,stand = FALSE,frame = FALSE,geom = "point")
    
    
    
    

1614668-20190716144555704-958414136.png
密度聚类有个问题就是,无法确定eps和Minpts的合适取值,有一种是dist()函数计算,查看大多数样本间的距离在什么范围,在以此距离作为参考来设定

期望最大化聚类

转载于:https://www.cnblogs.com/sakura-d/p/11170901.html

全部评论 (0)

还没有任何评论哟~