我使用numpy.polyfit来拟合观察。 polyfit给出了多项式的估计系数,并且还可以提供估计系数的误差协方差矩阵。精细。现在,我想知道是否有办法估计估计曲线周围的+/- 1西格玛不确定性。
我知道MatLab可以做到(https://stats.stackexchange.com/questions/56596/finding-uncertainty-in-coefficients-from-polyfit-in-matlab)但是我找不到在python中制作它的方法。
答案 0 :(得分:5)
如果您有足够的数据点,则可以使用参数cov=True
获得polyfit()
的估计协方差矩阵。请记住,您可以使用p[0]*t**n + p[1]*t**(n-1) + ... + p[n]
将多项式np.dot(tt, p)
写为矩阵乘积tt=[t**n, tt*n-1, ..., 1]
。 t
可以是单个值,也可以是列向量。由于这是一个线性方程,使用C_p
的协方差矩阵p
,值的协方差矩阵为np.dot(tt, np.dot(C_p tt.T))
。
这是一个简单的例子
import numpy as np
import matplotlib.pyplot as plt
# sample data:
x = np.array([0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0])
y = np.array([0.0, 0.8, 0.9, 0.1, -0.8, -1.0, -3.0])
n = 3 # degree of polynomial
p, C_p = np.polyfit(x, y, n, cov=True) # C_z is estimated covariance matrix
# Do the interpolation for plotting:
t = np.linspace(-0.5, 6.5, 500)
# Matrix with rows 1, t, t**2, ...:
TT = np.vstack([t**(n-i) for i in range(n+1)]).T
yi = np.dot(TT, p) # matrix multiplication calculates the polynomial values
C_yi = np.dot(TT, np.dot(C_p, TT.T)) # C_y = TT*C_z*TT.T
sig_yi = np.sqrt(np.diag(C_yi)) # Standard deviations are sqrt of diagonal
# Do the plotting:
fg, ax = plt.subplots(1, 1)
ax.set_title("Fit for Polynomial (degree {}) with $\pm1\sigma$-interval".format(n))
ax.fill_between(t, yi+sig_yi, yi-sig_yi, alpha=.25)
ax.plot(t, yi,'-')
ax.plot(x, y, 'ro')
ax.axis('tight')
fg.canvas.draw()
plt.show()
给出
请注意,计算完整矩阵C_yi
在计算上和记忆方面效率不高。
更新 - 关于@ oliver-w的请求,有关方法论的几句话:
polyfit
假设参数x_i
是确定性的,y_i
是不相关的随机变量,具有预期值y_i
和相同的方差sigma
。因此,它是线性估计问题,并且可以使用普通的最小二乘法。通过确定残基的样本方差,可以近似sigma
。根据{{1}},sigma
的协方差矩阵可以按Wikipedia article on Least Squares所示进行计算。这几乎就是pp
使用的方法:对于polyfit()
,使用了更保守的因子sigma
而不是S/(n-m-2)
。