划分聚类分析
K 均值聚类
最常见的划分方法是K均值聚类分析。从概念上讲,K均值算法如下:
- 选择K个中心点(随机选择K行);
- 把每个数据点分配到离它最近的中心点;
- 重新计算每类中的点到该类中心点距离的平均值(也就说,得到长度为p的均值向量,这
里的p是变量的个数); - 分配每个数据到它最近的中心点;
- 重复步骤(3)和步骤(4)直到所有的观测值不再被分配或是达到最大的迭代次数(R把10次
作为默认迭代次数)。
K均值聚类能处理比层次聚类更大的数据集。由于K均值聚类在开始要随机选择k个中心点,在每次调用函数时可能获得不同的方案。使用
set.seed() 函数可以保证结果是可复制的。此外,聚类方法对初始中心值的选择也很敏感。
kmeans() 函数有一个 nstart 选项尝试多种初始配置并输出最好的一个。
同样是聚类分析,上一次介绍的是层次聚类分法,这种方法输出的聚类树状图是其最大的优点,但是层次分析法的缺点就在于适合的样本数比较小,大概在150个左右。所以,当我们面临更大的数据时,划分聚类法就是更好的选择,虽然没有树状聚类图,却而代之的是圈型的聚类图。
- 代码:
setwd("E:\\Rwork")
library(rattle)
wine <- read.csv("wine.csv")
head(wine)
df <- wine[,-1]#或者wine$Type <- NULL
head(df)
df.scaled <- scale(df)
library(NbClust)
set.seed(1234)
devAskNewPage(ask = TRUE)#按回车输出图形
nc <- NbClust(df.scaled,min.nc = 2,max.nc = 15,method="kmeans")
table(nc$Best.n[1,])
*******************************************************************
* Among all indices:
* 4 proposed 2 as the best number of clusters
* 15 proposed 3 as the best number of clusters
* 1 proposed 10 as the best number of clusters
* 1 proposed 12 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
*******************************************************************
barplot(table(nc$Best.n[1,]),
xlab="Number of Clusters", ylab="Number of Criteria",
main="Number of Clusters Chosen by 26 Criteria")
- NbClust 包中的26种指标中有15种建议使用类别数为3的聚类方案
set.seed(1234)
fit.km<- kmeans(df.scaled,3,nstart = 25)#nstart=25默认推荐值
fit.km$size #查看具体分类数量
fit.km$centers#查看具体中心点
aggregate(df,by=list(culster=fit.km$cluster),mean)
ct.km<-table(wine$Type, fit.km$cluster) #查看分类概括
ct.km
1 2 3
1 59 0 0
2 3 65 3
3 0 0 48
- 用 flexclust 包中的兰德指数(Rand index)来量化类型变量和类之间的协议:
library(flexclust)
randIndex(ct.km)#-1是完全不同意,1是完全同意
ARI
0.897495
library(cluster)
par(mfrow=c(1,1),no.readonly = FALSE)#NbCluster将图形改为(1,2)的形式,这里将其改回(1,1)的形式
clusplot(df.scaled,fit.km$cluster,color = TRUE,shade = T,labels = 2,lines = 1)#输出聚类图
围绕中心点的划分
因为K均值聚类方法是基于均值的,所以它对异常值是敏感的。一个更稳健的方法是围绕中心点的划分(PAM)。与其用质心(变量均值向量)表示类,不如用一个最有代表性的观测值来表示(称为中心点)。K均值聚类一般使用欧几里得距离,而PAM可以使用任意的距离来计算。因此,PAM可以容纳混合数据类型,并且不仅限于连续变量。
PAM算法如下:
- 随机选择K个观测值(每个都称为中心点);
- 计算观测值到各个中心的距离/相异性;
- 把每个观测值分配到最近的中心点;
- 计算每个中心点到每个观测值的距离的总和(总成本);
- 选择一个该类中不是中心的点,并和中心点互换;
- 重新把每个点分配到距它最近的中心点;
- 再次计算总成本;
- 如果总成本比步骤(4)计算的总成本少,把新的点作为中心点;
- 重复步骤(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=TRUE)
> fit.pam$medoids
> clusplot(fit.pam, main="Bivariate Cluster Plot")
- 该数据中PAM法不如k-means法
ct.pam <- table(wine$Type, fit.pam$clustering)
> randIndex(ct.pam)
ARI
0.6994957