Как рассчитать расстояние Махаланобиса в Python


Расстояние Махаланобиса — это расстояние между двумя точками в многомерном пространстве. Он часто используется для поиска выбросов в статистическом анализе, включающем несколько переменных.

В этом руководстве объясняется, как рассчитать расстояние Махаланобиса в Python.

Пример: расстояние Махаланобиса в Python

Используйте следующие шаги, чтобы вычислить расстояние Махаланобиса для каждого наблюдения в наборе данных в Python.

Шаг 1: Создайте набор данных.

Во-первых, мы создадим набор данных, который отображает экзаменационные баллы 20 студентов, а также количество часов, которые они потратили на учебу, количество сданных подготовительных экзаменов и их текущую оценку по курсу:

import numpy as np
import pandas as pd 
import scipy as stats

data = {'score': [91, 93, 72, 87, 86, 73, 68, 87, 78, 99, 95, 76, 84, 96, 76, 80, 83, 84, 73, 74],
 'hours': [16, 6, 3, 1, 2, 3, 2, 5, 2, 5, 2, 3, 4, 3, 3, 3, 4, 3, 4, 4],
 'prep': [3, 4, 0, 3, 4, 0, 1, 2, 1, 2, 3, 3, 3, 2, 2, 2, 3, 3, 2, 2],
 'grade': [70, 88, 80, 83, 88, 84, 78, 94, 90, 93, 89, 82, 95, 94, 81, 93, 93, 90, 89, 89]
 }

df = pd.DataFrame(data,columns=['score', 'hours', 'prep','grade'])
df.head()

 score hours prep grade
0 91 16 3 70
1 93 6 4 88
2 72 3 0 80
3 87 1 3 83
4 86 2 4 88

Шаг 2: Рассчитайте расстояние Махаланобиса для каждого наблюдения.

Далее мы напишем короткую функцию для вычисления расстояния Махаланобиса.

#create function to calculate Mahalanobis distance
def mahalanobis(x= None , data= None , cov= None ):

 x_mu = x - np.mean(data)
 if not cov:
 cov = np.cov(data.values.T)
 inv_covmat = np.linalg.inv(cov)
 left = np.dot(x_mu, inv_covmat)
 mahal = np.dot(left, x_mu.T)
 return mahal.diagonal()

#create new column in dataframe that contains Mahalanobis distance for each row
df['mahalanobis'] = mahalanobis(x=df, data=df[['score', 'hours', 'prep', 'grade']])

#display first five rows of dataframe
df.head()

 score hours prep grade mahalanobis
0 91 16 3 70 16.501963
1 93 6 4 88 2.639286
2 72 3 0 80 4.850797
3 87 1 3 83 5.201261
4 86 2 4 88 3.828734

Шаг 3: Рассчитайте p-значение для каждого расстояния Махаланобиса.

Мы видим, что некоторые расстояния Махаланобиса намного больше других. Чтобы определить, является ли какое-либо из расстояний статистически значимым, нам нужно рассчитать их p-значения.

Значение p для каждого расстояния рассчитывается как значение p, которое соответствует статистике хи-квадрата расстояния Махаланобиса с k-1 степенями свободы, где k = количество переменных. Итак, в этом случае мы будем использовать степени свободы 4-1 = 3.

from scipy.stats import chi2

#calculate p-value for each mahalanobis distance 
df['p'] = 1 - chi2.cdf(df['mahalanobis'], 3)

#display p-values for first five rows in dataframe
df.head()

 score hours prep grade mahalanobis p
0 91 16 3 70 16.501963 0.000895
1 93 6 4 88 2.639286 0.450644
2 72 3 0 80 4.850797 0.183054
3 87 1 3 83 5.201261 0.157639
4 86 2 4 88 3.828734 0.280562

Обычно выбросом считается p-значение меньше 0,001.Мы видим, что первое наблюдение является выбросом в наборе данных, потому что его значение p меньше 0,001.

В зависимости от контекста проблемы вы можете удалить это наблюдение из набора данных, поскольку оно является выбросом и может повлиять на результаты анализа.