Python Numpy多边形拟合:协方差矩阵缩放中可能存在的错误?

Python Numpy多边形拟合:协方差矩阵缩放中可能存在的错误?,python,numpy,Python,Numpy,我很难计算出numpy多边形拟合中协方差矩阵的比例 在本文中,我了解到从未标度到标度协方差矩阵的标度因子是 chi2 / sqrt(N - DOF). 在下面附带的代码中,比例因子实际上是 chi2 / DOF 这是我的密码 # Generate synthetically the data # True parameters import numpy as np true_slope = 3 true_intercept = 7 x_data = np.linspace(-5, 5,

我很难计算出numpy多边形拟合中协方差矩阵的比例

在本文中,我了解到从未标度到标度协方差矩阵的标度因子是

chi2 / sqrt(N - DOF).
在下面附带的代码中,比例因子实际上是

chi2 / DOF
这是我的密码

# Generate synthetically the data
# True parameters
import numpy as np

true_slope = 3
true_intercept = 7

x_data = np.linspace(-5, 5, 30)

# The y-data will have a noise term, to simulate imperfect observations
sigma = 1
y_data = true_slope * np.linspace(-5, 5, 30) + true_intercept
y_obs = y_data + np.random.normal(loc=0.0, scale=sigma, size=x_data.size)

# Here I generate artificially some unequal uncertainties 
# (even if there is no reason for them to be so)
y_uncertainties = sigma * np.random.normal(loc=1.0, scale=0.5*sigma, size=x_data.size)

# Make the fit
popt, pcov = np.polyfit(x_data, y_obs, 1, w=1/y_uncertainties, cov='unscaled')
popt, pcov_scaled = np.polyfit(x_data, y_obs, 1, w=1/y_uncertainties, cov=True)

my_scale_factor = np.sum((y_obs - popt[0] * x_data  - popt[1])**2 / y_uncertainties**2)\
                         / (len(y_obs)-2)

scale_factor =  pcov_scaled[0,0] / pcov[0,0]
如果我运行代码,我会看到实际的比例因子是chi2/DOF,而不是文档中报告的值。这是真的还是我遗漏了什么

我还有一个问题。在不确定度为正态分布的情况下,为什么建议仅使用y数据误差的倒数而不是y数据误差倒数的平方作为权重

编辑以添加运行代码生成的数据

x_data = array([-5.        , -4.65517241, -4.31034483, -3.96551724, -3.62068966,
   -3.27586207, -2.93103448, -2.5862069 , -2.24137931, -1.89655172,
   -1.55172414, -1.20689655, -0.86206897, -0.51724138, -0.17241379,
    0.17241379,  0.51724138,  0.86206897,  1.20689655,  1.55172414,
    1.89655172,  2.24137931,  2.5862069 ,  2.93103448,  3.27586207,
    3.62068966,  3.96551724,  4.31034483,  4.65517241,  5.        ])

y_obs = array([-7.27819725, -8.41939411, -3.9089926 , -5.24622589, -3.78747379,
   -1.92898727, -1.375255  , -1.84388812, -0.37092441,  0.27572306,
    2.57470918,  3.860485  ,  4.62580789,  5.34147103,  6.68231985,
    7.38242258,  8.28346559,  9.46008873, 10.69300274, 12.46051285,
   13.35049975, 13.28279961, 14.31604781, 16.8226239 , 16.81708308,
   18.64342284, 19.37375515, 19.6714002 , 20.13700708, 22.72327533])

y_uncertainties = array([ 0.63543112,  1.07608924,  0.83603265, -0.03442888, -0.07049299,
    1.30864191,  1.36015322,  1.42125414,  1.04099854,  1.20556608,
    0.43749964,  1.635056  ,  1.00627014,  0.40512511,  1.19638787,
    1.26230966,  0.68253139,  0.98055035,  1.01512232,  1.83910276,
    0.96763007,  0.57373151,  1.69358475,  0.62068133,  0.70030971,
    0.34648312,  1.85234844,  1.18687269,  1.23841579,  1.19741206])
通过这些数据,我获得了
比例系数=1.6534129347542432
我的比例系数=1.653412934754234
,以及文件中报告的“标称”比例系数,即

nominal_scale_factor = np.sum((y_obs - popt[0] * x_data  - popt[1])**2 /\  
                               y_uncertainties**2) / np.sqrt(len(y_obs) - len(y_obs) + 2)
具有值<代码>标称比例系数=32.735905145554

我的numpy版本是
1.18.5 3.7.7(默认值,2020年5月6日11:45:54)[MSC v.1916 64位(AMD64)]
关于
numpy.polyfit
文档:

默认情况下,协方差按chi2/sqrt(N-dof)进行缩放,即,假定权重不可靠,除非是在相对意义上,并且所有内容都按比例缩放,以使减少的chi2为单位

这看起来像是一个文档错误。协方差的正确比例因子为
chi_square/(N-M)
,其中
M
是拟合参数的数量,
N-M
是自由度的数量。看起来像是
np。由于
my\u scale\u factor
scale\u factor
是一致的,因此polyfit
的实现是正确的

关于为什么不“y数据误差的倒数平方”的问题:多项式拟合或更一般地说,最小二乘拟合涉及求解

A @ p = y
其中,
A
y
中的
N
数据点和
p
中的
M
元素的
(N,M)
矩阵,
A
中的每列是在相应的
x
值处计算的多项式项

解决方案最小化了

    (SUM_j A[i, j] p[j] - y[i])^2
SUM -----------------------------
 i           sigma_y[i]^2

在计算上,最便宜的计算方法是将
A
y
中的每一行乘以相应的
1/sigma_y
,然后取
A@p=y
方程。通过让用户提供反向错误,可以避免fit例程处理零除法问题和缓慢的平方根操作。

关于第一部分,我打开了一个Github问题

该线程的结论是文档错误,但函数的行为正确

文件应更新至

默认情况下,协方差按chi2/dof进行缩放,即,假定权重不可靠,除非是在相对意义上,并且所有内容都按比例缩放,以使减少的chi2为单位


如果我用
np.\uuuuu version\uuuuuu='1.18.1'
)运行这个函数,
myuu-scale\u-factor
scale\u-factor
总是有相同的值,尽管这个值因随机种子而异,所以它与除以
N-nDOF
是一致的@Han KwangNienhuys你能更清楚地解释一下吗?比例因子的公式是确定的,所以它要么是对的,要么是错的……请您提供代码生成的数字,并解释为什么它们不是您期望的数字?@Han Kwangniennhuys我将数据添加到主帖子中您的
nominal_scale_factor
表达式会产生错误<代码>镜头(y_obs)看起来可疑。关于第二个问题,这个很好的答案的平方根也是。我必须注意到,关于这一部分的文档有点草率/不清楚。