最近邻居的距离函数的输入维度



scikit-learn的无监督最近邻居的上下文中,我实现了自己的距离函数来处理我的不确定点(即,点表示为正态分布):

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 
'''     
cov_inv = np.linalg.inv(np.diag(x[:2])+np.diag(y[:2]))
return sp.spatial.distance.mahalanobis(x[:2], y[:2], cov_inv)

然而,当我设置我最近的邻居:

nnbrs = NearestNeighbors(n_neighbors=1, metric='pyfunc', func=my_mahalanobis_distance)
nearest_neighbors = nnbrs.fit(X)

其中X(N, 4) (n_samples, n_features)阵列,如果我在my_mahalanobis_distance中打印xy,我会得到(10,)的形状,而不是我所期望的(4,)

示例:

我在my_mahalanobis_distance中添加以下行:

print(x.shape)

然后在我的主要:

n_features = 4
n_samples = 10
# generate X array:
X = np.random.rand(n_samples, n_features)
nnbrs = NearestNeighbors(n_neighbors=1, metric='pyfunc', func=my_mahalanobis_distance)
nearest_neighbors = nnbrs.fit(X)

结果是:

(10,)
ValueError: shapes (2,) and (8,8) not aligned: 2 (dim 0) != 8 (dim 0)

我完全理解这个错误,但我不明白为什么我的x.shape(10,),而我的特征数量是X中的4

我正在使用Python 2.7.10scikit学习0.16.1

编辑:

return sp.spatial.distance.mahalanobis(x[:2], y[:2], cov_inv)替换为return 1仅用于测试返回:

(10,)
(4,)
(4,)
(4,)
(4,)
(4,)
(4,)
(4,)
(4,)
(4,)
(4,)

因此,只有对my_mahalanobis_distance的第一次调用是错误的。查看第一次迭代中的xy值,我的观察结果是:

  • xy是相同的

  • 如果我多次运行代码,xy仍然相同,但与上次运行相比,它们的值发生了变化。

  • 这些值似乎来自CCD_ 23函数。

我得出结论,这样的第一个调用是一段未删除的调试代码。

这不是一个答案,但对于注释来说太长了。我无法重现这个错误。

使用:

Python 3.5.2和Sklearn 0.18.1

代码:

from sklearn.neighbors import NearestNeighbors
import numpy as np
import scipy as sp
n_features = 4
n_samples = 10
# generate X array:
X = np.random.rand(n_samples, n_features)

def my_mahalanobis_distance(x, y):    
cov_inv = np.linalg.inv(np.diag(x[:2])+np.diag(y[:2]))
print(x.shape)
return sp.spatial.distance.mahalanobis(x[:2], y[:2], cov_inv)
n_features = 4
n_samples = 10
# generate X array:
X = np.random.rand(n_samples, n_features)
nnbrs = NearestNeighbors(n_neighbors=1, metric=my_mahalanobis_distance)
nearest_neighbors = nnbrs.fit(X)

输出为

(4,)
(4,)
(4,)
(4,)
(4,)
(4,)
(4,)
(4,)
(4,)
(4,)

我自定义了my_mahalanobis_distance来处理这个问题:

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 
'''     
if (x.size, y.size) == (4, 4):        
return sp.spatial.distance.mahalanobis(x[:2], y[:2], 
np.linalg.inv(np.diag(x[2:]) 
+ np.diag(y[2:])))
# to handle the buggy first call when calling NearestNeighbors.fit()
else:
warnings.warn('x and y are respectively of size %i and %i' % (x.size, y.size))
return sp.spatial.distance.euclidean(x, y)

相关内容

  • 没有找到相关文章

最新更新