python - Scipy ODR 结果与 sd_beta 的巨大相对误差
问题描述
在一些实验数据上运行 ODR 算法时,我被要求使用以下模型运行它:
很明显,这个拟合函数包含一个冗余的自由度。
当我对我的实验数据运行拟合时,我得到了巨大的 beta 相对误差,从 8000% 的相对误差开始。
当我尝试再次运行拟合但使用没有冗余自由度的拟合函数时,例如:
我不明白这种问题。
为什么会这样?为什么 ODR 算法对冗余自由度如此敏感?我无法向我的主管回答这些问题。一个答案将不胜感激。
重现代码示例:from scipy.odr import RealData, Model, ODR
def func1(a, x):
return a[0] * (x + a[1]) / (a[3] * (x + a[1]) + a[1] * x) + a[2]
def func2(a, x):
return a[0] / (x + a[1]) + a[2]
# fmt: off
zx = [
1911.125, 2216.95, 2707.71, 3010.225, 3410.612, 3906.015, 4575.105, 5517.548,
6918.481,
]
dx = [
0.291112577, 0.321695254, 0.370771197, 0.401026507, 0.441068641, 0.490601621,
0.557573268, 0.651755155, 0.79184836,
]
zy = [
0.000998056, 0.000905647, 0.000800098, 0.000751041, 0.000699982, 0.000650532,
0.000600444, 0.000550005, 0.000500201,
]
dy = [
5.49029e-07, 5.02824e-07, 4.5005e-07, 4.25532e-07, 3.99991e-07, 3.75266e-07,
3.50222e-07, 3.25003e-07, 3.00101e-07,
]
# fmt: on
data = RealData(x=zx, y=zy, sx=dx, sy=dy)
print("Func 1")
print("======")
beta01 = [
1.46,
4775.4,
0.01,
1000,
]
model1 = Model(func1)
odr1 = ODR(data, model1, beta0=beta01)
result1 = odr1.run()
print("beta", result1.beta)
print("sd beta", result1.sd_beta)
print("relative", result1.sd_beta / result1.beta * 100)
print()
print()
print("Func 2")
print("======")
beta02 = [
1,
1,
1,
]
model2 = Model(func2)
odr2 = ODR(data, model2, beta0=beta02)
result2 = odr2.run()
print("beta", result2.beta)
print("sd beta", result2.sd_beta)
print("relative", result2.sd_beta / result2.beta * 100)
这打印出来:
Func 1
======
beta [ 1.30884537e+00 -2.82585952e+03 7.79755196e-04 9.47943376e+01]
sd beta [1.16144608e+02 3.73765816e+06 6.12613738e-01 4.20775596e+03]
relative [ 8873.82193523 -132266.24068473 78564.88054498 4438.82627453]
Func 2
======
beta [1.40128121e+00 9.80844274e+01 3.00511669e-04]
sd beta [2.73990552e-03 3.22344713e+00 3.74538794e-07]
relative [0.1955286 3.28640051 0.12463369]
Scipy/Numpy/Python 版本信息:
版本是:
- Scipy - 1.4.1
- 麻木- 1.18.2
- 蟒蛇- 3.7.2
解决方案
问题不在于自由度。
自由度是数据点数与拟合参数数之差。两个公式的问题具有相同数量的自由度,因为它们具有相同数量的参数。看起来你没有自由度,这是个好消息,这意味着它可以被安装。
但是,您是对的,第一个表达式有一些问题:您尝试拟合的参数不是独立的。
用一些更简单的例子可能会更好地理解这一点。
考虑以下表达式:
y = x + b + c
给定和with 的n
数据,您尝试拟合它。x
y
n >> 2
问题是: 和 的最佳值是b
多少c
?这是无法回答的。您可以从数据中说出的所有x
信息y
都是关于组合的。因此,如果b + c
是0
,拟合不能告诉我们是否b = 1000, c = -1000
或b = 1, c= -1
,但至少我们可以说,给定b
我们可以确定c
。给定 的错误是什么b
?潜在无限。这就是拟合给您带来较大相对误差的原因。
推荐阅读
- php - 如何使用 AES/Cryptography 和 Scribe Online API 和 PHP 加密文本
- javascript - 加载应用程序时未通过 AsyncStorage 更新状态
- node.js - 从 mongodb 获取大量数据(~20000 项)并将其显示在 Angular 7 管理产品页面中
- javascript - 接收错误 - 实现 React Spring 基本示例时,只能在函数组件的主体内部调用 Hooks
- android - Android - 这些值对于应用程序是否正常?
- c - 程序不扫描数字 149,对于任何其他数字它返回 0
- react-native - 如何使用 ES6 在 render() 中映射存储在 Redux 中的对象数组
- google-apps-script - 是否可以在收件箱中显示 gmail 附加卡或用户必须单击消息?
- reactjs - 为什么不能在 JSX 中传递数字
- python - 通过根据另一个数据框上的条件选择 pandas 数据框列来创建一个 numpy 数组