K-means聚类是一种无监督学习算法,用于将数据划分为不同的组或簇,使得同一簇内的数据点更相似,而不同簇之间的数据点更不同。它适用于数值型数据,可以在二维、三维乃至更高维度上运行。
K-means聚类算法步骤
示例数据
我们用如下数据集来演示 K 均值聚类的基本流程。假设我们有 10 个样本数据,每个样本有两个特征x和y:
# 创建数据集
data <- data.frame(
sample = c("A", "B", "C", "D", "E", "F", "G", "H", "I", "J"),
x = c(1.0, 1.5, 5.0, 8.0, 1.0, 9.0, 8.0, 10.0, 9.0, 9.0),
y = c(2.0, 1.8, 8.0, 8.0, 0.6, 11.0, 2.0, 2.0, 3.0, 5.0)
)
print(data)
步骤1:选择簇的数量K
步骤2:随机选择初始簇中心
初始中心点为 A(1.0, 2.0),C(5.0, 8.0) 和 G(8.0, 2.0)。
步骤3:计算距离并分配簇
# 计算欧几里得距离并分配到最近的簇中心
library(stats)
set.seed(123) # 设置随机种子
# 使用 K 均值聚类
kmeans_result <- kmeans(data[, c("x", "y")], centers = 3)
data$cluster <- kmeans_result$cluster
# 输出结果
print(data)
步骤4:重新计算簇中心
计算每个簇的新均值,并将其作为新的中心。例如,第一个簇内数据的均值为所有点的x坐标和y坐标的平均值,作为新的簇中心。
步骤5:重复步骤3和步骤4
继续迭代,直到簇分配不再发生变化或达到指定的迭代次数。最终分配如下:
评价聚类质量 - 方差与肘部法则
方差
每个簇的质量可以通过计算簇内点的方差来评价。方差越小,表示簇内数据点越接近,聚类效果越好。
肘部法则
通过绘制“簇数-K”与“簇内方差”图来选择最佳的 K。K 值增加,簇内方差减少,但减少速率逐渐下降,形成一个“肘部”。该点的 K 值即为理想的 K 值。
# 绘制肘部图
wss <- sapply(1:10, function(k){
kmeans(data[, c("x", "y")], centers = k, nstart = 10)$tot.withinss
})
plot(1:10, wss, type="b", pch = 19, xlab="簇数 K", ylab="簇内总方差 (WSS)")
K 均值聚类与层次聚类的区别