使用马哈拉诺比斯距离进行多变量离群值去除

2024-04-15

我的数据有异常值。我怎样才能找到马哈拉诺比斯距离 并用它来删除异常值。


首先让我提出一些一般准则:

  1. 实际上,如果你有很多特征和较少的样本,马哈拉诺比斯算法往往会给出误导性的结果(你可以自己尝试一下),所以你拥有的特征越多,你应该提供的样本就越多。
  2. 协方差矩阵必须是对称 https://en.wikipedia.org/wiki/Symmetric_matrix and 正定 https://en.wikipedia.org/wiki/Positive-definite_matrix为了使算法正常工作,因此您应该在继续之前进行检查。

正如已经提到的,欧几里得度量 https://en.wikipedia.org/wiki/Euclidean_distance无法找到正确的距离,因为它试图获得ordinary直线距离。 因此,如果我们有多维的变量空间中,两个点可能看起来具有相同的距离Mean,但其中之一距离数据云很远(即它是一个异常值).


解决办法是马哈拉诺比斯距离 https://en.wikipedia.org/wiki/Mahalanobis_distance这使得类似的东西特征缩放通过采取特征向量 https://en.wikipedia.org/wiki/Eigenvalues_and_eigenvectors变量而不是原始轴。

它应用以下公式:

where:

  • x is the 观察找到它的距离;
  • m is the mean观察结果;
  • S is the 协方差矩阵 https://en.wikipedia.org/wiki/Covariance_matrix.

复习:

The 协方差 https://en.wikipedia.org/wiki/Covariance代表两个变量之间关系的方向(即正、负或零),因此它显示了一个变量与其他变量的变化相关的强度。


执行

考虑一下这个6x3数据集,其中每一行代表一个样本,每一列代表给定样本的一个特征:

首先,我们需要创建一个协方差矩阵features每个样本的,这就是我们设置参数的原因rowvar to False in the numpy.cov https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.cov.html函数,所以现在每一列代表一个变量:

covariance_matrix = np.cov(data, rowvar=False)  
# data here looks similar to the above table
# in the picture

接下来,我们找到Inverse协方差矩阵的:

inv_covariance_matrix = np.linalg.inv(covariance_matrix)

但在继续之前,我们应该检查,如上所述,矩阵及其逆矩阵是否是对称 and 正定。我们为此使用乔列斯基分解 https://en.wikipedia.org/wiki/Cholesky_decomposition幸运的是,该算法已经在numpy.linalg.cholesky https://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.cholesky.html:

def is_pos_def(A):
    if np.allclose(A, A.T):
        try:
            np.linalg.cholesky(A)
            return True
        except np.linalg.LinAlgError:
            return False
    else:
        return False 

然后我们找到均值m每个特征上的变量(我应该说维度)并将它们保存在一个数组中,如下所示:

vars_mean = []
for i in range(data.shape[0]):
    vars_mean.append(list(data.mean(axis=0)))  
    # axis=0 means each column in the 2D array

请注意,我重复每一行只是为了利用矩阵减法,如下所示。

接下来,我们发现x - m(即微分),但由于我们已经有了向量化vars_mean,我们需要做的就是:

diff = data - vars_mean
# here we subtract the mean of feature
# from each feature of each example

最后,应用这样的公式:

md = []
for i in range(len(diff)):
    md.append(np.sqrt(diff[i].dot(inv_covariance_matrix).dot(diff[i]))) 

请注意以下事项:

  • 协方差矩阵的逆矩阵的维数为:number_of_features x number_of_features
  • 的尺寸diff矩阵与原始数据矩阵类似:number_of_examples x number_of_features
  • 因此,每个diff[i](即行)是1 x number_of_features.
  • 因此根据矩阵乘法规则,得到的矩阵为diff[i].dot(inv_covariance_matrix)1 x number_of_features;当我们再次乘以diff[i]; numpy自动将后者视为列矩阵(即number_of_features x 1);所以最终结果将变成单个值(即不需要转置)。

为了检测异常值,我们应该指定一个threshold;但由于马哈拉诺比斯距离的平方遵循卡方分布,自由度 = 数据集中的特征数量,那么我们可以选择一个阈值,例如 0.1,然后我们可以使用chi2.cdf https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.chi2.html方法来自Scipy, 像这样:

1 - chi2.cdf(square_of_mahalanobis_distances, degree_of_freedom)

因此,任何 (1 - 卡方 CDF) 小于或等于阈值的点都可以归类为异常值。


将所有内容放在一起

import numpy as np


def create_data(examples=50, features=5, upper_bound=10, outliers_fraction=0.1, extreme=False):
    '''
    This method for testing (i.e. to generate a 2D array of data)
    '''
    data = []
    magnitude = 4 if extreme else 3
    for i in range(examples):
        if (examples - i) <= round((float(examples) * outliers_fraction)):
            data.append(np.random.poisson(upper_bound ** magnitude, features).tolist())
        else:
            data.append(np.random.poisson(upper_bound, features).tolist())
    return np.array(data)


def MahalanobisDist(data, verbose=False):
    covariance_matrix = np.cov(data, rowvar=False)
    if is_pos_def(covariance_matrix):
        inv_covariance_matrix = np.linalg.inv(covariance_matrix)
        if is_pos_def(inv_covariance_matrix):
            vars_mean = []
            for i in range(data.shape[0]):
                vars_mean.append(list(data.mean(axis=0)))
            diff = data - vars_mean
            md = []
            for i in range(len(diff)):
                md.append(np.sqrt(diff[i].dot(inv_covariance_matrix).dot(diff[i])))

            if verbose:
                print("Covariance Matrix:\n {}\n".format(covariance_matrix))
                print("Inverse of Covariance Matrix:\n {}\n".format(inv_covariance_matrix))
                print("Variables Mean Vector:\n {}\n".format(vars_mean))
                print("Variables - Variables Mean Vector:\n {}\n".format(diff))
                print("Mahalanobis Distance:\n {}\n".format(md))
            return md
        else:
            print("Error: Inverse of Covariance Matrix is not positive definite!")
    else:
        print("Error: Covariance Matrix is not positive definite!")



def is_pos_def(A):
    if np.allclose(A, A.T):
        try:
            np.linalg.cholesky(A)
            return True
        except np.linalg.LinAlgError:
            return False
    else:
        return False


data = create_data(15, 3, 10, 0.1)
print("data:\n {}\n".format(data))

MahalanobisDist(data, verbose=True)

Result

data:
 [[ 12   7   9]
 [  9  16   7]
 [ 14  11  10]
 [ 14   5   5]
 [ 12   8   7]
 [  8   8  10]
 [  9  14   8]
 [ 12  12  10]
 [ 18  10   6]
 [  6  12  11]
 [  4  12  15]
 [  5  13  10]
 [  8   9   8]
 [106 116  97]
 [ 90 116 114]]

Covariance Matrix:
 [[ 980.17142857 1143.62857143 1035.6       ]
 [1143.62857143 1385.11428571 1263.12857143]
 [1035.6        1263.12857143 1170.74285714]]

Inverse of Covariance Matrix:
 [[ 0.03021777 -0.03563241  0.0117146 ]
 [-0.03563241  0.08684092 -0.06217448]
 [ 0.0117146  -0.06217448  0.05757261]]

Variables Mean Vector:
 [[21.8, 24.6, 21.8], [21.8, 24.6, 21.8], [21.8, 24.6, 21.8], [21.8, 24.6, 21.8], [21.8, 24.6, 21.8], [21.8, 24.6, 21.8], [21.8, 24.6, 21.8], [21.8, 24.6, 21.8], [21.8, 24.6, 21.8], [21.8, 24.6, 21.8], [21.8, 24.6, 21.8], [21.8, 24.6, 21.8], [21.8, 24.6, 21.8], [21.8, 24.6, 21.8], [21.8, 24.6, 21.8]]

Variables - Variables Mean Vector:
 [[ -9.8 -17.6 -12.8]
 [-12.8  -8.6 -14.8]
 [ -7.8 -13.6 -11.8]
 [ -7.8 -19.6 -16.8]
 [ -9.8 -16.6 -14.8]
 [-13.8 -16.6 -11.8]
 [-12.8 -10.6 -13.8]
 [ -9.8 -12.6 -11.8]
 [ -3.8 -14.6 -15.8]
 [-15.8 -12.6 -10.8]
 [-17.8 -12.6  -6.8]
 [-16.8 -11.6 -11.8]
 [-13.8 -15.6 -13.8]
 [ 84.2  91.4  75.2]
 [ 68.2  91.4  92.2]]

Mahalanobis Distance:
 [1.3669401667524865, 2.1796331318432967, 0.7470525416547134, 1.6364973119931507, 0.8351423113609481, 0.9128858131134882, 1.397144258271586, 0.35603382066414996, 1.4449501739129382, 0.9668775289588046, 1.490503433100514, 1.4021488309805878, 0.4500345257064412, 3.239353067840299, 3.260149280200771]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用马哈拉诺比斯距离进行多变量离群值去除 的相关文章

  • scikit-learn 中 ColumnTransformer 的自定义 Transformer 出现问题

    我想在 scikit learn 中创建一个稳定的管道来预处理数据 我试图完成的第一步是估算None对数据框中不同列应用不同策略的值 即用平均值 中位数或其他描述性统计数据替换 但是 我 我开始使用SimpleImputer变压器连同Col
  • goJS 下拉菜单删除项目

    我有简单的 python Flask goJS 图形应用程序 如下所示 节点和链接文本的源是从应用程序的后端加载的 我将它们设置为model modelData像这样的部分 var graphDataString JSON parse di
  • 在Linux中的端口80上运行flask[重复]

    这个问题在这里已经有答案了 也许以前有过这个问题的答案 所以请重定向我 如果是这样的话 我正在考虑在端口 80 上运行 Flask 所以我检查了是否有任何东西正在使用端口 80 因为事实证明端口 80 没有运行 所以当我输入以下内容时 if
  • Python 如果 kwargs 中的 key 并且 key 为 true

    if force in kwargs and kwargs force is True 感觉应该有更好的方法来编写这个条件 因为我重复了键和变量 假设您确实想检查返回的关键字参数是否is True 这是另一种稍微不同的方式 if kwarg
  • matplotlib get_color 用于子图

    我正在按照这里的教程进行操作 https matplotlib org gallery ticks and spines multiple yaxis with spines html https matplotlib org galler
  • 硒网格监听节点端口而不是集线器端口

    对于我的测试 我在不同的端口上本地运行网格和节点 java jar usr bin selenium server jar port 4444 role hub java jar usr bin selenium server jar ro
  • 如何从数据库模式自动生成示例 Django 应用程序?

    我正在评估概念验证应用程序的框架 该应用程序的生命周期约为 30 天 之后它将被遗忘或完全重写 我已确定要从现有数据库模式自动生成示例应用程序 然后调整视觉设计的某些方面 我看过一个演示红宝石 on Rails 它会为数据库中的每个表自动生
  • python 打开相对文件夹中所有以.txt结尾的文件

    我需要打开并解析文件夹中的所有文件 但我必须使用相对路径 类似于 input files 我知道在 JavaScript 中你可以使用 path 库来解决这个问题 我怎样才能在Python中做到这一点 这样您就可以获得路径中的文件列表作为列
  • Pandas cut 方法不包括下限

    我正在尝试对包含 0 到 100 范围内的年龄的数据帧列进行分箱 当我尝试使用垃圾箱来包含零年龄时 它不起作用 这是一个使用包含我的数据范围的列表的演示 pd cut pd Series range 101 0 24 49 74 100 范
  • 确保特定列位于数据框中最后(或第一个)的最快方法是什么

    given df df pd DataFrame np arange 8 reshape 2 4 columns list abcd 假设我需要专栏 b 到最后 我可以做 df a c d b 但是确保给定列位于末尾的最有效方法是什么 这就
  • Python textwrap.wrap 导致 \n 问题

    所以我只是重新格式化了一堆代码以合并textwrap wrap 却发现我所有的 n都消失了 这是一个例子 from textwrap import wrap def wrapAndPrint msg width 25 wrap msg to
  • Web 应用程序框架:C++ 与 Python

    作为一名程序员 我熟悉 Python 和 C 我正在考虑编写自己的简单 Web 应用程序 并且想知道哪种语言更适合服务器端 Web 开发 我正在寻找一些东西 它必须是直观的 我认识到 Wt 存在并且它遵循 Qt 的模型 我讨厌 Qt 的一件
  • 有什么理由不在Python中混合使用多处理和线程模块

    我正在考虑使用Python来实现一个需要大量多线程的程序 另一个要求是它将在桌面上运行 因此拥有许多进程将使应用程序显得混乱且难以杀死 在任务管理器中 因此 我正在考虑使用线程和多处理模块来减少进程数量 据我了解 GIL 仅适用于单个进程
  • Python 多处理:全局对象未正确复制到子级

    前几天我回答了一个关于SO的问题 https stackoverflow com q 67047533 1925388关于并行读取 tar 文件 这是问题的要点 import bz2 import tarfile from multipro
  • 使用 django-profiles 以配置文件形式编辑相关模型

    我在用着Django 配置文件 http bitbucket org ubernostrum django profiles wiki Home在我的应用程序中 因为它为我提供了一些简单的视图 可以帮助我更快地到达我想去的地方 但是 我有一
  • 类型错误:不可散列的类型:pandas 的“切片”

    我有一个 pandas 数据结构 我这样创建 test inputs pd read csv input test csv delimiter 它的形状 print test inputs shape is this 28000 784 我
  • 如何在Python中仅列出顶级目录?

    我希望能够仅列出某个文件夹内的目录 这意味着我不需要列出文件名 也不需要其他子文件夹 让我们看看一个例子是否有帮助 在当前目录中我们有 gt gt gt os listdir os getcwd cx Oracle doc DLLs Doc
  • 在 python 中,VSCode 调试器不会单步执行外部代码。无法弄清楚如何编辑 launch.json 中的“justMyCode”

    我一直在提到https code visualstudio com docs python debugging justmycode https code visualstudio com docs python debugging jus
  • 写入文件的正确方法?

    我想知道这样做是否有什么区别 var1 open filename w write Hello world 并做 var1 open filename w var1 write Hello world var1 close 我发现没有必要
  • Django Python - LDAP 身份验证

    我目前正在研究 Django Python 我的目标是从 Ldap 目录对用户进行身份验证 我确实有 python 代码来访问 ldap 目录并检索信息 Code import ldap try l ldap open ldap forum

随机推荐

  • Windows Phone 8.1 应用程序中按钮的大小不是预期的

    我是 Windows Phone 开发的新手 尝试通过以下代码将 2 个按钮放入网格中
  • 创建 3 个 IEnumerables 的并集时,实现 O(n) 性能的最简单方法是什么?

    说a b c都是List
  • FirePHP 并不总是写入日志消息

    我在 Bootstrap php 中设置了记录器 如下所示 logger new Zend Log if environment gt debug 1 stream fopen var www html rta rta log a fals
  • 如何在 Windows 上获取 Arduino 草图的汇编语言列表?

    我希望能够看到我的 Arduino 草图的汇编语言列表 我怎样才能实现这个目标 Update 我正在 Windows 机器上运行 Arduino 软件 一种方法是使用avr objdump on the elf构建创建的文件 例如 在 OS
  • socket.io - 服务器多次发出

    我已经研究了近两天 似乎找不到答案 我正在尝试构建一个应用程序 在其中使用套接字通知我的前端服务器上发生了某些变化 注意 我没有在前端使用任何操作 因此这使得这个问题与在此线程上找到的问题不同 例如 socket io 多次发出 https
  • 由注释限制的有界类型参数

    在 Java 中 可以使边界类型参数必须从特定的类或接口扩展 例如 public class Box
  • @Html.ValidationSummary() 在 Ajax.BeginForm 中不起作用

    使用有什么问题吗 Html ValidationSummary 里面一个Ajax BeginForm form 我遇到以下情况 但无法验证必填字段 表单刚刚发布 也没有抛出任何错误 这是视图 using Ajax BeginForm Reg
  • 在 scenebuilder 17 中加载自定义组件

    我们正在开发 Javafx 项目 该项目在 Java8 上运行良好 最近 我们用Java17更新了项目 我们能够解决 IDEA 的问题 好像Java 9 之后他们已经严格封装了所有的类 要使用它 我们必须在虚拟机选项中使用 export o
  • RStudio 的早期命令持续发出警告

    我正在努力为此创建一个可重现的示例 但我怀疑其他人会明白我的意思 为什么 R 有时似乎会陷入积压的警告 错误消息中 并且在后续命令之后再次重复 例如 你会收到一些警告消息Bad whatever system choking运行一些代码后
  • 如何在 Windows 上通过 Vim 使用 MinGW make

    我已经在我的机器上安装了 Vim 和 MinGW 所以我尝试创建 Hello World 然后在 Vim 中编译 一切正常 但是当我输入时 make它显示错误 make not recognized as an internal or ex
  • JQuery 菜单无法正常工作

    我正在尝试 Jquery 菜单小部件 但由于某种原因它不起作用 我在浏览器和 JSFiddle 上都尝试过 http jsfiddle net evanevee MANH4 2 http jsfiddle net evanvee MANH4
  • Java 中间隔重复算法的开源实现 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在从事一个项目 其中间隔重复至关重要 但我不是该主题的专家 我害怕重新发明方轮 我的研究指出了两个不
  • 用于 Java 集成测试的 Groovy 是否有更好的替代方案? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我计划使用其编程接口来测试我的基于 Java 的 Web 应用程序 为此 我打算使用它们的 RMI We
  • WEB-INF 在 Java EE Web 应用程序中代表什么? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 互联网上的大多数地方都说它代表WEB INF信息 我比较怀疑 该文件夹包含可执行文件 信息不是一个合适的名字 据我所知 正如你所说 INF 代表
  • 如何从 GTK Builder 检索对象的名称? [复制]

    这个问题在这里已经有答案了 如何获取从 Builder 对象检索的 Gtk Widget 的名称 我特指的是在 Glade 中看到的名字 例如 button1 而不是类的名称 GtkWindow 这个问题与this one https st
  • 基准和处理时间结果的差异

    我一直在尝试对替换数据框中的 NA 的最有效方法进行一些测试 我首先在 100 万行 12 列的数据集上比较 NA 与 0 的替换解决方案 把所有有管道能力的都扔进去microbenchmark我得到以下结果 问题一 有没有办法测试子集左赋
  • Oracle查询将多列转换为一列

    我的表中有 50 列 它只返回一行 我希望 50 列的一行显示为 50 行和 1 列 任何人都可以建议我使用 Oracle 查询吗 您可以使用UNPIVOT对于像这样的一行 仅获取包含值的列 SELECT colvalue FROM SEL
  • 在单独的 cpp 文件中进行 Boost 单元测试

    我想将 Boost 单元测试分成单独的 cpp 文件 例如 Test1 cpp Test2 cpp Test3 cpp 等 这样我就不会在单个 cpp 文件中包含 1000 个测试 到目前为止 当我尝试构建时 我遇到了各种错误 测试1 cp
  • 节或组名称“oracle.manageddataaccess.client”已定义

    将 Oracle ManagedDataAccess dll 从版本 4 121 1 0 更新到版本 4 121 2 0 后 由于我无法使用 NHibernate 保存先前版本中 CLOB 类型的值 因此在客户端计算机上出现以下错误 Sys
  • 使用马哈拉诺比斯距离进行多变量离群值去除

    我的数据有异常值 我怎样才能找到马哈拉诺比斯距离 并用它来删除异常值 首先让我提出一些一般准则 实际上 如果你有很多特征和较少的样本 马哈拉诺比斯算法往往会给出误导性的结果 你可以自己尝试一下 所以你拥有的特征越多 你应该提供的样本就越多