具有不确定点的最近邻
Nearest neighbors with uncertain points
我有两个二维点集 A
和 B
。我想为 B
中的每个点找到 A
中的第一个最近邻居。
但是,我正在处理不确定的点(即点具有均值(2D 向量)和 2*2 协方差矩阵)。
因此我想使用 Mahalanobis 距离,但是在 scikit-learn
(例如)中,我无法为每个点传递一个协方差矩阵,因为它需要一个协方差矩阵。
目前,仅考虑平均位置(即我的 2D 正态分布的平均值),我有:
nearest_neighbors = NearestNeighbors(n_neighbors=1, metric='l2').fit(A)
distance, indices = nearest_neighbors.kneighbors(B)
由于我的不确定点,与其使用L2范数作为距离,我宁愿计算(在A
中的点a
和B中的点b
之间,他们的马氏距离:
d(a, b) = sqrt( transpose(mu_a-mu_b) * C * (mu_a-mu_b))
其中 C = inv(cov_a + cov_b)
其中mu_a
(respmu_b
)和cov_a
(resp.cov_b
)是不确定点[=17的二维均值和2*2协方差矩阵=](相应的 b
)。
您可以简单地使用列表推导式使用您自己的距离函数来实现 KNN 解决方案。这是一个使用 OpenCV 库中内置的马氏距离实现的示例
import numpy as np
import cv2
np_gallery=np.array(gallery)
np_query=np.array(query)
K=12
ids=[]
def insertionsort(comp_list):
for i in range( 1, len(comp_list)):
tmp = comp_list[i]
k = min(i,K)
while k > 0 and tmp[1] < comp_list[k - 1][1]:
comp_list[k] = comp_list[k - 1]
k -= 1
comp_list[k] = tmp
def search():
for q in np_query:
c = [(i,cv2.Mahalanobis(q, x, icovar)) for i, x in enumerate(np_gallery)]
insertionsort(c)
ids.append(map(lambda tup: tup[0], c[0:K]))
或
def search():
for q in np_query:
c = [(i,cv2.Mahalanobis(q, x, icovar)) for i, x in enumerate(np_gallery)]
ids.append(map(lambda tup: tup[0], sorted(c, key=lambda tup: tup[1])[0:K]))
在第一种情况下,我使用了考虑参数 K 的插入排序变体。当 N >> K
时效率更高
我最终使用了自定义距离:
def my_mahalanobis_distance(x, y):
'''
x: array of shape (4,) x[0]: mu_x_1, x[1]: mu_x_2,
x[2]: cov_x_11, x[3]: cov_x_22
y: array of shape (4,) y[0]: mu_ y_1, y[1]: mu_y_2,
y[2]: cov_y_11, y[3]: cov_y_22
'''
return sp.spatial.distance.mahalanobis(x[:2], y[:2],
np.linalg.inv(np.diag(x[2:])
+ np.diag(y[2:])))
因此一个点有4个特征:
x
和 y
坐标
x
和 y
方差(协方差矩阵在我的例子中是对角线)
我有两个二维点集 A
和 B
。我想为 B
中的每个点找到 A
中的第一个最近邻居。
但是,我正在处理不确定的点(即点具有均值(2D 向量)和 2*2 协方差矩阵)。
因此我想使用 Mahalanobis 距离,但是在 scikit-learn
(例如)中,我无法为每个点传递一个协方差矩阵,因为它需要一个协方差矩阵。
目前,仅考虑平均位置(即我的 2D 正态分布的平均值),我有:
nearest_neighbors = NearestNeighbors(n_neighbors=1, metric='l2').fit(A)
distance, indices = nearest_neighbors.kneighbors(B)
由于我的不确定点,与其使用L2范数作为距离,我宁愿计算(在A
中的点a
和B中的点b
之间,他们的马氏距离:
d(a, b) = sqrt( transpose(mu_a-mu_b) * C * (mu_a-mu_b))
其中 C = inv(cov_a + cov_b)
其中mu_a
(respmu_b
)和cov_a
(resp.cov_b
)是不确定点[=17的二维均值和2*2协方差矩阵=](相应的 b
)。
您可以简单地使用列表推导式使用您自己的距离函数来实现 KNN 解决方案。这是一个使用 OpenCV 库中内置的马氏距离实现的示例
import numpy as np
import cv2
np_gallery=np.array(gallery)
np_query=np.array(query)
K=12
ids=[]
def insertionsort(comp_list):
for i in range( 1, len(comp_list)):
tmp = comp_list[i]
k = min(i,K)
while k > 0 and tmp[1] < comp_list[k - 1][1]:
comp_list[k] = comp_list[k - 1]
k -= 1
comp_list[k] = tmp
def search():
for q in np_query:
c = [(i,cv2.Mahalanobis(q, x, icovar)) for i, x in enumerate(np_gallery)]
insertionsort(c)
ids.append(map(lambda tup: tup[0], c[0:K]))
或
def search():
for q in np_query:
c = [(i,cv2.Mahalanobis(q, x, icovar)) for i, x in enumerate(np_gallery)]
ids.append(map(lambda tup: tup[0], sorted(c, key=lambda tup: tup[1])[0:K]))
在第一种情况下,我使用了考虑参数 K 的插入排序变体。当 N >> K
时效率更高我最终使用了自定义距离:
def my_mahalanobis_distance(x, y):
'''
x: array of shape (4,) x[0]: mu_x_1, x[1]: mu_x_2,
x[2]: cov_x_11, x[3]: cov_x_22
y: array of shape (4,) y[0]: mu_ y_1, y[1]: mu_y_2,
y[2]: cov_y_11, y[3]: cov_y_22
'''
return sp.spatial.distance.mahalanobis(x[:2], y[:2],
np.linalg.inv(np.diag(x[2:])
+ np.diag(y[2:])))
因此一个点有4个特征:
x
和y
坐标x
和y
方差(协方差矩阵在我的例子中是对角线)