R语言实现聚类算法
1.聚类
层次聚类
在层次聚类中,起初每一个实例或观测值属于一类。聚类就是每一次把两类聚成新的一类,直到所有的类聚成 单个类为止,算法如下: (1) 定义每个观测值(行或单元)为一类; (2) 计算每类和其他各类的距离; (3) 把距离短 的两类合并成一类,这样类的个数就减少一个; (4) 重复步骤(2)和步骤(3),直到包含所有观测值的类合并成单个 的类为止。层次聚类方法:
单联动--一个类中的点和另一个类中的点的最小距离
全联动--一个类中的点和另一个类中的点的最大距离
平均联动--一个类中的点和另一个类中的点的平均距离(也称作UPGMA,即非加权对组平均)
质心--两类中质心(变量均值向量)之间的距离。对单个的观测值来说,质心就是变量的值
Ward法--两个类之间所有变量的方差分析的平方和
算法如下:
(1) 定义每个观测值(行或单元)为一类;
(2) 计算每类和其他各类的距离;
(3) 把距离短的两类合并成一类,这样类的个数就减少一个;
(4) 重复步骤(2)和步骤(3),直到包含所有观测值的类合并成单个的类为止。
划分聚类
将数据对象集划分为K个不重叠的子集,使得每个数据对象恰在一个子集中。例:K-means聚类
K均值算法如下:
(1) 选择K个中心点(随机选择K行);
(2) 把每个数据点分配到离它近的中心点;
(3) 重新计算每类中的点到该类中心点距离的平均值(也就说,得到长度为p的均值向量,这里的p是变量的个 数);
(4) 重新分配每个数据到离它最近的中心点;
(5) 重复步骤(3)和步骤(4)直到所有的观测值不再被分配或是达到大的迭代次数(R把10次作为默认迭代次数)
2.R语言实现
(1)层次聚类
层次聚类方法可以用hclust()函数来实现,格式是hclust(d, method=),其中d是通过 dist()函数产生的距离矩 阵,并且方法包括 "single"、"complete"、"average"、 "centroid"和"ward"。
①数据准备
在flexclust包中的营养数据集,它包括对27种肉、鱼和禽的营养物质的测量。
install.packages("flexclust")
data(nutrient, package = "flexclust")
dist()函数能用来计算矩阵或数据框中所有行(观测值)之间的距离。格式是dist(x, method=),这里的x表示 输入数据,并且默认为欧几里得距离。函数默认返回一个 下三角矩阵,但是as.matrix()函数可使用标准括号符号 得到距离。
#标准化数据、计算距离、平均联动聚类
nutrient.scaled <- scale(nutrient)
d <- dist(nutrient.scaled)
fit.average <- hclust(d, method = "average")
plot(fit.average, hang = -1, cex = .8, main = "Average Linkage Clustering")
#输出
上图提供了27种 食物之间的相似性/异质性的层次分析视图。tuna canned和chicken canned是相似 的,但是都和clams canned有很大的不同。
(2)划分聚类
在R中K均值的函数格式是kmeans(x,centers),这里x表示数值数据集(矩阵或数据框), centers是要提取的 聚类数目。函数返回类的成员、类中心、平方和(类内平方和、类间平方和、总平方和)和类大小。
两个关键问题:
①K值的选取
NbClust包提供了众多的指数来确定在一个聚类分析里类的最佳数目,NbClust()函数的输入包括需要做聚类的矩 阵或是数据框,使用的距离测度和聚类方法,并考虑 小和大聚类的个数来进行聚类。它返回每一个聚类指数,同 时输出建议聚类的最佳数目。
代码实现:
#NbClust确定聚类个数
library(NbClust)
set.seed(1234)
devAskNewPage(ask = TRUE)
nc <- NbClust(df, min.nc = 2, max.nc = 15, method = "kmeans")
table(nc$Best.n[1,])
barplot(table(nc$Best.n[1,]),
xlab = "Number of Clusters", ylab = "Number of Criteria",
main = "Number of Clusters Chosen by 26 Criteria")
另外,在K均值聚类中,类中总的平方值对聚类数量的曲线也可用来确定最佳聚类数目。
代码实现:
#wssplot确定聚类个数
wssplot <- function(data, nc=15, seed=1234){
wss <- (nrow(data)-1)*sum(apply(data, 2, var))
for(i in 2:nc){
set.seed(seed)
wss[i] <- sum(kmeans(data, centers = i)$withinss)
}
plot(1:nc, wss, type = "b",xlab = "Number of Clusters",
ylab = "Within groups sum of squares")
}
②初始中心点的选取
kmeans()函数有一个nstart选项尝试多种初始配置并输出好的一个。例如,加上nstart=25 会生成25个初始配 置。通常推荐使用这种方法。
#安装rattle包并加载数据
install.packages("rattle")
data(wine, package = "rattle")
head(wine)
> head(wine)
Type Alcohol Malic Ash Alcalinity Magnesium Phenols Flavanoids Nonflavanoids
1 1 14.23 1.71 2.43 15.6 127 2.80 3.06 0.28
2 1 13.20 1.78 2.14 11.2 100 2.65 2.76 0.26
3 1 13.16 2.36 2.67 18.6 101 2.80 3.24 0.30
4 1 14.37 1.95 2.50 16.8 113 3.85 3.49 0.24
5 1 13.24 2.59 2.87 21.0 118 2.80 2.69 0.39
6 1 14.20 1.76 2.45 15.2 112 3.27 3.39 0.34
Proanthocyanins Color Hue Dilution Proline
1 2.29 5.64 1.04 3.92 1065
2 1.28 4.38 1.05 3.40 1050
3 2.81 5.68 1.03 3.17 1185
4 2.18 7.80 0.86 3.45 1480
5 1.82 4.32 1.04 2.93 735
6 1.97 6.75 1.05 2.85 1450
#标准化数据
df <- scale(wine[-1])
#K值的选取
#wssplot确定聚类个数
wssplot <- function(data, nc=15, seed=1234){
wss <- (nrow(data)-1)*sum(apply(data, 2, var))
for(i in 2:nc){
set.seed(seed)
wss[i] <- sum(kmeans(data, centers = i)$withinss)
}
plot(1:nc, wss, type = "b",xlab = "Number of Clusters",
ylab = "Within groups sum of squares")
}
wssplot(df)
画出组内的平方和和提取的聚类个数的对比,从一类到三类下降的很快(之后下降的很慢),建议选用聚类个数为三的解决方案。
#NbClust确定聚类个数
library(NbClust)
set.seed(1234)
devAskNewPage(ask = TRUE)
nc <- NbClust(df, min.nc = 2, max.nc = 15, method = "kmeans")
table(nc$Best.n[1,])
barplot(table(nc$Best.n[1,]),
xlab = "Number of Clusters", ylab = "Number of Criteria",
main = "Number of Clusters Chosen by 26 Criteria")
#Kmeans聚类
set.seed(1234)
fit.km <- kmeans(df, 3, nstart = 25)
fit.km$size
fit.km$centers
aggregate(wine[-1], by = list(cluster = fit.km$cluster), mean)
#输出
> fit.km$centers
Alcohol Malic Ash Alcalinity Magnesium Phenols Flavanoids
1 0.8328826 -0.3029551 0.3636801 -0.6084749 0.57596208 0.88274724 0.97506900
2 -0.9234669 -0.3929331 -0.4931257 0.1701220 -0.49032869 -0.07576891 0.02075402
3 0.1644436 0.8690954 0.1863726 0.5228924 -0.07526047 -0.97657548 -1.21182921
Nonflavanoids Proanthocyanins Color Hue Dilution Proline
1 -0.56050853 0.57865427 0.1705823 0.4726504 0.7770551 1.1220202
2 -0.03343924 0.05810161 -0.8993770 0.4605046 0.2700025 -0.7517257
3 0.72402116 -0.77751312 0.9388902 -1.1615122 -1.2887761 -0.4059428
> aggregate(wine[-1], by = list(cluster = fit.km$cluster), mean)
cluster Alcohol Malic Ash Alcalinity Magnesium Phenols Flavanoids
1 1 13.67677 1.997903 2.466290 17.46290 107.96774 2.847581 3.0032258
2 2 12.25092 1.897385 2.231231 20.06308 92.73846 2.247692 2.0500000
3 3 13.13412 3.307255 2.417647 21.24118 98.66667 1.683922 0.8188235
Nonflavanoids Proanthocyanins Color Hue Dilution Proline
1 0.2920968 1.922097 5.453548 1.0654839 3.163387 1100.2258
2 0.3576923 1.624154 2.973077 1.0627077 2.803385 510.1692
3 0.4519608 1.145882 7.234706 0.6919608 1.696667 619.0588
上一篇: 模糊聚类(FCM)介绍及R语言实现
下一篇: R语言 Kmeans聚类法 主成分分析