使用Python进行线性拟合时的误差传播

5
假设我对某个独立变量 x 进行多次测量,记录每次测量相对应的因变量 y 的值,并且记录每次测量的不确定性 dy。例如,这可能是这样的:
import numpy as np
x = np.array([1, 2, 3, 4])
y = np.array([4.1, 5.8, 8.1, 9.7])
dy = np.array([0.2, 0.3, 0.2, 0.4]) 

现在假设我期望测量值遵循线性关系 y = mx + b,而我想要确定未测量的x值x_unm对应的y值y_umn。如果我不考虑误差,在Python中进行线性拟合非常容易:
fit_params, residuals, rank, s_values, rcond = np.polyfit(x, y, 1, full=True)
poly_func = np.poly1d(fit_params)

x_unm   # The unmeasured x value
y_unm = poly_func(x_unm)  # The unmeasured x value

我对这种方法有两个问题。第一个是np.polyfit不考虑每个点的误差。第二个是我不知道y_unm的不确定性是什么。
有人知道如何拟合带有误差的数据,以便让我确定y_unm的不确定性吗?
1个回答

1
这是一个可以通过分析解决的问题,但更适合作为数学/统计讨论。例如,请参见(众多来源之一):

https://www.che.udel.edu/pdf/FittingData.pdf

拟合误差可以通过解析计算得出。但需要注意,当考虑到测量误差时,拟合本身是不同的。

在Python中,我不确定是否有内置函数处理错误,但这里有一个使用scipy.optimize.fmin进行最小二乘拟合的示例。

#Calculate Chi^2 function to minimize
def chi_2(params,x,y,sigy):
    m,c=params
    return sum(((y-m*x-c)/sigy)**2)

data_in=(x,y,dy)
params0=[1,0]

q=fmin(chi_2,params0,args=data_in)

为了进行比较,我使用了你的多项式拟合解法和解析解法,并针对你提供的数据绘制了图表。
给定技术的参数结果如下:
使用 fmin 的加权卡方: m=1.94609996 b=2.1312239

Analytic: m=1.94609929078014 b=2.1312056737588647

Polyfit: m=1.91 b=2.15

线性拟合给定数据

以下是完整代码:

import numpy as np
from scipy.optimize import fmin
import matplotlib.pyplot as plt

x = np.array([1, 2, 3, 4])
y = np.array([4.1, 5.8, 8.1, 9.7])
dy = np.array([0.2, 0.3, 0.2, 0.4]) 

#Calculate Chi^2 function to minimize
def chi_2(params,x,y,sigy):
    m,c=params
    return sum(((y-m*x-c)/sigy)**2)

data_in=(x,y,dy)
params0=[1,0]

q=fmin(chi_2,params0,args=data_in)

#Unweighted fit to compare

a=np.polyfit(x,y,deg=1)

#Analytic solution
sx=sum(x/dy**2)
sx2=sum(x**2/dy**2)
s1=sum(1./dy**2)
sy=sum(y/dy**2)
sxy=sum(x*y/dy**2)

ma=(s1*sxy-sx*sy)/(s1*sx2-sx**2)
ba=(sx2*sy-sx*sxy)/(sx2*s1-sx**2)

xplt=np.linspace(0,5,100)
yplt1=xplt*q[0]+q[1]


yplt2=xplt*a[0]+a[1]

yplt3=xplt*ma+ba

plt.figure()
plt.plot(xplt,yplt1,label='Error Weighted',color='black')
plt.plot(xplt,yplt2,label='Non-Error Weighted',color='blue')
plt.plot(xplt,yplt3,label='Error Weighted Analytic',linestyle='--',color='red')
plt.errorbar(x,y,yerr=dy,fmt='ko')
plt.legend()
plt.show()

我们如何确定 y_unm 的不确定度或误差棒? - Edifice

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接