R语言中K-Means聚类绘图出现非真实点问题求助
问题排查与解决方案
咱们先拆解你遇到的核心问题,再一步步给出修正方案:
1. 为什么会出现负值点?
你用的clusplot()函数本质是先对数据做了**主成分分析(PCA)**来生成可视化坐标轴,而主成分得分是允许为负数的——这是PCA的正常特性,和你原始数据的非负性完全不冲突!
你误以为图中x/y轴是原始的「平均销量」和「平均库存」,但实际上clusplot()默认会把数据投影到前两个主成分上,这两个主成分是原始变量的线性组合,自然可能出现负值。这不是数据或聚类的问题,是可视化方法的固有属性。
2. 为什么觉得点不是原始数据的有效点?
同样是PCA转换导致的:它会对原始数据做旋转、缩放等操作,投影后的点坐标和原始数据坐标不一样,但每个点依然对应你输入的reduced_dataset里的每一行样本,只是换了个「坐标系」展示而已。
3. 修正代码&实现你想要的可视化
如果你想直接用原始的平均销量和库存做聚类散点图(无负值、完全对应原始数据),可以不用clusplot(),直接用基础plot()函数搭配聚类颜色。另外你的代码还有几个小细节需要修正:
修正后的完整代码
# 加载你提供的数据集 reduced_dataset <- structure(list(Avg_Sold_No_Promo = c(0.255722695, 1.139983236, 0.458651842, 0.784966698, 1.642746914, 0.115264798, 7.50338696, 0.487603306, 1.023373984, 0.956099815, 1.505901506, 0.253837072, 0.834963325, 0.880898876, 6.527699531, 11.54054054, 3.44077135, 0.750182882, 0.251033058, 1.875698324), Avg_Inventory_No_Promo = c(6.068672335, 22.57865326, 9.00694927, 11.56137012, 28.47530864, 7.485981308, 170.9064352, 11.07438017, 22.80792683, 40.63863216, 41.73463573, 10.87603306, 35.87408313, 46.09213483, 185.5671362, 315.6015693, 165.1129477, 78.18032187, 9.65857438, 198.4385475)), .Names = c("Avg_Sold_No_Promo", "Avg_Inventory_No_Promo"), row.names = c(NA, 20L), class = "data.frame") # 肘部法找最优聚类数:更简洁的R风格写法 wcss <- sapply(1:10, function(i) { sum(kmeans(reduced_dataset, centers = i)$withinss) }) plot(1:10, wcss, type = 'b', main = 'The Elbow Method', xlab = 'Number of clusters', ylab = 'WCSS') # 拟合K-Means:注意不要用kmeans作为变量名,会覆盖R内置函数! km_result <- kmeans(x = reduced_dataset, centers = 2) y_kmeans <- km_result$cluster # 方法1:用原始变量绘制聚类散点图(完全对应原始数据,无负值) plot(reduced_dataset$Avg_Sold_No_Promo, reduced_dataset$Avg_Inventory_No_Promo, col = y_kmeans + 1, # 用不同颜色区分聚类 pch = 16, main = 'Clusters of categories - NOT ON SALE', xlab = 'Average Sold Quantity', ylab = 'Average Inventory') # 添加聚类中心标记 points(km_result$centers, col = c(2,3), pch = 8, cex = 2) # 方法2:如果一定要用clusplot,修正坐标轴标签避免误解 library(cluster) clusplot(reduced_dataset, y_kmeans, lines = 0, shade = TRUE, color = TRUE, labels = 2, plotchar = FALSE, span = TRUE, main = 'Clusters (PCA Projection) - NOT ON SALE', xlab = 'Principal Component 1', ylab = 'Principal Component 2')
关键修正说明
- 避免变量名冲突:原代码中
kmeans = kmeans(...)会覆盖R内置的kmeans()函数,后续调用会出错,所以改成km_result存储聚类结果。 - 原始数据可视化:直接用
plot()绘制原始的两个变量,搭配颜色区分聚类,还能添加聚类中心,完全符合你对「原始数据有效点」的预期。 - 修正clusplot标签:明确标注坐标轴为主成分,避免误解负值的来源。
验证结果
运行修正后的代码:
- 方法1的散点图会完全使用你原始的非负数据,每个点对应输入样本,聚类边界清晰;
- 方法2的clusplot依然会有负值,但你现在明确知道这是主成分得分,属于正常现象。
内容的提问来源于stack exchange,提问作者lnros
相关产品推荐
相关产品推荐

