Ненужка, указывающая, что недопустимое значение при расчете нормализованного расстояния махаланоби

Примечание .

Это для домашнего задания в моем классе интеллектуального анализа данных.

Я собираюсь помещать соответствующие фрагменты кода в этот пост SO, но вы можете найти всю мою программу на http://pastebin.com/CzNFbLJ2

Набор данных, который я использую для этой программы, можно найти по адресу http://archive.ics.uci.edu/ml/datasets/Iris


Итак, я получаю: RuntimeWarning: недопустимое значение, встреченное в sqrt return np.sqrt (m)

Я пытаюсь найти среднее расстояние Махаланобиса от данного набора диафрагмы (как для сырых, так и для нормализованных наборов данных). Ошибка происходит только в нормализованной версии набора данных, что заставляет меня задаться вопросом, неправильно ли я понял, что означает нормализация (как в коде, так и математически).

Я думал, что нормализация означает, что каждая компонента вектора делится на его длину вектора (заставляя вектор добавить до 1). Я нашел этот вопрос SO Как нормализовать 2-мерный массив numpy в python менее подробный? и думал, что это соответствует моей концепции нормализации. Но теперь мой код сообщает, что расстояние Махаланобиса над нормализованным набором данных – это NAN

def mahalanobis(data): import numpy as np; import scipy.spatial.distance; avg = 0 count = 0 covar = np.cov(data, rowvar=0); invcovar = np.linalg.inv(covar) for i in range(len(data)): for j in range(i + 1, len(data)): if(j == len(data)): break avg += scipy.spatial.distance.mahalanobis(data[i], data[j], invcovar) count += 1 return avg / count def normalize(data): import numpy as np row_sums = data.sum(axis=1) norm_data = np.zeros((50, 4)) for i, (row, row_sum) in enumerate(zip(data, row_sums)): norm_data[i,:] = row / row_sum return norm_data 

Возможно, слишком поздно, но посмотрите страницу 64-65 в нашем учебнике «Введение в интеллектуальный анализ данных». Существует раздел под названием «Нормализация или стандартизация», в котором объясняется концепция нормализованных данных, которые ищет Херн.

В основном стандартизованный набор данных x '= (x – mean (x)) / standardDeviation (x)

Поскольку я вижу, что вы используете python, вот как это сделать, используя SciPy:

 normalizedData = (data - data.mean(axis=0)) / data.std(axis=0, ddof=1) 

Источник: http://mail.scipy.org/pipermail/numpy-discussion/2011-April/056023.html

Вы можете использовать pdist() для вычисления расстояния без цикла:

 from sklearn import datasets iris = datasets.load_iris() from scipy.spatial.distance import pdist, squareform print squareform(pdist(iris.data, 'mahalanobis')) 

Нормализация в этом контексте, вероятно, означает вычитание среднего и масштабирования, поэтому данные имеют единую ковариационную матрицу.

Однако для масштабирования каждого вектора в вашем наборе данных используйте единицу: norm_data=data/np.sqrt(np.sum(data*data,1))[:,None] .

Вам нужно разделить по норме L2 каждого вектора, что означает возведение в квадрат значения каждого элемента, а затем взятие квадратного корня из суммы. Broadcasting позволяет избежать явного кодирования цикла (см. Ответ на указанный вами вопрос: https://stackoverflow.com/a/8904762/1149913 ).