gpt4 book ai didi

python - 将 scipy.optimize.curve_fit 与权重一起使用

转载 作者:太空狗 更新时间:2023-10-30 00:17:16 24 4
gpt4 key购买 nike

根据documentation ,参数 sigma 可用于设置拟合中数据点的权重。当参数 absolute_sigma=True 时,这些“描述”1-sigma 错误。

我有一些数据具有不同的人工正态分布噪声:

n = 200
x = np.linspace(1, 20, n)
x0, A, alpha = 12, 3, 3

def f(x, x0, A, alpha):
return A * np.exp(-((x-x0)/alpha)**2)

noise_sigma = x/20
noise = np.random.randn(n) * noise_sigma
yexact = f(x, x0, A, alpha)
y = yexact + noise

如果我想使用 curve_fit 将嘈杂的 y 拟合到 f,我应该设置什么 sigma?这里的文档不是很具体,但我通常会使用 1/noise_sigma**2 作为权重:

p0 = 10, 4, 2
popt, pcov = curve_fit(f, x, y, p0)
popt2, pcov2 = curve_fit(f, x, y, p0, sigma=1/noise_sigma**2, absolute_sigma=True)

不过,它似乎并没有改善合身性。

enter image description here

此选项仅用于通过协方差矩阵更好地解释拟合不确定性吗?这两个告诉我有什么区别?

In [249]: pcov
Out[249]:
array([[ 1.10205238e-02, -3.91494024e-08, 8.81822412e-08],
[ -3.91494024e-08, 1.52660426e-02, -1.05907265e-02],
[ 8.81822412e-08, -1.05907265e-02, 2.20414887e-02]])

In [250]: pcov2
Out[250]:
array([[ 0.26584674, -0.01836064, -0.17867193],
[-0.01836064, 0.27833 , -0.1459469 ],
[-0.17867193, -0.1459469 , 0.38659059]])

最佳答案

至少对于 scipy 版本 1.1.0,参数 sigma 应该等于每个参数的误差。特别是 documentation说:

A 1-d sigma should contain values of standard deviations of errors in ydata. In this case, the optimized function is chisq = sum((r / sigma) ** 2).

在你的情况下会是:

curve_fit(f, x, y, p0, sigma=noise_sigma, absolute_sigma=True)

我浏览了 source代码并验证当您以这种方式指定 sigma 时它最小化 ((f-data)/sigma)**2

作为旁注,这通常是当您知道错误时希望最小化的内容。给定模型 f 观察点 data 的可能性由下式给出:

L(data|x0,A,alpha) = product over i Gaus(data_i, mean=f(x_i,x0,A,alpha), sigma=sigma_i)

如果你取负对数就变成了(直到不依赖于参数的常数因子):

-log(L) = sum over i (f(x_i,x0,A,alpha)-data_i)**2/(sigma_i**2)

这只是卡方。

我编写了一个测试程序来验证 curve_fit 确实返回了正确指定了 sigma 的正确值:

from __future__ import print_function
import numpy as np
from scipy.optimize import curve_fit, fmin

np.random.seed(0)

def make_chi2(x, data, sigma):
def chi2(args):
x0, A, alpha = args
return np.sum(((f(x,x0,A,alpha)-data)/sigma)**2)
return chi2

n = 200
x = np.linspace(1, 20, n)
x0, A, alpha = 12, 3, 3

def f(x, x0, A, alpha):
return A * np.exp(-((x-x0)/alpha)**2)

noise_sigma = x/20
noise = np.random.randn(n) * noise_sigma
yexact = f(x, x0, A, alpha)
y = yexact + noise

p0 = 10, 4, 2

# curve_fit without parameters (sigma is implicitly equal to one)
popt, pcov = curve_fit(f, x, y, p0)
# curve_fit with wrong sigma specified
popt2, pcov2 = curve_fit(f, x, y, p0, sigma=1/noise_sigma**2, absolute_sigma=True)
# curve_fit with correct sigma
popt3, pcov3 = curve_fit(f, x, y, p0, sigma=noise_sigma, absolute_sigma=True)

chi2 = make_chi2(x,y,noise_sigma)

# double checking that we get the correct answer
xopt = fmin(chi2,p0,xtol=1e-10,ftol=1e-10)

print("popt = %s, chi2 = %.2f" % (popt,chi2(popt)))
print("popt2 = %s, chi2 = %.2f" % (popt2, chi2(popt2)))
print("popt3 = %s, chi2 = %.2f" % (popt3, chi2(popt3)))
print("xopt = %s, chi2 = %.2f" % (xopt, chi2(xopt)))

哪些输出:

popt  = [ 11.93617403   3.30528488   2.86314641], chi2 = 200.66
popt2 = [ 11.94169083 3.30372955 2.86207253], chi2 = 200.64
popt3 = [ 11.93128545 3.333727 2.81403324], chi2 = 200.44
xopt = [ 11.93128603 3.33373094 2.81402741], chi2 = 200.44

如您所见,当您将 sigma=sigma 指定为 curve_fit 的参数时,chi2 确实已正确最小化。

至于为什么改进不是“更好”,我不太确定。我唯一的猜测是,如果不指定 sigma 值,您会隐含地假设它们相等,并且在拟合重要的数据部分(峰值)上,误差“大约”相等。

要回答您的第二个问题, sigma 选项不仅用于更改协方差矩阵的输出,它实际上还更改了正在最小化的内容。

关于python - 将 scipy.optimize.curve_fit 与权重一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27696324/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com