使用 KMeans 算法和 Python 对地理位置坐标(纬度、经度对)进行聚类

Posted

技术标签:

【中文标题】使用 KMeans 算法和 Python 对地理位置坐标(纬度、经度对)进行聚类【英文标题】:Clustering geo location coordinates (lat,long pairs) using KMeans algorithm with Python 【发布时间】:2014-09-05 21:33:46 【问题描述】:

使用以下代码对地理位置坐标进行聚类会产生 3 个聚类:

    import numpy as np
    import matplotlib.pyplot as plt
    from scipy.cluster.vq import kmeans2, whiten

    coordinates= np.array([
               [lat, long],
               [lat, long],
                ...
               [lat, long]
               ])
    x, y = kmeans2(whiten(coordinates), 3, iter = 20)  
    plt.scatter(coordinates[:,0], coordinates[:,1], c=y);
    plt.show()

使用 Kmeans 进行位置聚类是否正确,因为它使用 Euclidean distance 而不是 Haversine formula 作为距离函数?

【问题讨论】:

【参考方案1】:

k-means 不是用于空间聚类的好算法,因为你的意思。相反,您可以使用 scikit-learn 的 DBSCAN 以及半正弦度量和球树算法来完成此聚类工作。

本教程使用 DBSCAN/haversine 演示 clustering latitude-longitude spatial data 并避免所有欧几里得距离问题:

df = pd.read_csv('gps.csv')
coords = df.as_matrix(columns=['lat', 'lon'])
db = DBSCAN(eps=eps, min_samples=ms, algorithm='ball_tree', metric='haversine').fit(np.radians(coords))

请注意,这专门使用 scikit-learn v0.15,因为一些早期/后期版本似乎需要计算完整的距离矩阵。另请注意,eps 值以弧度为单位,而 .fit() 采用弧度单位的坐标作为半正弦度量。

【讨论】:

【参考方案2】:

这在很大程度上取决于您的应用程序:

在赤道附近,结果应该相当准确。靠近其中一个极点,结果将毫无用处。 但是,它可以作为预处理步骤或用于精度要求较低的应用,例如小的、不重叠且非常不同的集群。

如果您真的需要Haversine 公式,您可能需要查看this 讨论。正如 Anony-Mousse 所说:

请注意,Haversine 距离不适用于 k-means 或平均链接聚类,除非您找到一种计算均值的智能方法,以使方差最小化。如果您有经纬度坐标的 -180/+180 环绕,请不要使用算术平均值。

【讨论】:

以上是关于使用 KMeans 算法和 Python 对地理位置坐标(纬度、经度对)进行聚类的主要内容,如果未能解决你的问题,请参考以下文章

如何用mapreduce分布式实现kmeans算法

Kmeans聚类算法及其 Python实现

聚类算法 - kmeans

Python训练Kmeans算法预测图像的主色

Kmeans 聚类 及其python实现

Python—kmeans算法学习笔记