【问题标题】:Implementing Mahalanobis Distance from scratch in python在python中从头开始实现马氏距离
【发布时间】:2019-12-19 20:42:22
【问题描述】:

我正在从头开始实施马氏距离,但发生了错误。 马氏距离的公式是- 我在下面提供我的代码错误-

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)

错误 - 下图

请帮忙。有没有人可以检查和更正我的代码

【问题讨论】:

标签: python machine-learning jupyter-notebook distance


【解决方案1】:
X = df[['carat', 'depth', 'price']].head(500).values.tolist
Y =df[['carat', 'depth', 'price']].values.tolist

.tolist

它的功能。我认为你需要:

.tolist()

【讨论】:

  • 请注意,如果您使用类型提示,mypy 可能会为您捕获此错误。即def mahalanobis(x: np.array, y: np.array, cov: np.array = None) -> np.array:。 Mypy 会给你一个更有意义的错误。
【解决方案2】:

我要指出你的代码中有很多错误

  1. 在使用 numpy 数组时使用 np.cov 计算协方差,不要重新实现所有内容

  2. np.dot 的第三个参数是输出,所以你应该写 D_square = np.dot( x_minus_mn_with_transpose, inv_covmat, x_minus_mn) 而不是 D_square = np.dot(np.dot(x_minus_mn, inv_covmat), np.transpose(x_minus_mn))

  3. 而不是X = df[['carat', 'depth', 'price']].head(500).values.tolist 使用X = np.asarray(df[['carat', 'depth', 'price']].head(500).values)。如果您使用 numpy,则仅使用 numpy 数组,而不是列表。

这是您提供的代码的修改版本

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)

【讨论】:

  • 你为什么使用 np.transpose(y)
  • 感谢您的帮助,但我也想从头开始实现协方差
  • 因为我们正在计算与我们的特征相关的协方差,所以协方差矩阵的形状应该是 3x3,其中 3 是这里的特征数。 y 的形状为 (num_inputs, num_features),因此传递它会给您一个形状为 (num_inputs, num_inputs) 的协方差矩阵,而我们想要的是一个形状为 (num_features, num_features) 的协方差矩阵
  • 您可以从头开始计算协方差矩阵,只需确保在协方差函数中返回一个 numpy 数组而不是列表。
  • 你能帮我吗
猜你喜欢
  • 2012-04-13
  • 2016-04-21
  • 2013-09-10
  • 1970-01-01
  • 1970-01-01
  • 2012-07-06
  • 2019-08-01
  • 1970-01-01
相关资源
最近更新 更多