将sklearn Haversine输出解释为公里

时间:2019-07-03 02:48:09

标签: python scikit-learn haversine

我不知道如何解释sklearn(版本20.2)中haversine实现的输出

文档说,“请注意,haversine距离度量标准需要[纬度,经度]形式的数据,并且输入和输出均以弧度为单位。”,因此我应该能够将km乘以6371 (最大距离约为半径)。

从两点开始的有效距离计算如下:

def distance(origin, destination):
    lat1, lon1 = origin
    lat2, lon2 = destination
    radius = 6371 # km

    dlat = math.radians(lat2-lat1)
    dlon = math.radians(lon2-lon1)
    a = math.sin(dlat/2) * math.sin(dlat/2) + math.cos(math.radians(lat1)) \
        * math.cos(math.radians(lat2)) * math.sin(dlon/2) * math.sin(dlon/2)
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
    d = radius * c

    return d

distance([32.027240,-81.093190],[41.981876,-87.969982])
1263.103504537151

这是正确的距离。

使用BallTree实现:

from sklearn.neighbors import BallTree
test_points = [[32.027240,41.981876],[-81.093190,-87.969982]]
tree = BallTree(test_points,metric = 'haversine')
results = tree.query_radius(test_points,r = 10,return_distance  = True)

results[1]
array([array([0.        , 1.53274271]), array([1.53274271, 0.        ])],
      dtype=object)

与distanceMetric实现相同:

dist = DistanceMetric.get_metric('haversine')
dist.pairwise([[32.027240,41.981876],[-81.093190,-87.969982]])
array([[0.        , 1.53274271],
       [1.53274271, 0.        ]])

我还尝试更改顺序,以防不应该将其输入为[[lat1,lat2],[lon1,lon2]]并且没有得到我可以解释的结果。

有人知道我可以使用sklearn实现从两个坐标获取以千米为单位的距离吗?

2 个答案:

答案 0 :(得分:1)

所以问题是sklearn要求所有内容都以<弧度> <弧度为单位,但是我的纬度/经度和半径分别以度/米为单位。在使用之前,我需要进行一些转换:

from sklearn.neighbors import BallTree
earth_radius = 6371000 # meters in earth
test_radius = 10 # meters

test_points = [[32.027240,41.981876],[-81.093190,-87.969982]]
test_points_rad = [[x[0] * np.pi / 180, x[1] * np.pi / 180] for x in test_points ]

tree = BallTree(test_points_rad, metric = 'haversine')
results = tree.query_radius(test_points, r=test_radius/earth_radius, return_distance  = True)

答案 1 :(得分:0)

只是为了澄清@flyingmeatball的先前答案,有几件事:

  1. 可能是由于sklearn的变化:您需要按行指定坐标
  2. 一种简单的转换为弧度的方法就是从数学中导入弧度模块
  3. 最终获得的结果需要再次乘以地球半径,才能得到米/公里的答案。

请参见下面的代码示例...

from math import radians
earth_radius = 6371000 # meters in earth
test_radius = 1300000 # meters

test_points = [[32.027240,-81.093190],[41.981876,-87.969982]]
test_points_rad = np.array([[radians(x[0]), radians(x[1])] for x in test_points ])

tree = BallTree(test_points_rad, metric = 'haversine')
ind,results = tree.query_radius(test_points_rad, r=test_radius/earth_radius, 
return_distance  = True)
print(ind)
print(results * earth_radius/1000)