Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interpreting sklearn haversine outputs to kilometers

I can't figure out how to interpret the outputs of the haversine implementations in sklearn (version 20.2)

The documentation says,"Note that the haversine distance metric requires data in the form of [latitude, longitude] and both inputs and outputs are in units of radians.",so I should be able to convert to km multiplying by 6371 (great distance approx for radius).

A functioning distance calculation from two points would be as follows:

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

This is the correct distance.

Using the BallTree implementation:

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)

Same for the distanceMetric implementation:

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

I also tried changing the order, in case it wasn't supposed to be input as [[lat1,lat2],[lon1,lon2]] and also didn't get results that I can interpret.

Does anyone know how I can get the distance in km from two coordinates using the sklearn implementations?

like image 628
flyingmeatball Avatar asked Dec 31 '22 20:12

flyingmeatball


1 Answers

So the issue is that sklearn requires everything to be in radians, but the latitude/longitude and radius I have were in degrees/meters respectively. Before using, I needed to do some conversions:

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)
like image 127
flyingmeatball Avatar answered Jan 10 '23 05:01

flyingmeatball