我在哪里可以找到 scipy 中的 mad(平均绝对偏差)?

Posted

技术标签:

【中文标题】我在哪里可以找到 scipy 中的 mad(平均绝对偏差)?【英文标题】:Where can I find mad (mean absolute deviation) in scipy? 【发布时间】:2012-02-14 08:48:15 【问题描述】:

似乎 scipy 曾经提供了一个函数 mad 来计算一组数字的平均绝对偏差:

http://projects.scipy.org/scipy/browser/trunk/scipy/stats/models/utils.py?rev=3473

但是,我在当前版本的 scipy 中找不到它。当然可以只从存储库中复制旧代码,但我更喜欢使用 scipy 的版本。我在哪里可以找到它,或者它已被替换或删除?

【问题讨论】:

抱歉,在github repository 中的搜索没有找到任何结果。 从零开始写有这么难吗? @RomanSusi,不,但正如我在问题中所说,这不是重点。 注意,“MAD”通常指的是“中值绝对偏差”,不是均值差:en.wikipedia.org/wiki/Mean_absolute_difference 【参考方案1】:

不想被误导,疯子现在在 scipy.stats:https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.median_absolute_deviation.html

【讨论】:

你是说它现在是图书馆的一部分吗? @Frank 并不完全清楚你想说什么。请考虑编辑您的答案并添加更多详细信息... @Scratte 是的,它在 scipy.stats 中【参考方案2】:

仅使用numpy

def meanDeviation(numpyArray):
    mean = np.mean(numpyArray)
    f = lambda x: abs(x - mean)
    vf = np.vectorize(f)
    return (np.add.reduce(vf(numpyArray))) / len(numpyArray)

【讨论】:

【参考方案3】:

这不是 scipy 版本,但这是一个使用掩码数组忽略错误值的 MAD 实现: http://code.google.com/p/agpy/source/browse/trunk/agpy/mad.py

编辑:更新的版本可用here。

编辑 2:在 astropy here 中也有一个版本。

【讨论】:

【参考方案4】:

如果你喜欢在Pandas 工作(就像我一样),它有一个有用的function for the mean absolute deviation:

import pandas as pd
df = pd.DataFrame()
df['a'] = [1, 1, 2, 2, 4, 6, 9]
df['a'].mad()

输出:2.3673469387755106

【讨论】:

这是最好的答案。奇怪的是,这不是 numpy 内置的……但既然曾经没有 numpy 就不能拥有 pandas,所以无论如何都应该真正使用 pandas!【参考方案5】:

[编辑] 因为这一直被低估:我知道 median 绝对偏差是一个更常用的统计数据,但提问者要求 mean 绝对偏差,方法如下:

from numpy import mean, absolute

def mad(data, axis=None):
    return mean(absolute(data - mean(data, axis)), axis)

【讨论】:

【参考方案6】:

statsmodels 的当前版本在statsmodels.robust 中有mad

>>> import numpy as np
>>> from statsmodels import robust
>>> a = np.matrix( [
...     [ 80, 76, 77, 78, 79, 81, 76, 77, 79, 84, 75, 79, 76, 78 ],
...     [ 66, 69, 76, 72, 79, 77, 74, 77, 71, 79, 74, 66, 67, 73 ]
...  ], dtype=float )
>>> robust.mad(a, axis=1)
array([ 2.22390333,  5.18910776])

请注意,默认情况下,这会通过缩放结果一个缩放因子来计算假设正态分布的标准偏差的稳健估计;来自help

Signature: robust.mad(a, 
                      c=0.67448975019608171, 
                      axis=0, 
                      center=<function median at 0x10ba6e5f0>)

R 中的版本进行了类似的规范化。如果你不想要这个,显然只需设置c=1

(之前的评论提到这在statsmodels.robust.scale 中。实现在statsmodels/robust/scale.py 中(参见github)但robust 包不导出scale,而是导出@987654334 中的公共函数明确地@。)

【讨论】:

请注意这是中位数,而不是均值绝对偏差(后者是问题所在) @sfjac 好一个。您能否解释一下如何根据常量c=0.67448975019608171 对数组进行缩放?这真的有助于更好地理解它。我无法从 github 页面清楚地理解它。这真的很有帮助。 @SaiKumar 选择这个常数是为了如果数据样本是从高斯总体 N(mu, sigma) 中抽取的,那么得到的统计数据将是对 sigma 的稳健估计。 @sfjac 我没明白,你所说的 sigma 的稳健估计是什么意思。你能解释一下这里的计算是如何进行的吗?如果您执行robust.mad(a, axis=1, c=1),您会得到[1.5,3.5] 的输出,这是正确的MAD,但我们为什么要使用c=0.67 you get array as [2.2239,5.1891]`。我想知道它是如何完成的。它是否与常数相乘?对不起,我是 python 新手。 对。它计算与样本中位数的绝对偏差的中位数。这是独立于分布的分布宽度的稳健估计。如果数据是高斯的,这个值将大约等于高斯的标准偏差除以 0.67。默认情况下,该函数按此 0.67 重新调整结果,并返回一个近似等于标准偏差的统计量。【参考方案7】:

我只是在学习 Python 和 Numpy,但这是我为检查我 7 年级学生的数学作业而编写的代码,该作业需要 2 组数字的 M(ean)AD:

Numpy 矩阵行中的数据:

import numpy as np

>>> a = np.matrix( [ [ 80, 76, 77, 78, 79, 81, 76, 77, 79, 84, 75, 79, 76, 78 ], \\    
... [ 66, 69, 76, 72, 79, 77, 74, 77, 71, 79, 74, 66, 67, 73 ] ], dtype=float )    
>>> matMad = np.mean( np.abs( np.tile( np.mean( a, axis=1 ), ( 1, a.shape[1] ) ) - a ), axis=1 )    
>>> matMad    
matrix([[ 1.81632653],
        [ 3.73469388]])

Numpy 一维数组中的数据:

>>> a1 = np.array( [ 80, 76, 77, 78, 79, 81, 76, 77, 79, 84, 75, 79, 76, 78 ], dtype=float )    
>>> a2 = np.array( [ 66, 69, 76, 72, 79, 77, 74, 77, 71, 79, 74, 66, 67, 73 ], dtype=float )    
>>> madA1 = np.mean( np.abs( np.tile( np.mean( a1 ), ( 1, len( a1 ) ) ) - a1 ) )    
>>> madA2 = np.mean( np.abs( np.tile( np.mean( a2 ), ( 1, len( a2 ) ) ) - a2 ) )    
>>> madA1, madA2    
(1.816326530612244, 3.7346938775510199)

【讨论】:

【参考方案8】:

为了它的价值,我用它来疯狂:

def mad(arr):
    """ Median Absolute Deviation: a "Robust" version of standard deviation.
        Indices variabililty of the sample.
        https://en.wikipedia.org/wiki/Median_absolute_deviation 
    """
    arr = np.ma.array(arr).compressed() # should be faster to not use masked arrays.
    med = np.median(arr)
    return np.median(np.abs(arr - med))

【讨论】:

不错的解决方案;但是,提问者询问的是 mean 绝对偏差。您提供了中值绝对偏差。【参考方案9】:

我正在使用:

from math import fabs

a = [1, 1, 2, 2, 4, 6, 9]

median = sorted(a)[len(a)//2]

for b in a:
    mad = fabs(b - median)
    print b,mad

【讨论】:

样本数为偶数时无效。【参考方案10】:

由于烘焙不足,2008 年 8 月的 scipy.stats.models 似乎是 removed。开发已迁移到statsmodels

【讨论】:

是的,大部分旧的 stats.models 是 scikits.statsmodels 的基础,经过大量清理。 MAD 在底部页面statsmodels.sourceforge.net/rlm.html 作为线性模型稳健估计的一部分,但我从未单独使用它,因为它只有几行。 上面的链接坏了,所以我在 statsmodels 文档上找到了this one。

以上是关于我在哪里可以找到 scipy 中的 mad(平均绝对偏差)?的主要内容,如果未能解决你的问题,请参考以下文章