聚类地理位置坐标(纬线,长线对)


51

什么是正确的地理位置聚类方法和聚类算法?

我正在使用以下代码对地理位置坐标进行聚类:

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()

使用K均值进行地理位置聚类是否正确,因为它使用的是欧几里得距离,而不是Haversine公式作为距离函数?


您也可以看看这个类似的问题:datascience.stackexchange.com/questions/10063/…–
VividD

我认为k均值的可行性取决于您的数据在哪里。如果您的数据散布到世界各地,那么它将无法正常工作,因为距离并不像其他用户已经说过的那样。但是,如果您的数据更局部,则k均值就足够了,因为几何是局部欧几里德的。
Juan Ignacio Gil

Answers:


7

在这种情况下,K均值应该是正确的。由于k均值试图仅基于对象之间的欧几里得距离进行分组,因此您将获得彼此靠近的位置簇。

要找到最佳数目的聚类,您可以尝试对平方距离的组内和进行“肘部”绘制。这可能会有所帮助(http://nbviewer.ipython.org/github/nborwankar/LearnDataScience/blob/master/notebooks/D3.%20K-Means%20Clustering%20Analysis.ipynb


3
如何处理环绕点上彼此靠近的点?
casperOne 2014年

1
您需要找到一个采用预先计算的距离矩阵的算法,或者允许您提供一个距离函数,当需要计算距离时可以调用该函数。否则它将无法正常工作。
Spacedman 2014年

肘部图可能根本无法帮助您,因为可能没有肘部。另外,请确保尝试使用相同的簇号尝试多次运行k均值,因为您可能会得到不同的结果。
蚱hopper'17年

这是一个糟糕的主意,因为所有点都将被聚类,这在映射中很少是一个好主意。
理查德

52

在这里,K均值不是最合适的算法。

原因是k-means旨在最小化方差。当然,这是从统计和信号处理的角度来看的,但是您的数据不是“线性的”。

由于您的数据采用纬度,经度格式,因此您应该使用一种可以处理任意距离函数(尤其是大地测距函数)的算法。分层群集,PAM,CLARA和DBSCAN是这种情况的流行示例。

https://www.youtube.com/watch?v=QsGOoWdqaT8建议使用OPTICS群集。

当您考虑接近+ -180度环绕点的点时,很容易看到k均值的问题。即使您破解了k均值以使用Haversine距离,在更新步骤中重新计算均值时,结果也将被严重破坏。最糟糕的情况是,k均值将永远不会收敛!


您能否建议一种更合适的地理位置数据聚类方法?
Alex Spurling

您注意到第三段了吗?
Anony-Mousse

7

GPS坐标可以直接转换为geohash。Geohash根据位数将地球分为大小不同的“存储桶”(较短的Geohash代码创建较大的区域,较长的代码创建较小的区域)。Geohash是一种可调精度的聚类方法。


根据答案中链接的Wikipedia文章,这似乎也遭受了K-Means相同的180度环绕问题。
诺曼·H

是的 加号代码更好。plus.codes
Brian Spiering

该解决方案的一个好处是,只要您计算一次geohash,重复比较操作就会更快。
诺曼H

Geohash将在铲斗边缘情况下遇到问题-根据每个铲斗的任意边缘,将两个非常接近的点放在不同的铲斗中。
Dan G

5

我的答案可能很晚,但是如果您仍在处理地理聚类,那么您可能会发现这项研究很有趣。它涉及两种比较不同的地理数据分类方法的比较:K均值聚类和潜在类增长建模。

研究中的图像之一:

在此处输入图片说明

作者得出的结论是,最终结果总体上是相似的,并且在某些方面,LCGM过度渗透了K均值。


5

您可以为此使用HDBSCAN。python软件包支持hasversine距离,可以正确计算经纬度点之间的距离。

文档所述,您首先需要将点转换为弧度才能起作用。以下psuedocode应该可以解决问题:

points = np.array([[lat1, lon1], [lat2, lon2], ...])
rads = np.radians(points)
clusterer = hdbscan.HDBSCAN(min_cluster_size=N, metric='haversine')
cluster_labels = clusterer.fit_predict(points)

0

用k均值算法对位置进行聚类不是一个好主意。您的位置可以分布在世界各地,您无法预测群集的数量,不仅是如果将群集设置为1,那么位置还将被分组为1个单个群集。我正在使用分层集群。



-1

与Kmeans群集一起使用,因为HBScan将永远使用。我为一个项目尝试了它,但最终使用Kmeans获得了预期的结果。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.