You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用R创建等大小聚类?购物篮产品均衡聚类方案问询

嘿,这个问题我之前帮不少朋友解决过——要实现严格大小相等的聚类,普通的K-means或者PAM确实做不到,因为它们的核心目标是最小化簇内距离,不会强制约束每个簇的规模。不过有几个靠谱的方案,我给你拆解下:

可行方案汇总

1. 先聚类再调整(最简单易实现)

先用常规的K-means/PAM得到初始聚类结果,然后手动调整簇的大小,直到所有簇的元素数量一致。具体步骤:

  • 第一步:跑普通聚类,得到每个簇的当前大小
  • 第二步:对于超过目标大小(N/k)的簇,挑选那些离簇中心最远的元素(或者和其他小簇中心最接近的元素),把它们移到元素不足的小簇里
  • 第三步:重复调整,直到所有簇的大小都等于目标值

示例代码(Python)

这里以K-means为例,写个简化的调整脚本:

import numpy as np
from sklearn.cluster import KMeans

def balanced_kmeans(X, n_clusters):
    # 先跑普通K-means得到初始标签
    kmeans = KMeans(n_clusters=n_clusters, random_state=42)
    labels = kmeans.fit_predict(X)
    
    target_size = len(X) // n_clusters
    cluster_sizes = np.bincount(labels)
    
    # 循环调整簇大小
    for cluster_idx in range(n_clusters):
        while cluster_sizes[cluster_idx] > target_size:
            # 找到当前簇里离中心最远的样本
            cluster_points = X[labels == cluster_idx]
            distances = np.linalg.norm(cluster_points - kmeans.cluster_centers_[cluster_idx], axis=1)
            farthest_pos = np.argmax(distances)
            original_data_idx = np.where(labels == cluster_idx)[0][farthest_pos]
            
            # 找到当前最小的簇,把样本移过去
            smallest_cluster = np.argmin(cluster_sizes)
            labels[original_data_idx] = smallest_cluster
            
            # 更新簇大小统计
            cluster_sizes[cluster_idx] -= 1
            cluster_sizes[smallest_cluster] += 1
    
    # 可选:重新计算调整后的簇中心
    new_centers = np.array([X[labels == i].mean(axis=0) for i in range(n_clusters)])
    return labels, new_centers

# 测试:24个样本分成4簇,每簇6个
X = np.arange(24).reshape(-1, 1)
labels, centers = balanced_kmeans(X, 4)
print("各簇大小:", np.bincount(labels))  # 输出应该是[6,6,6,6]

这个方法的好处是简单易上手,缺点是会稍微牺牲一点簇内的紧凑性,但对于大多数业务场景来说完全够用。

2. 使用专门的约束聚类算法

如果想要更严谨的实现,可以用Equal K-means——这是K-means的变种,专门为等大小簇设计。它在迭代分配样本的阶段,会强制每个簇只能接收固定数量的样本,从根源上保证簇大小一致。

不过这个算法没有被sklearn这类常用库集成,你可以自己实现(核心是在分配步骤加数量约束),或者找一些专门的约束聚类工具包。另外,PAM也有约束版本,通过修改medoid选择的规则来限制簇大小,但实现起来相对复杂。

3. 基于排序的划分(适合有明显维度特征的场景)

如果你的数据可以通过某个特征(比如综合得分、PCA降维后的第一主成分)排序,并且排序后的样本具有相似性(比如得分接近的样本更像),那可以直接把排序后的样本切成k段,每段正好N/k个元素。

比如你的示例数据是1到24,按数值排序后直接分成4段:[1-6], [7-12], [13-18], [19-24],每段就是一个簇。这个方法简单粗暴,完全不需要聚类算法,但前提是排序维度能准确反映样本的相似性。

总结
  • 优先试试「先聚类再调整」的方法,快速满足需求
  • 如果追求聚类质量和严谨性,可以研究Equal K-means的实现
  • 数据有合适排序维度的话,直接分段效率最高

内容的提问来源于stack exchange,提问作者BS.Mira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:58:25