如何使用Scikit-learn计算已有带标签聚类的簇质心
解决方案:基于已有聚类标签计算质心
没问题!针对已经有聚类标签的数据集计算质心其实超简单,用Scikit-learn配合基础数据处理工具就能轻松搞定——毕竟标签都给你分好组了,根本不需要再跑一遍聚类算法~
核心思路
首先明确:在欧氏距离的定义下,簇的质心就是该簇内所有样本特征的均值向量,因为均值向量到簇内所有点的平方距离之和是最小的,完全符合你要的“与簇内所有数据点距离最小的向量”的要求。所以我们的核心操作就是:按聚类标签分组,计算每组的特征均值。
代码实现(两种常见场景)
场景1:处理NumPy数组格式的特征数据
如果你的特征是用NumPy数组存储的,直接按标签筛选分组计算均值即可:
import numpy as np # 可选:如果数据需要标准化,导入Scikit-learn的标准化工具 from sklearn.preprocessing import StandardScaler # 示例数据:X是特征矩阵(样本数×特征数),labels是已有的聚类标签数组 X = np.array([[1, 2], [2, 3], [3, 4], [10, 11], [11, 12], [12, 13]]) labels = np.array([0, 0, 0, 1, 1, 1]) # 获取所有唯一的聚类标签 unique_labels = np.unique(labels) # 遍历每个标签,计算对应簇的质心 centroids = [] for label in unique_labels: # 筛选出当前簇的所有样本 cluster_samples = X[labels == label] # 按特征维度(axis=0)计算均值,得到质心 centroid = cluster_samples.mean(axis=0) centroids.append(centroid) # 转换成NumPy数组方便后续使用 centroids = np.array(centroids) print("各簇质心:\n", centroids)
运行这段代码后,你会得到两个簇的质心:[[2. 3.] [11. 12.]],完全符合示例数据的分布。
场景2:处理Pandas DataFrame格式的数据集
如果你的数据是用DataFrame存储的(实际项目中很常见),用分组聚合的方式会更简洁:
import pandas as pd # 将示例数据转换成DataFrame df = pd.DataFrame(X, columns=["feature1", "feature2"]) df["cluster_label"] = labels # 按聚类标签分组,计算每个特征的均值(即质心) centroids_df = df.groupby("cluster_label").mean() # 转换成NumPy数组(如果需要的话) centroids = centroids_df.values print("各簇质心:\n", centroids_df)
这种方式更直观,输出的结果会保留特征列名,方便查看每个特征维度的质心值。
额外注意:标准化数据的质心还原
如果你的数据之前做过标准化处理(比如用StandardScaler),那上面计算出来的质心是标准化后的尺度。如果需要还原到原始数据的尺度,记得用标准化器的inverse_transform方法:
# 假设之前对数据做了标准化 scaler = StandardScaler() X_scaled = scaler.fit_transform(X) # 计算标准化后的质心 centroids_scaled = [] for label in unique_labels: cluster_samples = X_scaled[labels == label] centroid = cluster_samples.mean(axis=0) centroids_scaled.append(centroid) centroids_scaled = np.array(centroids_scaled) # 还原到原始数据尺度 centroids_original = scaler.inverse_transform(centroids_scaled) print("原始尺度下的质心:\n", centroids_original)
这样得到的质心就和原始数据的数值范围一致了。
内容的提问来源于stack exchange,提问作者sheldonzy
相关产品推荐
相关产品推荐

