Входные размеры для функции расстояния для ближайших соседей
В контексте неконтролируемых ближайших соседей с 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)
, Если я напечатаю x
и y
в моем my_mahalanobis_distance
, я получу формы (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,)
, в то время как мое число признаков составляет 4
в X
.
Я использую Python 2.7.10 и scikit-learn 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
неверен. Глядя на x
и y
значения на этой первой итерации, мои наблюдения:
-
x
иy
идентичны -
Если я выполняю свой код несколько раз,
x
иy
по-прежнему идентичны, но их значения изменились по сравнению с предыдущим запуском. -
Эти значения, по-видимому, исходят из функции
numpy.random
.
2 ответа:
Это не ответ, но слишком длинный для комментария. Я не могу воспроизвести ошибку.
Использование:
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)