你可以用以下方法来解决这个问题KDTree
。这使用scipy
,但是 scikit-learnKDTree https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KDTree.html很相似:
from scipy.spatial import KDTree
from scipy.spatial.distance import euclidean
tree = KDTree(X)
def midpoint(pnt1, pnt2):
return np.array([(pnt1[0] + pnt2[0]) / 2, (pnt1[1] + pnt2[1]) / 2])
tree.query_ball_point(midpoint(p1, p2), euclidean(p1, p2) / 2)
解释:
(Left)想象一个点的二维空间,并且您想要找到与两个灰点最相似的点。 (Right)现在想象一下你可以画出一个长度-D
连接两个灰点的线,为您提供一个新的中点m
和一个具有直径的圆D
去里面搜索。
我们可以建立一个KDTree
我们的数据并查询它以查找某个位置附近的点。它可以泛化为处理单个点的最近邻居、3 个以上示例的中点,或者通过扩展查询半径来“软化”
完整代码:
import numpy as np
from scipy.spatial.distance import euclidean
from scipy.spatial import KDTree
X = np.array([[-0.750,-0.766,-0.546,-0.430,-0.0940,0.186,0.422,0.470,0.0780,-0.458,-0.214], [0.531,0.655,0.803,0.659,-0.421,-0.501,-0.477,-0.305,-0.121,0.403,0.183]]).T
tree = KDTree(X)
def midpoint(pnt1, pnt2):
return np.array([(pnt1[0] + pnt2[0]) / 2, (pnt1[1] + pnt2[1]) / 2])
# Two points from our original data `X`
p1, p2 = X[8], X[9]
# Query the tree with the midpoint and radius (distance / 2) of p1, p2:
most_similar = tree.query_ball_point(midpoint(p1, p2), euclidean(p1, p2) / 2)
print(X[most_similar]) # `most_similar` is a list of indices
# [[-0.214 0.183]] # Returns a point from our original X