【发布时间】:2014-07-22 17:35:27
【问题描述】:
我是一个相当新的 python/scipy/numpy 并开始使用它,因为 Scipy 的内置 Theil-Sen 估计器函数和 Python 的友好可迭代性。在将我的 python 脚本的结果与其他 Theil-Sen 计算进行比较后,我想我在 scipy.stats.mstats.theilslopes 函数中发现了两个错误。我希望更有经验的程序员/统计学家能证实我的发现。
mstats 源 (https://github.com/scipy/scipy/blob/v0.14.0/scipy/stats/mstats_basic.py#L673) 有(我认为)两个部分有错误。在第一部分,两个系列都必须是浮动的,没有理由掩盖系列的一部分。所以我会修改这段代码:
y = ma.asarray(y).flatten()
y[-1] = masked
n = len(y)
if x is None:
x = ma.arange(len(y), dtype=float)
else:
x = ma.asarray(x).flatten()
...到:
y = ma.asarray(y,dtype=float).flatten()
n = len(y)
if x is None:
x = ma.arange(len(y), dtype=float)
else:
x = ma.asarray(x,dtype=float).flatten()
其次,Theil-Sen 截距的计算似乎存在根本性错误(定义见此处:http://books.google.com/books?id=lK9gHXwYnqgC&pg=PA67#v=onepage&q&f=false)。当前代码计算所有 x 和 y 的中值,然后根据这些值和斜率计算截距。见:
slopes = ma.hstack([(y[i+1:]-y[i])/(x[i+1:]-x[i]) for i in range(n-1)])
slopes.sort()
medslope = ma.median(slopes)
medinter = ma.median(y) - medslope*ma.median(x)
但是,正确的方法是将斜率应用于每个坐标对,然后根据这些值计算中值。所以,我认为正确的代码是:
slopes = ma.hstack([(y[i+1:]-y[i])/(x[i+1:]-x[i]) for i in range(n-1)])
slopes.sort()
medslope = ma.median(slopes)
intercepts = ma.hstack([(y[i] - medslope*x[i]) for i in range(n)])
intercepts.sort()
medinter = ma.median(intercepts)
那么——你们都在外面嗖嗖嗖嗖,你们怎么看?谢谢!
【问题讨论】:
-
4 月份在这方面做了一些工作:github.com/scipy/scipy/pull/3574。看看 github 上 scipy master 分支中的代码。具体来说,向下滚动到github.com/scipy/scipy/blob/master/scipy/stats/mstats_basic.py 和github.com/scipy/scipy/blob/master/scipy/stats/stats.py 中
theilslopes的定义。如果它仍然看起来不对,请在 github 上创建一个问题。 -
感谢您的回复,沃伦。我很欣赏这些链接。尽管声称对截距值存在分歧,但当前的计算不可能是正确的,并且没有得到我读过的任何其他计算方法的支持。所以我会按照你的建议在 github 上开始一个问题。再次感谢!
标签: python numpy scipy bug-reporting