7

我有一个奇怪的情况, scipy.stats.linregress 似乎返回了一个不正确的标准错误:

from scipy import stats
x = [5.05, 6.75, 3.21, 2.66]
y = [1.65, 26.5, -5.93, 7.96]
gradient, intercept, r_value, p_value, std_err = stats.linregress(x,y)
>>> gradient
5.3935773611970186
>>> intercept
-16.281127993087829
>>> r_value
0.72443514211849758
>>> r_value**2
0.52480627513624778
>>> std_err
3.6290901222878866

而 Excel 返回以下内容:

 slope: 5.394

 intercept: -16.281

 rsq: 0.525

 steyX: 11.696

steyX 是 excel 的标准误差函数,返回 11.696 而 scipy 的 3.63。有人知道这里发生了什么吗?在不使用 Rpy的情况下,是否有任何替代方法可以在 python 中获得回归的标准错误?

4

5 回答 5

8

SciPy 用户组刚刚通知我,这里的 std_err 代表梯度线的标准误差,而不是根据 Excel 预测的 y 的标准误差。不过这个函数的用户应该小心,因为这并不总是这个库的行为 - 它曾经完全像 Excel 一样输出,并且在过去几个月中似乎已经发生了转换。

无论如何,仍然在 Python 中寻找与 STEYX 等价的东西。

于 2010-01-10T22:15:07.843 回答
6

你可以试试statsmodels包:

In [37]: import statsmodels.api as sm

In [38]: x = [5.05, 6.75, 3.21, 2.66]

In [39]: y = [1.65, 26.5, -5.93, 7.96]

In [40]: X = sm.add_constant(x) # intercept

In [41]: model = sm.OLS(y, X)

In [42]: fit = model.fit()

In [43]: fit.params
Out[43]: array([  5.39357736, -16.28112799])

In [44]: fit.rsquared
Out[44]: 0.52480627513624789

In [45]: np.sqrt(fit.mse_resid)
Out[45]: 11.696414461570097
于 2010-01-11T05:36:16.650 回答
2

是的,这是真的——梯度的标准估计是 linregress 返回的;但是,估计值 (Y) 的标准估计值是相关的,您可以通过乘以 linregress 给您的梯度 (SEG) 的标准误差来返回 SEE:SEG = SEE / sqrt( (X - 平均值的总和) X)**2)

Stack Exchange 不处理乳胶,但如果您有兴趣,数学就在这里,在“分析样本数据”标题下。

于 2018-02-06T18:34:06.043 回答
1

这将为您提供与使用 python 的 STEYX 的等价物:

fit = np.polyfit(x,y,deg=1)
n = len(x)
m = fit[0]
c = fit[1]
y_pred = m*x+c
STEYX = (((y-y_pred)**2).sum()/(n-2))**0.5
print(STEYX)
于 2019-09-07T15:56:56.467 回答
0

excel中“std err on y”的计算实际上是y值的标准差

这与 x 上的 std err 相同。最后一步中的数字“2”是您给出的示例的自由度。

>>> x = [5.05, 6.75, 3.21, 2.66]
>>> y = [1.65, 26.5, -5.93, 7.96]
>>> def power(a):
        return a*5.3936-16.2811

>>> y_fit = list(map(power,x))
>>> y_fit
[10.956580000000002, 20.125700000000005, 1.032356, -1.934123999999997]
>>> var = [y[i]-y_fit[i] for i in range(len(y))]
>>> def pow2(a):
        return a**2

>>> summa = list(map(pow2,var))
>>> summa
[86.61243129640003, 40.63170048999993, 48.47440107073599, 97.89368972737596]
>>> total = 0
>>> for i in summa:
        total += i
>>> total
273.6122225845119
>>> import math
>>> math.sqrt(total/2)
11.696414463084658
于 2019-02-22T16:48:58.920 回答