缘由
艺多不压身
碎碎念
我们继续飞行在云层和雾气之间,飞行在一个无光无影的空洞世界中。 ——《风沙星辰》
Ref
K-means clustering with tidy data principles – tidymodels
代码
利用kmeans 选择聚类数
library(tidymodels)
library(ggplot2)
#️⃣ Step 1 构造模拟数据
# 目的:生成三类点,便于测试聚类算法
# 优点:数据结构已知,能验证算法效果
set.seed(27)
centers <- tibble(
cluster = factor(1:3),
num_points = c(100, 150, 50), # 每簇点数
x1 = c(5, 0, -3), # x1中心
x2 = c(-1, 1, -2) # x2中心
)
#️⃣ Step 2 生成带标签的数据
# 目的:为每个簇中心生成正态分布点
# 优点:既有真实标签又保留随机性
labelled_points <-
centers %>%
mutate(
x1 = map2(num_points, x1, function(n, center) rnorm(n, center)),
x2 = map2(num_points, x2, function(n, center) rnorm(n, center))
) %>%
select(-num_points) %>%
unnest(cols = c(x1, x2))
# 可视化标签数据
ggplot(labelled_points, aes(x1, x2, color = cluster)) +
geom_point(alpha = 0.3)
#️⃣ Step 3 运行 K-means 聚类
# 目的:对无标签数据进行聚类
# 优点:检验算法能否恢复原簇结构
points <- labelled_points %>% select(-cluster)
kclust <- kmeans(points, centers = 3)
kclust
# 输出统计信息
augment(kclust, points)
tidy(kclust)
glance(kclust)
#️⃣ Step 4 探索不同聚类数
# 目的:尝试 k=1 到 9,观察聚类效果
# 优点:帮助确定合适的簇数
kclusts <-
tibble(k = 1:9) %>%
mutate(
kclust = map(k, ~kmeans(points, .x)),
tidied = map(kclust, tidy),
glanced = map(kclust, glance),
augmented = map(kclust, augment, points)
)
clusters <- kclusts %>% unnest(cols = c(tidied))
assignments <- kclusts %>% unnest(cols = c(augmented))
clusterings <- kclusts %>% unnest(cols = c(glanced))
#️⃣ Step 5 可视化不同聚类数
# 目的:展示不同 k 下的聚类划分
# 优点:直观比较聚类边界和样本分配
p1 <-
ggplot(assignments, aes(x = x1, y = x2)) +
geom_point(aes(color = .cluster), alpha = 0.8) +
facet_wrap(~ k)
p1
#️⃣ Step 6 计算总平方和 手肘法选取簇数
# 目的:评估不同簇数下的聚类紧凑度
# 优点:为手肘法选 k 提供数据
ggplot(clusterings, aes(k, tot.withinss)) +
geom_line() +
geom_point()