围绕固定质心聚类坐标的最优方法:Scikit K-Means优化及替代方案探讨
固定质心坐标聚类方案实现
你的需求本质是固定质心的最近邻分配,不需要用K-Means聚类,最优方案就是对每个目标点计算到所有预设质心的距离,将其分配到距离最近的质心分组中,实现简单且效果完全符合预期。
你之前使用K-Means出现瑕疵的核心原因是:K-Means的核心逻辑是「分配点到最近质心→更新质心为分组内点的均值」两步迭代,你只设置了初始质心但没有禁用质心更新,会导致最终聚类的质心偏离你预设的home点,自然不符合要求。
实现步骤
1. 距离度量选择
- 如果是平面直角坐标,使用欧氏距离即可
- 如果是经纬度坐标,使用哈弗辛(Haversine)距离计算球面距离,注意需先将角度转为弧度
2. 代码实现
这里使用scipy优化的距离计算函数,比手动实现循环效率高很多,适配大规模坐标场景:
import numpy as np from scipy.spatial.distance import cdist # 输入数据示例,替换为自己的坐标列表即可 home_coords = np.array([ [1.0, 2.0], # home_coords_1 [3.0, 4.0], # home_coords_2 [5.0, 6.0] # home_coords_3 ]) dest_coords = np.array([ [5.2, 6.1], # destination_coords_1 [0.8, 2.3], # destination_coords_2 [4.9, 5.8], # destination_coords_3 [2.9, 4.2], # destination_coords_4 [1.1, 1.9] # destination_coords_5 ]) # 计算所有目标点到所有home点的距离矩阵,行对应目标点,列对应home点 dist_matrix = cdist(dest_coords, home_coords, metric='euclidean') # 若为经纬度坐标,使用以下代码(坐标需先转弧度) # dist_matrix = cdist(np.radians(dest_coords), np.radians(home_coords), metric='haversine') # 为每个目标点匹配距离最近的home点索引 nearest_home_idx = np.argmin(dist_matrix, axis=1) # 按要求格式组装结果 result = [[home.tolist()] for home in home_coords] for idx, dest in zip(nearest_home_idx, dest_coords): result[idx].append(dest.tolist()) print(result)
运行上述代码输出和你需求示例完全一致:
[[[1.0, 2.0], [0.8, 2.3], [1.1, 1.9]], [[3.0, 4.0], [2.9, 4.2]], [[5.0, 6.0], [5.2, 6.1], [4.9, 5.8]]]
方案优势
- 结果完全符合需求:所有目标点都分配到距离最近的固定home点下,不会出现质心偏移问题
- 效率极高:底层C实现的距离计算,支持百万级坐标秒级处理
- 结果确定性:无随机性,每次运行结果完全一致
- 可灵活适配不同距离度量,满足平面、球面等不同坐标场景的需求
你之前考虑的「遍历home点逐个选最近的n个目标点」逻辑确实有缺陷,会出现同一个目标点被多个home点选中的冲突,而上述方案是反过来给每个目标点匹配最近的home点,完全避免冲突,不存在效果无保障的问题。
内容的提问来源于stack exchange,提问作者jan
相关产品推荐
相关产品推荐

