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

rok*_*rok 8 python numpy geolocation scipy k-means

使用以下代码聚类地理位置坐标会产生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()
Run Code Online (Sandbox Code Playgroud)

使用Kmeans进行位置聚类是否正确,因为它使用欧几里德距离而非使用Haversine公式作为距离函数?

eos*_*eos 7

由于您的意思,k-means不是用于空间聚类的好算法.相反,您可以使用scikit-learn的DBSCAN和hasrsine metric and ball-tree算法来完成此聚类工作.

本教程演示了使用DBSCAN/hasrsine对纬度 - 经度空间数据进行聚类,并避免了所有这些欧几里德距离问题:

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))
Run Code Online (Sandbox Code Playgroud)

请注意,这特别使用了scikit-learn v0.15,因为一些早期/后期版本似乎需要计算全距离矩阵.另请注意,eps值以弧度表示,而.fit()以半径为单位获取半正弦度量的坐标.

  • `.as_matrix()` 已弃用 >0.23.0。请改用 df.values。 (5认同)

Fal*_*lko 5

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

  • 在赤道附近,结果应该相当准确.接近其中一个极点,结果根本没用.
  • 然而,它可以作为预处理步骤或具有低精度要求的应用,例如小的,非重叠的和非常不同的簇.

如果你真的需要Haversine公式,你可能想看看这个讨论.正如Anony-Mousse所说:

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