5

I try to create a KD tree of WGS84 coordinates and find neighbors within a certain radius

from sklearn.neighbors.dist_metrics import DistanceMetric
from sklearn.neighbors.kd_tree import KDTree    
T = KDTree([[47.8665, 8.90123]], metric=DistanceMetric.get_metric('haversine'))

But get the following error:

ValueError: metric HaversineDistance is not valid for KDTree

How can I use haversine distance in a KD-Tree?

user307380
  • 55
  • 1
  • 4

2 Answers2

4

The k-d-tree can (to the best of my knowledge) only be used with Minkowski norms.

There are other trees such as the ball tree in sklearn, or the covertree in ELKI that work with Haversine distance because it is a metric.

Has QUIT--Anony-Mousse
  • 76,138
  • 12
  • 138
  • 194
  • 1
    You can also use the KDTree but then you have to convert your longitude, latitude pairs to carthesian/euclidean values and convert the distance value back to miles or kilometers than. As far as I know you can also convert longitude and latitude to radians which gives you the distances directly in kilometers. But haven't tested that. – Matthias Aug 16 '17 at 19:39
  • @Matthias: Your first proposal is probably the best solution. With many queries, it will also be much faster than using latitude/longitude and haversine distance. – Eric Duminil Apr 29 '22 at 12:05
0

KDTree.valid_metrics

Output -

['p',
 'l1',
 'chebyshev',
 'manhattan',
 'minkowski',
 'cityblock',
 'l2',
 'euclidean',
 'infinity']

Which tells, you can't use haversine with KDTree. The reason behind it is haversine distance gives you Orthodromic distance which is the distance measure used when your points are represented in a sphere. But in a kdTree the points are organised in a tree which makes it invalid to use.

hashcode55
  • 5,622
  • 4
  • 27
  • 40