使用 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 对地理位置坐标(纬度、经度对)进行聚类的主要内容,如果未能解决你的问题,请参考以下文章