Одномерное расстояние Махаланобиса в Python - PullRequest
5 голосов
/ 30 марта 2012

Я пытался проверить мой код для вычисления Расстояние Махаланобиса , записанное в Python (и двойная проверка для сравнения результата в OpenCV) Мои данныеточки имеют размерность 1 (5 строк x 1 столбец).

В OpenCV (C ++) мне удалось вычислить расстояние Махаланобиса, когда измерение точки данных было с измерениями выше.

Следующий код был неудачным при расчете расстояния Махаланобиса, когда размерность матрицы составляла 5 строк x 1 столбец. Но это работает, когда число столбцов в матрице превышает 1 :

import numpy;
import scipy.spatial.distance;
s = numpy.array([[20],[123],[113],[103],[123]]);
covar = numpy.cov(s, rowvar=0);
invcovar = numpy.linalg.inv(covar)
print scipy.spatial.distance.mahalanobis(s[0],s[1],invcovar);

Я получаю следующую ошибку:

Traceback (most recent call last):
  File "/home/abc/Desktop/Return.py", line 6, in <module>
    invcovar = numpy.linalg.inv(covar)
  File "/usr/lib/python2.6/dist-packages/numpy/linalg/linalg.py", line 355, in inv
    return wrap(solve(a, identity(a.shape[0], dtype=a.dtype)))
IndexError: tuple index out of range

Ответы [ 2 ]

4 голосов
/ 30 марта 2012

Одномерное расстояние Махаланобиса действительно легко вычислить вручную:

import numpy as np
s = np.array([[20], [123], [113], [103], [123]])
std = s.std()
print np.abs(s[0] - s[1]) / std

(сокращение формулы до одномерного случая).

Нопроблема с scipy.spatial.distance заключается в том, что по какой-то причине np.cov возвращает скаляр, то есть массив нулевого измерения, когда задан набор 1d переменных.Вы хотите передать в 2d массив:

>>> covar = np.cov(s, rowvar=0)

>>> covar.shape
()

>>> invcovar = np.linalg.inv(covar.reshape((1,1)))

>>> invcovar.shape
(1, 1)

>>> mahalanobis(s[0], s[1], invcovar)
2.3674720531046645
0 голосов
/ 19 ноября 2017

Covariance нужно 2 массива для сравнения. В обоих случаях np.cov () и Opencv CalcCovarMatrix ожидает, что эти два массива будут наложены друг на друга (используйте vstack). Вы также можете располагать 2 массива рядом, если вы измените Rowvar на false в numpy или используете COVAR_COL в opencv. Если ваши массивы многомерны, просто сплющите их сначала.

Так что, если я хочу сравнить два изображения 24x24, я объединю их оба в 2 изображения 1x1024, затем сложу их в два, чтобы получить 2x1024, и это первый аргумент np.cov ().

Затем вы должны получить большую квадратную матрицу, где она показывает результаты сравнения каждого элемента в массиве 1 с каждым элементом в массиве 2. В моем примере это будет 1024x1024. Это то, что вы передаете в свою функцию инвертирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...