library(cluster)
library(mclust)

《数据挖掘:R语言实战》第7章

7.1 概述

这些算法本身无优劣,二最终运用于数据的效果存在好坏差异,这取决于数据使用者对于算法的选择是否恰当。

7.1.1 K-均值聚类

快速聚类方法,但对异常值或极端值敏感,稳定性差,因此较适合分布集中的大样本数据集。

7.1.2 K-中心点聚类

是针对K-均值算法易受极值影响这一缺点的改进算法。

在原理上的差异在于选择各类别中心点时不取样本均值点,而在类别内选取到其余样本距离之和最小的样本为中心点。

7.1.3 系谱聚类(层次聚类)

不需事先设定类别数k,每次迭代过程仅将距离最近的两个样本/簇聚为一类

7.1.4 密度聚类

DBSCAN是基于密度的聚类方法中最常用的代表算法之一,另外还有OPTICS算法,DENCLUE算法。

K-均值,K-中心点,系谱聚类这些基于距离的聚类算法,其优势在于弥补了它们只能发现“类圆形”聚类簇的缺陷,该类算法由于是基于“密度”来聚类的,可以再具有噪声的空间数据库中发现任意形状的簇。

DBSCAN算法将簇看做是空间数据中被低密度区域分隔开的“稠密区域”,即密度相连样本点的最大集合。

7.1.5 期望最大化聚类(EM算法)

它将数据集看做一个含有隐形变量的概率模型,并以实现模型最优化,即获取与数据本身性质最契合的聚类方式为目的,通过“反复估计”模型参数找出最优解,同时给出相应的最优类别数k。

而“反复估计”过程即是EM算法的精华所在,这一过程由E-step(Expectation)和M-step(Maximization)两个步骤较低进行来实现。

7.2 R中的实现

7.2.1 相关软件包

7.2.2 核心函数

kmeans

kmeans(x,centers,iter.max=10,nstart=1,algorithm=c("Hartigan-Wong","Lloyd","For-gy","MacQueen"))

pam

pam(x,k,diss=inherits(x,"dist"),metric="euclidean",medoids=NULL,stand=FALSE,cluster.only=FALSE)

dbscan

dbscan(data,eps,MinPts=5,scale=F,method=c("hybrid","raw","dist"),seeds=T,showplot=F,countmode=NULL)

hclust/cutree/rect.hclust

hclust(d,method="complete",members=NULL)

cutree(tree,k=NULL,h=NULL) 用于对hclust()函数的聚类结果进行剪枝,选择输出制定类别数的系谱聚类结果

rect.hclust()可以在plot()形成的系谱图中将制定类别中的样本分支用方框表示出来,十分有助于直观分析聚类结果。

rect.hclust(tree,k=NULL,which=NULL,x=NULL,h=NULL,border=2,cluster=NULL)

Mclust/mclustBIC/mclust2Dplot/densityMclust 函数

源于mclust软件包,Mclust()函数为进行EM聚类的核心函数

Mclust(data,G=NULL,modelNames=NULL,prior=NULL,control=emControl(),initialization=NULL,warn=FALSE,...)

mclustBIC()函数的参数设置与Mclust基本一致,用于获取数据集所对应的参数化高斯混合模型的BIC值,评价模型优劣,BIC值越高模型越优。

mclust2Dplot()可根据EM算法所生成的参数对二维数据制图。

densityMclust()函数利用Mclust()的聚类结果对数据集中的每个样本点进行密度估计。

7.2.3 数据集

countries <- read.csv("D:\\data\\contries.csv",header = F)
names(countries) <- c("country","birth","death")
countries <- countries[countries$country!="FRANCE",]
var <- countries$country
var <- as.character(var)
for(i in 1:68)
  row.names(countries)[i]=var[i]

7.3 应用案例

7.3.1 K-均值聚类

fit_km1 <- kmeans(countries[,-1],center=3)
print(fit_km1)

给出了给类别的组内平方和,1~3类逐渐升高,即第一类样本点见的差异性最小,第三类最大,且组间平方和占总平方和的76.4%。该值可用于与类别数取不同值时的聚类结果进行比较,从而找出最优聚类结果,该百分数越大表明组内差距越小、组间差距越大,即聚类效果越好。

fit_km1$totss
fit_km1$tot.withinss
fit_km1$betweenss

调节类别数参数center的取值,并通过前面所讨论的组间平方和占总平方和的百分比值(简称为“聚类优度”)来比较选择出最优类别数。

有68个样本,类别数从1~67取遍

result=rep(0,67)
for(k in 1:67){
  fit_km <- kmeans(countries[,-1],center=k)
  result[k] <- fit_km$betweenss/fit_km$totss
}
round(result,2)

在类别数小于10时,随着类别数增加聚类效果越来越好;类别数超过10后,聚类效果基本不再提高

plot(1:67,result,type="b",main="Choosing the Optimal Number of Cluster",
     xlab="number of cluster: 1 to 67",ylab="betweenss/totss")
points(10,result[10],pch=16)
legend(10,result[10],paste("(10,",sprintf("%.1f%%",result[10]*100),")",sep=""),bty="n",xjust=0.3,cex=0.8)

如果并非要求极高的聚类效果,取k=5或6即可,较小的类别数在后续的数据分析过程中往往是更为方便、有效的。

7.3.2 K-中心点聚类

fit_pam <- pam(countries[,-1],3) # 用k-Medoids算法对countries数据集做聚类
print(fit_pam)

Medoids输出中心样本点,可以作为该类的代表。这是K-均值算法无法获知的。

pam函数还可以回看一些信息。

head(fit_pam$data)
fit_pam$call

keep.data=FALSE时,数据集不再被保留

fit_pam1 <- pam(countries[,-1],3,keep.data = F)
fit_pam1$data

cluster.only设置为FALSE时,除个样本归属的类别,不再产生其他信息

fit_pam2 <- pam(countries[,-1],3,cluster.only = T)
print(fit_pam2)

将K-Means和K-Medoids算法在分3类情况下比较,一些国家不一致。

which(fit_km1$cluster==fit_pam$clustering)

7.3.3 系谱聚类

先使用dist()函数中默认的欧式距离来产生COuntries数据集的距离矩阵,再用hclust()函数展开系谱聚类,生成系谱图

fit_hc <- hclust(dist(countries[,-1]))
print(fit_hc)
plot(fit_hc)

剪枝可以控制输出类别个数或树高度

group_k3 <- cutree(fit_hc,k=3)
group_k3
table(group_k3)
group_h18 <- cutree(fit_hc,h=18)
group_h18
table(group_h18)
unique(group_k3)

查看各类别样本

sapply(unique(group_k3),function(g) countries$country[group_k3==g])

上述过程,通过cutree()的使用查看了指定类别数k或树高度h的聚类结果;

另外,还可以通过控制k和h来控制,使用rect.hclus()函数从系谱图中选择查看聚类结果

plot(fit_hc)
rect.hclust(fit_hc,k=4,border="light grey")
plot(fit_hc)
rect.hclust(fit_hc,k=3,border="dark grey")

用深灰色框出7分类的第2类和第6类的聚类结果

plot(fit_hc)
rect.hclust(fit_hc,k=7,which=c(2,6),border="darkgrey")

7.3.4 密度聚类

待补充

7.3.5 期望最大化聚类

fit_EM <- Mclust(countries[,-1])
summary(fit_EM)

根据BIC选择出的最佳模型类型为EII,最优类别数为4

summary(fit_EM,parameters = T)
plot(fit_EM)


ahorawzy/TFTSA documentation built on May 13, 2019, 12:18 p.m.