带约束的空间坐标人群聚类:避免同坐标者过度同簇
解决空间约束聚类的同坐标违规问题
核心思路
先优先处理重复坐标的人员,强制将他们分散到不同簇,再用约束聚类完成剩余人员的分组,从根源上避免k-means-constrained因空间距离优先导致的同坐标人员扎堆问题。
具体实现步骤
1. 标记并拆分重复坐标群体
先把所有坐标重复的人员单独筛选出来,方便针对性处理:
import pandas as pd from k_means_constrained import KMeansConstrained # 假设你的数据集是df,包含latitude、longitude列 df['coord_key'] = df.apply(lambda x: f"{x['latitude']}_{x['longitude']}", axis=1) # 统计每个坐标的人数 coord_counts = df['coord_key'].value_counts() # 筛选出人数超过1的重复坐标 duplicate_coords = coord_counts[coord_counts > 1].index.tolist() # 拆分出重复坐标人员和无重复坐标人员 duplicate_group = df[df['coord_key'].isin(duplicate_coords)].sort_values('coord_key') unique_group = df[~df['coord_key'].isin(duplicate_coords)]
2. 预分配重复坐标人员到不同簇
先计算总簇数(总人数必须是9的倍数,若不是需先调整样本量),然后给每个重复坐标的人员轮流分配簇ID,确保同一坐标的人不会扎堆:
total_clusters = len(df) // 9 cluster_assignments = [] for coord in duplicate_coords: current_coord_people = duplicate_group[duplicate_group['coord_key'] == coord] # 循环分配簇ID,让同一坐标的人分散到不同簇 for idx, _ in enumerate(current_coord_people.iterrows()): cluster_assignments.append(idx % total_clusters) duplicate_group['cluster'] = cluster_assignments
3. 对剩余人员执行约束聚类
根据预分配的结果,计算每个簇还需要补充的人数(9减去已分配人数),再用k-means-constrained完成剩余人员的聚类:
# 统计每个簇已有的人数,没有的填0 cluster_current = duplicate_group['cluster'].value_counts().reindex(range(total_clusters), fill_value=0) # 每个簇需要补充的人数(正好凑够9人) cluster_need = 9 - cluster_current # 提取无重复坐标人员的空间特征 X = unique_group[['latitude', 'longitude']].values # 运行约束聚类,指定每个簇的人数上下限(这里上下限一致,确保恰好补够) kmc = KMeansConstrained( n_clusters=total_clusters, size_min=cluster_need.values, size_max=cluster_need.values, random_state=42 ) unique_group['cluster'] = kmc.fit_predict(X) # 合并最终结果 final_result = pd.concat([duplicate_group, unique_group]).sort_index()
4. 验证结果合规性
检查每个簇的人数是否为9,以及是否存在同坐标人员同簇的违规情况:
# 检查簇人数 print(final_result['cluster'].value_counts()) # 检查同坐标同簇的违规记录 violations = final_result.groupby(['coord_key', 'cluster']).size() print(violations[violations > 1])
关键优化说明
- 前置处理重复坐标:避免k-means-constrained只看空间距离,把同坐标的人聚在一起
- 轮询分配强制分散:同一坐标的人员按顺序分配到不同簇,从源头杜绝同坐标扎堆
- 动态约束人数:根据预分配结果调整每个簇的聚类人数要求,确保最终每个簇恰好9人
内容的提问来源于stack exchange,提问作者PParker
相关产品推荐
相关产品推荐

