对纬度/经度对使用自定义距离度量进行聚类

Posted

技术标签:

【中文标题】对纬度/经度对使用自定义距离度量进行聚类【英文标题】:Clustering using a custom distance metric for lat/long pairs 【发布时间】:2014-06-18 16:38:13 【问题描述】:

我正在尝试为 scikit-learn DBSCAN 实现指定自定义聚类函数:

def geodistance(latLngA, latLngB):
    print latLngA, latLngB
    return vincenty(latLngA, latLngB).miles

cluster_labels = DBSCAN(
            eps=500,
            min_samples=max(2, len(found_geopoints)/10),
            metric=geodistance
).fit(np.array(found_geopoints)).labels_

但是,当我打印出距离函数的参数时,它们根本不是我所期望的:

[ 0.53084126  0.19584111  0.99640966  0.88013373  0.33753788  0.79983037
  0.71716144  0.85832664  0.63559538  0.23032912]
[ 0.53084126  0.19584111  0.99640966  0.88013373  0.33753788  0.79983037
  0.71716144  0.85832664  0.63559538  0.23032912]

这是我的 found_geopoints 数组的样子:

[[  4.24680600e+01   1.40868060e+02]
 [ -2.97677600e+01  -6.20477000e+01]
 [  3.97550400e+01   2.90069000e+00]
 [  4.21144200e+01   1.43442500e+01]
 [  8.56111000e+00   1.24771390e+02]
...

那么为什么距离函数的参数不是纬度经度对呢?

【问题讨论】:

vincenty 是做什么的?你为什么看len(found_geopoints) 形成集群的最小样本数取决于可用的地理点数。 vincenty 是en.wikipedia.org/wiki/Vincenty's_formulae 的实现 我是否得出结论 latLngAlatLngB 是相同的 - 都是 10 个元素长?您对 DBSCAN 了解多少? found_geopoints 的总大小是多少?你在哪些单位工作?度数? latLngA 和 latLngB 是相同的。 len(found_geopoints) == 83。我的工作是度数。几天前我第一次读到 DBSCAN。 ELKI(不是 python,而是 Java)内置了对大地距离的支持,以及全索引加速(使用 R*-trees)。这将在 O(n log n) 而不是 O(n^2) 中运行。 【参考方案1】:

我似乎找到了一种解决方法,可以使用以下方法计算距离矩阵: http://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.pairwise_distances.html 然后将其用作DBSCAN(metric='precomputed').fit(distance_matrix)的参数

【讨论】:

【参考方案2】:

您可以使用 scikit-learn 做到这一点:使用具有球树算法的半正弦度量,并将弧度单位传递给 DBSCAN 拟合方法。

本教程演示了如何cluster spatial lat-long data with scikit-learn's DBSCAN使用harsine metric根据经纬度点之间的精确大地距离进行聚类:

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

请注意,坐标以弧度单位传递给.fit() 方法,并且 epsilon 参数值也必须以弧度单位为单位。

如果您希望 epsilon 为 1.5 公里,那么以弧度为单位的 epsilon 参数值将 = 1.5/6371。

【讨论】:

以上是关于对纬度/经度对使用自定义距离度量进行聚类的主要内容,如果未能解决你的问题,请参考以下文章

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

在 Python 中使用自定义距离函数对任意对象进行聚类

如何使用微笑库的 CLARANS 方法使用自定义距离矩阵对我的数据进行聚类

在 Swift 中按计算的距离对数组进行排序

如何按距离(以英里为单位)从 C# 中的给定纬度/经度对纬度/经度列表进行排序?

覆盖聚类算法中的距离度量