为什么scipy的K-means算法未使用全部预先指定的K个簇?
scipy K-means返回簇数少于指定K值的原因解释
首先明确:scipy的K-means实现本身没有设计「自动弃用超出实际需求K值」的逻辑,你观察到的簇数减少完全是空簇被默认丢弃的结果,具体原因如下:
- 核心原因是空簇的默认丢弃逻辑:K-means算法迭代过程中,如果某一个初始质心在某一轮迭代中没有被分配到任何样本,就会形成空簇。
scipy.cluster.vq.kmeans和scipy.cluster.vq.kmeans2的默认处理逻辑都是直接移除空簇对应的质心,不会做额外的补全,因此最终返回的簇数会小于你指定的K值。 - 你的场景下空簇高发的诱因:你使用的数据集仅8.1万样本,指定的K值高达8613,平均每个簇仅能分配到9个左右样本,这种K值和样本量比值过高的场景下,初始化阶段就很容易出现部分随机质心周围没有对应样本的情况,迭代过程中原本有样本的簇也很容易因为样本全部分配到其他更近的质心而变成空簇,最终就出现了1600左右的簇数缺口。
- 可选解决方案:如果需要强制保证返回K个簇,可以调整
scipy.cluster.vq.kmeans2的minit参数换用更稳定的初始化方式,或者改用sklearn的KMeans实现,通过设置empty_cluster='singleton'参数,将空簇替换为距离当前质心最远的样本作为新质心,避免空簇被丢弃。但要注意在K值过高的场景下,强制保留所有簇大概率会产生大量无实际意义的单样本簇。
内容的提问来源于stack exchange,提问作者Mahfuja nilufar
相关产品推荐
相关产品推荐

