1
votes

I am implementing Mahalanobis Distance from scratch but an error occurred. The formula of Mahalanobis Distance is- enter image description here I am providing my code below with error-

from math import*
from decimal import Decimal
import numpy as np

def mahalanobis(x, y, cov=None):
    x_mean = np.mean(x)
    y_mean = np.mean(y)
    y_minus_mn = y - y_mean
    x_minus_mn_with_transpose =np.transpose(x- x_mean)
    Covariance = covar(x, y)
    inv_covmat = np.linalg.inv(Covariance)
    x_minus_mn = x - x_mean
    D_square = np.dot( x_minus_mn_with_transpose, inv_covmat, x_minus_mn)
    return D_square

def covar(x, y):
    x_mean = np.mean(x)
    y_mean = np.mean(y)
    Cov_numerator = sum(((a - x_mean)*(b - y_mean)) for a, b in zip(x, y))
    Cov_denomerator = len(x) - 1
    Covariance = (Cov_numerator / Cov_denomerator)
    return  Covariance

import pandas as pd

filepath = 'https://raw.githubusercontent.com/selva86/datasets/master/diamonds.csv'
df = pd.read_csv(filepath).iloc[:, [0,4,6]]
df.head()

X = df[['carat', 'depth', 'price']].head(500).values.tolist
Y =df[['carat', 'depth', 'price']].values.tolist

mahalanobis(X, Y)

Error - below picture enter image description here

Plz help. Is there anyone who can check and correct my code

2

2 Answers

2
votes
X = df[['carat', 'depth', 'price']].head(500).values.tolist
Y =df[['carat', 'depth', 'price']].values.tolist

.tolist

It's function. I think you need:

.tolist()

1
votes

There are a number of errors in your code that i shall point out

  1. Use np.cov for computing covariance when you are working with numpy arrays, don't reimplement everything

  2. The third argument to np.dot is the output, so instead of D_square = np.dot( x_minus_mn_with_transpose, inv_covmat, x_minus_mn) you should write D_square = np.dot(np.dot(x_minus_mn, inv_covmat), np.transpose(x_minus_mn))

  3. instead of X = df[['carat', 'depth', 'price']].head(500).values.tolist use X = np.asarray(df[['carat', 'depth', 'price']].head(500).values). if your'e using numpy then work with numpy arrays only, not lists.

here is a modified version of the code you provided

import numpy as np

def mahalanobis(x, y, cov=None):
    x_mean = np.mean(x)
    Covariance = np.cov(np.transpose(y))
    inv_covmat = np.linalg.inv(Covariance)
    x_minus_mn = x - x_mean
    D_square = np.dot(np.dot(x_minus_mn, inv_covmat), np.transpose(x_minus_mn))
    return D_square

import pandas as pd

filepath = 'https://raw.githubusercontent.com/selva86/datasets/master/diamonds.csv'
df = pd.read_csv(filepath).iloc[:, [0,4,6]]
df.head()

X = np.asarray(df[['carat', 'depth', 'price']].head(500).values)
Y =np.asarray(df[['carat', 'depth', 'price']].values)

mahalanobis(X, Y)