基于Sklearn Kmeans的二维用户数据簇内相似度量化方法问询
如何用Scikit-learn的KMeans获取簇内紧密程度指标?
当然可以!Scikit-learn的KMeans其实已经提供了足够的工具,让你轻松计算每个簇的方差、平方误差这类衡量簇内数据点紧密程度的指标。针对你的50个簇场景,这里有几种实用的方法:
1. 手动计算每个簇的簇内方差(均方误差)
KMeans会保存每个簇的中心坐标(cluster_centers_),我们可以遍历每个簇,计算簇内所有点到中心的距离平方的平均值——这就是簇内的均方误差(等价于方差的一种形式,对二维数据来说是整体的紧密程度指标)。
示例代码:
from sklearn.cluster import KMeans import numpy as np # 假设你的二维用户数据存储在X中,形状为(样本数, 2) kmeans = KMeans(n_clusters=50, random_state=42) labels = kmeans.fit_predict(X) cluster_centers = kmeans.cluster_centers_ # 存储每个簇的簇内均方误差 cluster_variances = [] for cluster_id in range(50): # 提取当前簇的所有数据点 cluster_points = X[labels == cluster_id] # 处理空簇(虽然KMeans一般不会出现,但还是做个兜底) if len(cluster_points) == 0: cluster_variances.append(0.0) continue # 计算每个点到簇中心的距离平方,再取平均值 distances_squared = np.sum((cluster_points - cluster_centers[cluster_id]) ** 2, axis=1) intra_variance = np.mean(distances_squared) cluster_variances.append(intra_variance) # 输出结果,cluster_variances的每个元素对应一个簇的紧密程度 print("各簇的簇内均方误差:", cluster_variances)
2. 利用KMeans的inertia_拆分每个簇的平方误差
KMeans的inertia_属性是所有簇的平方误差总和(即所有样本到其对应簇中心的距离平方之和)。我们可以结合每个簇的样本数量,拆分出单个簇的平方误差总和,再计算平均值得到簇内方差:
示例代码:
# 获取每个簇的样本数量 cluster_sizes = np.bincount(labels) # 存储每个簇的平方误差总和 cluster_sse = [] total_inertia = kmeans.inertia_ for cluster_id in range(50): cluster_points = X[labels == cluster_id] # 计算当前簇的平方误差总和 sse = np.sum((cluster_points - cluster_centers[cluster_id]) ** 2) cluster_sse.append(sse) # 验证拆分后的总和是否等于inertia_(浮点精度允许的误差范围内) assert np.isclose(sum(cluster_sse), total_inertia) # 计算每个簇的平均平方误差(即簇内方差) cluster_avg_sse = [sse / size if size > 0 else 0 for sse, size in zip(cluster_sse, cluster_sizes)]
3. 额外:用轮廓系数兼顾簇内紧密与簇间分离
如果你不仅想衡量簇内紧密,还想同时看簇与簇之间的分离程度,可以用轮廓系数。sklearn.metrics里的silhouette_samples能返回每个样本的轮廓系数,我们按簇取平均值就能得到每个簇的轮廓系数(范围[-1,1],越接近1说明簇内越紧密、与其他簇越分离):
示例代码:
from sklearn.metrics import silhouette_samples # 获取每个样本的轮廓系数 sample_sil_scores = silhouette_samples(X, labels) # 计算每个簇的平均轮廓系数 cluster_sil_avg = [] for cluster_id in range(50): cluster_sil = sample_sil_scores[labels == cluster_id] if len(cluster_sil) == 0: cluster_sil_avg.append(0.0) continue cluster_sil_avg.append(np.mean(cluster_sil))
这些指标里,簇内均方误差是最直接反映簇内紧密程度的指标;轮廓系数则能帮你同时评估聚类的整体合理性。根据你的具体需求选择就行!
内容的提问来源于stack exchange,提问作者Sundaresh Prasanna
相关产品推荐
相关产品推荐

