聚类分析是一种常用的无监督学习方法,是将所观测的事物或者指标进行分类的一种统计分析方法,其目的是通过辨认在某些特征上相似的事物,并将它们分成各种类别。R语言提供了多种聚类分析的方法和包。
方法 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
K-means | 计算效率高 | 需预设K值 | 球形数据分布 |
层次聚类 | 可视化直观 | 计算复杂度O(n²) | 小数据集/层级关系分析 |
DBSCAN | 发现任意形状 | 参数敏感 | 噪声数据/密度差异大 |
PAM | 对异常值鲁棒 | 计算成本高 | 中小规模数据 |
一、层次聚类
它是通过计算样本之间的距离来构建一个层次化的聚类结构,结果通常用树状图(dendrogram)来表示。
实现层次聚类的常用函数是R语言内置函数hclust(),还可以用cluter扩展包的agens()函数和flashClust扩展包的hclust()函数。
1、hclust()函数
下面用flexclust扩展包中的milk数据集进行讲解,此数据集包含了25种哺乳动物乳汁的成分数据:水分(water)、蛋白质(protein)、乳糖(lactose)、脂肪(fat)和灰分(ash)。
1.1 准备数据
library(flexclust)
# 第1步 准备数据:查看数据
data(milk)
milk
1.2 标准化数据
# 第2步 标准化数据
milk_data <- scale(milk, center=T, scale=T)
milk_data
1.3 计算距离
# 第3步 计算欧几里得距离;也可以选用其它方法
milk_dist <- dist(milk_data, method="euclidean")
milk_dist
1.4 层次聚类
使用平均距离法进行层次聚类
# 使用平均距离法进行层次聚类
fit_average <- hclust(milk_dist, method="averge")
fit_average
使用离差平和法进行层次聚类
# 使用平均距离法进行层次聚类
fit_average <- hclust(milk_dist, method="ward.D2")
fit_average
1.5 可视化结果
plot(fit_average, hang=-1, cex=1.2,main="平均距离层次聚类")
plot(fit_average, hang = -1, main = "层次聚类树状图", xlab = "样本", sub = "")
# 用矩形标出3个聚类
rect.hclust(fit_average, k = 3, border = 2:4)
1.6 切割聚类并评估
使用flexclust扩展包中的cuttree()函数将聚类结果分为3类(为什么分为3类,在此不细究,可上网查询方法)。
clusters <- cutree(fit_average, k=3)
# 可视化结果
plot(fit_average, hang=-1, cex=1, main="平均距离层次最终聚类")
rect.hclust(fit_average, k=3)
二、K-均值聚类
1、kmeans()函数
层次聚类是一次性的,即样本点一旦被划分道一个类中,就不会再被分配到其它的类中,而且当样本量达到数百甚至数千时,层次聚类会很难处理。
R语言中最常用的K-均值聚类函数时kmeans()函数。
1.1 数据准备
用R语言内置的iris数据集为例。首先需要将类别信息去除。
head(iris)
iris_data <- iris[, 1:4]
head(iris_data)
1.2 标准化数据
# 标准化数据,消除量纲的影响
iris_scaled <- scale(iris_data, center=T, scale=TRUE)
head(iris_scaled)
1.3 选择最佳K值
使用肘部法选择最佳的K值:通过计算不同聚类数k对应的总组内平方和(Total Within-Cluster Sum of Squares, WSS),找到WSS下降速度显著变缓的“肘部”点,该点对应的k即为最佳聚类数。
wss <- numeric(10)
for (k in 1:10) {kmeans_model <- kmeans(iris_scaled, centers = k, nstart = 25)wss[k] <- kmeans_model$tot.withinss
}
plot(1:10, wss, type = "b", pch = 19, main = "肘部法选择最佳k值", xlab = "聚类数k", ylab = "总组内平方和(WSS)")
从下面的截图可知,当k=3时,下降速度明显变缓。
1.4 K-均值聚类
centers:聚类数k。
nstart:随机初始中心点的次数(建议设为25以减少局部最优影响)。
iter.max:最大迭代次数(默认10)。
set.seed(123)
# 进行K-均值聚类
fit_means <- kmeans(iris_scaled, centers=3, iter.max=100, nstart=25)
1.5 可视化结果
library(factoextra)
fviz_cluster(fit_means, data = iris_scaled, palette = "jco", # 配色方案geom = "point", # 仅显示点ellipse.type = "norm", # 添加正态分布椭圆ggtheme = theme_minimal())