K-Means肘部法不同实现对比:两种方法是否均正确?
关于K-Means肘部法两种实现的解惑
首先,搞懂kmeans.inertia_到底是什么
inertia_是sklearn的KMeans模型训练完成后自带的属性,它的定义非常明确:所有样本到其所属簇中心的欧氏距离的平方和。公式可以写成:
$$\text{inertia} = \sum_{i=0}^{n-1} \min_{j \in {0..k-1}} ||x_i - c_j||^2$$
其中$x_i$是单个样本,$c_j$是第j个簇的中心,n是总样本数。这个值越小,说明簇内的样本越紧凑,聚类效果越好(当然k越大这个值肯定越小,所以才需要肘部法找拐点)。
两种实现的差异与正确性分析
你提到的两种方法,本质上都是在衡量聚类的"紧凑程度",只是用了不同的量化方式,两者都是正确的,差异来自指标的计算方式:
- 第一种直接调用
kmeans.inertia_:用的是平方距离的总和,这个值是KMeans训练过程中就已经计算好的,调用起来非常高效,不需要额外的计算。 - 第二种手动计算的方式:
sum(np.min(cdist(X, kmeanModel.cluster_centers_, 'euclidean'), axis=1)) / X.shape[0],它计算的是每个样本到最近簇中心的欧氏距离的平均值(先取每个样本的最小距离,求和后除以样本数)。
为什么结果会略有差异?
很简单:一个是平方距离的总和,一个是原始距离的平均值,数值维度和量级自然不一样。比如假设某个样本到中心的距离是3,它对inertia_的贡献是9,对第二种方法的贡献是3/总样本数。但重点是:随着k的增加,两个指标的变化趋势完全一致——都是单调递减,并且肘部出现的位置是相同的。因为肘部法看的是"下降速度突然变缓"的那个点,不管用哪种指标,这个拐点的位置不会变。
总结
两种实现都是有效的肘部法手段,选哪种都可以:
- 如果追求高效,直接用
inertia_就好,不用额外写计算代码; - 如果更习惯看"平均距离"这种直观的指标,手动计算的方式也没问题。
核心是理解它们都是在衡量簇内样本的紧凑性,趋势一致,所以都能帮你找到最优的k值。
内容的提问来源于stack exchange,提问作者user59419
相关产品推荐
相关产品推荐

