数据集过大如何开展聚类分析?R层次聚类内存不足问题求解
错误原因
传统层次聚类需要先生成n × n的全量距离矩阵,你当前样本量n = 42172,对应矩阵包含约17.8亿个数值,仅存储就需要6.6G以上内存,超出了普通设备的分配上限。
另外你的预处理逻辑存在业务偏差:删除Product和Week字段后,每条样本是单个产品单周的销量,对这个粒度做聚类几乎没有实际业务价值,常规需求都是对产品做销量特征聚类。
解决方案
方案1:修正聚类粒度(推荐)
先把原始数据转换为宽表,每行对应一个产品,每列对应对应周的销量,聚合后样本量仅为811条(和产品数量一致),不管用什么聚类算法都不会有内存压力,示例代码:
# 转换为产品-周销量宽表 library(tidyr) product_wide <- pivot_wider(df1, id_cols = Product, names_from = Week, values_from = Sales, values_fill = 0) # 提取数值特征做标准化 sc_df <- scale(product_wide[, -1]) # 此时做层次聚类完全没有内存问题 dist_df <- dist(sc_df, method = 'euclidean') hclust_avg <- hclust(dist_df, method = "average") plot(hclust_avg)
方案2:换用低内存开销的聚类算法
如果确实需要对原始4万多条单周销量数据做聚类,不用传统层次聚类即可:
- 用K-means算法:单变量场景下收敛快、内存开销极低,示例代码:
# 可先用肘部法确定最优聚类数k,这里示例k=3 kmeans_res <- kmeans(sc_df, centers = 3, nstart = 25) # 聚类标签可合并回原始数据集 df1$cluster <- kmeans_res$cluster
- 用优化版层次聚类实现:安装
fastcluster包,其针对低维数据做了专门优化,内存开销比原生hclust低50%以上,示例代码:
install.packages("fastcluster") library(fastcluster) # 直接传入一维向量计算,不需要提前生成全量距离矩阵 hclust_avg <- hclust.vector(sc_df$Sales, method = "average") plot(hclust_avg)
方案3:单变量场景直接用分箱替代聚类
单变量的聚类本质就是分箱,你可以直接用自然间断点分箱、等频分箱等方法实现和聚类完全一致的效果,内存开销可以忽略,示例代码:
install.packages("classInt") library(classInt) # 示例分为3类 breaks <- classIntervals(sc_df$Sales, n = 3, style = "jenks")$brks df1$cluster <- cut(sc_df$Sales, breaks = breaks, labels = 1:3, include.lowest = T)
内容的提问来源于stack exchange,提问作者SaltySenator
相关产品推荐
相关产品推荐

