R语言:复现Pearson相关系数K-means聚类遇空表问题求助
问题描述
需要复现Systat中基于Pearson相关系数的K-means聚类功能,使用ClusterR包处理包含Panelist(受访者)和回归系数两列的数据,目标是为每个受访者分配2个聚类中的其一。但运行代码后得到空表,期望得到含聚类分配(1或2)的结果表。
原错误代码
library(utils) library(cluster) library("ClusterR") library(dplyr) # Data data <- read.csv("/Users/sr/Documents/src/Learning/R-BimiProject/DoctorPanelistCoefficients.csv") data <- as.data.frame(data) data <- group_by(data, Panelist) # Define 'entire_sample' entire_sample <- nrow(data) # Invoke ClusterR clusters <- Clara_Medoids( data=data, clusters=2, samples=entire_sample, sample_size=1, distance_metric="pearson_correlation", minkowski_p=1, threads=1, swap_phase=TRUE, fuzzy=FALSE, verbose=FALSE, seed=1 ) # Create an Excel file with the results write.xlsx(clusters$clusterID, file = "ClusterID.xlsx")
错误原因分析
- 分组操作破坏数据结构:使用
group_by(data, Panelist)将数据转换为分组数据框,Clara_Medoids无法正确处理分组对象,导致聚类计算异常。 - Clara参数设置错误:
sample_size=1完全不符合Clara算法的设计逻辑(Clara是通过抽取多个大样本进行聚类,sample_size需要远大于1),这会导致无法生成有效聚类结果。 - 聚类特征选择错误:将包含字符串/标识的
Panelist列纳入聚类输入,聚类应该仅使用回归系数列作为特征,Panelist是用于匹配结果的标识列,不能参与聚类计算。
修正方案
根据数据量大小选择两种方案:
方案1:小数据集(样本量<1000)直接用KMeans_rcpp
KMeans_rcpp支持Pearson相关系数作为距离度量,更适合小数据集:
library(ClusterR) library(dplyr) library(openxlsx) # 推荐用openxlsx,比utils的write.xlsx更稳定 # 读取数据 data <- read.csv("/Users/sr/Documents/src/Learning/R-BimiProject/DoctorPanelistCoefficients.csv") # 分离标识列和聚类特征列:假设回归系数列名为"reg_coef",请根据实际列名修改 panelist_ids <- data$Panelist cluster_features <- select(data, -Panelist) # 仅保留回归系数列作为特征 # 执行K-means聚类(基于Pearson相关系数) kmeans_result <- KMeans_rcpp( data = cluster_features, clusters = 2, distance_metric = "pearson_correlation", verbose = FALSE, seed = 1 ) # 合并聚类结果与受访者ID cluster_assignments <- tibble( Panelist = panelist_ids, ClusterID = kmeans_result$clusters ) # 输出到Excel write.xlsx(cluster_assignments, file = "ClusterID.xlsx")
方案2:大数据集(样本量>1000)调整Clara_Medoids参数
如果数据量很大,需要用Clara算法,调整sample_size为合理值(比如样本量的10%):
library(ClusterR) library(dplyr) library(openxlsx) # 读取数据 data <- read.csv("/Users/sr/Documents/src/Learning/R-BimiProject/DoctorPanelistCoefficients.csv") # 分离标识列和聚类特征列 panelist_ids <- data$Panelist cluster_features <- select(data, -Panelist) # 定义合理的sample_size:比如取总样本量的10%,至少不小于50 total_rows <- nrow(cluster_features) sample_size <- max(50, round(total_rows * 0.1)) # 执行Clara聚类 clara_result <- Clara_Medoids( data = cluster_features, clusters = 2, samples = 10, # 抽取10个样本进行聚类,可根据需求调整 sample_size = sample_size, distance_metric = "pearson_correlation", threads = 1, swap_phase = TRUE, fuzzy = FALSE, verbose = FALSE, seed = 1 ) # 合并结果并输出 cluster_assignments <- tibble( Panelist = panelist_ids, ClusterID = clara_result$clusterID ) write.xlsx(cluster_assignments, file = "ClusterID.xlsx")
注意事项
- 请确保回归系数列是数值型数据,如果是字符型需要先转换:
cluster_features <- mutate(cluster_features, reg_coef = as.numeric(reg_coef)) - 如果你的回归系数列名不是
reg_coef,请替换为实际列名 - 推荐使用
openxlsx包处理Excel输出,比基础包的write.xlsx兼容性更好
内容的提问来源于stack exchange,提问作者StephenRappaport
相关产品推荐
相关产品推荐

