(Python)使用scikits bootstrap估计回归参数置信区间

时间:2013-05-23 06:37:06

标签: python scipy linear-regression scikits

我刚开始尝试通过scikits提供一个很好的自举包: https://github.com/cgevans/scikits-bootstrap

但是我在尝试从线性回归估计相关系数的置信区间时遇到了问题。返回的置信区间完全在原始统计范围之外。

以下是代码:

import numpy as np
from scipy import stats
import bootstrap as boot

np.random.seed(0)
x     = np.arange(10)
y     = 10 + 1.5*x + 2*np.random.randn(10)
r0    = stats.linregress(x, y)[2]

def my_function(y):
    return stats.linregress(x, y)[2]

ci    = boot.ci(y, statfunction=my_function, alpha=0.05, n_samples=1000, method='pi')

这产生ci = [-0.605,0.644]的结果,但原始统计量为r0 = 0.894。

我在R中尝试了这个并且似乎在那里工作得很好:ci如预期的那样跨越了r0。

请帮忙!

1 个答案:

答案 0 :(得分:9)

你能提供你的R代码吗?我很想知道如何在R中处理这个问题。

这里的问题是你只是将y传递给boot.ci,但每次运行my_function时,它都使用整个原始x(注意缺少x输入到my_function)。 Bootstrapping将统计函数应用于重新采样数据,因此,如果您使用原始xy样本来应用统计函数,那么您将获得无意义的结果。这就是为什么BCA方法根本不起作用的原因,实际上:它不能将你的统计函数应用于不具有相同数量元素的折刀样本。

样本沿着轴0(行)进行,因此如果要将多个1D数组传递给统计函数,可以使用多个列:xy = vstack((x,y)).T可以使用,然后使用从中获取数据的统计函数那些专栏:

def my_function(xysample):
    return stats.linregress(xysample[:,0], xysample[:,1])[2]

或者,如果您想避免弄乱数据,可以定义一个对索引进行操作的函数,然后将索引传递给boot.ci:

def my_function2(i):
    return stats.linregress(x[i], y[i])[2]

boot.ci(np.arange(len(x)), statfunction=my_function2, alpha=0.05, n_samples=1000, method='pi')

请注意,在这两种情况下,BCA都有效,因此您也可以使用method =' bca'除非你真的想要使用百分比间隔; BCA几乎总是更好。

我确实意识到这两种方法都不太理想。老实说,我从来没有需要将这样的多个数组传递给我的统计功能,而且大多数人可能会使用mean作为他们的统计功能。我认为这里最好的想法可能是允许传递大小相等的[0]数组列表,例如boot.ci([x,y],...),然后同时对所有这些数组进行采样并将它们全部传递给统计函数参数。在这种情况下,您可以拥有my_function(x,y)。我会看看我是否可以这样做,但是如果你能告诉我你的R代码,那就太棒了,因为我想知道是否有更好的方法可以解决这个问题。


更新

在最新版本的scikits.bootstrap(v0.3.1)中,可以提供一个数组元组,它们的样本将作为独立的参数传递给statfunction。此外,statfunction可以提供数组输出,并且将为输出中的每个点计算置信区间。因此,现在这很容易做到。以下内容将给出linregress的每个输出的置信区间:

cis = boot.ci( (x,y), statfunction=stats.linregress )
在这种情况下,

cis[:,2]将是所需的置信区间。