python - Python LMFIT - 使用有界参数时得到错误的最小化结果
问题描述
现在,我无法minimize
在 LMFIT-Module 中使用。请看下面的案例:
案例一:无约束的参数
import numpy as np
import matplotlib.pyplot as plt
from lmfit import Model, minimize, Parameters, Parameter, report_fit
noise = np.random.randn(100)
def func_model(para, x, data):
''' Model: y = a*sin(2*k*pi*x+theta)'''
a = para['a']
k = para['k']
theta = para['theta']
model= a*np.sin(2*k*np.pi*x+theta)
return model-data # thas's what I want to minimize
def func_noise(x, para):
a, k, theta = para
return a*np.sin(2*k*np.pi*x+theta) + noise
x_steps = np.linspace(-2*np.pi, 0, 100)
para_true = [10, 0.34, np.pi/6]
datas = func_noise(x_steps, para_true)
params = Parameters()
params.add('a', value=7)
params.add('k', value=0.2)
params.add('theta', value=0)
result = minimize(func_model, params, args=(x_steps, datas))
report_fit(result)
得到结果:
a: 10.0054134 +/- 0.14334401 (1.43%) (init = 7)
k: 0.33954301 +/- 0.00110337 (0.32%) (init = 0.2)
theta: 0.52071533 +/- 0.02546636 (4.89%) (init = 0)
与实际参数相比[10, 0.34, pi/6]
,结果是正确的。
案例 2:带约束的参数
只需更改为:
params.add('a', value=7, min=5, max=15) # should be 10
params.add('k', value=0.2, min=0, max=1) # should be 0.34
params.add('theta', value=0)
并保持其他代码相同,然后得到错误的结果:
a: 14.9999918 +/- 51.0737691 (340.49%) (init = 7)
k: 0.01305462 +/- 0.58283692 (4464.60%) (init = 0.2)
theta: -2.90461833 +/- 10.5723936 (363.99%) (init = 0)
怎么会发生?
解决方案
我认为主要问题是k
这里接近 0,这使得拟合过程很难确定其他参数。当参数达到其界限时,算法可能很难摆脱它。在这里看起来它尝试a
了〜15,然后推向k
零,它最终离得很远,它不知道如何解开。
一般来说,根据物理限制设置边界是一个好主意,或者知道拟合将如何响应边界附近的值。也就是说,我真的不知道为什么这个案子如此糟糕。
推荐阅读
- kubernetes - 如何通过 kubernetes api 删除标签?
- azure-devops - azure devops 多级管道中的错误
- ruby-on-rails - 菜鸟学生在 Ruby 上遇到问题
- cordova-plugins - Google Fit 获取历史记录(更新)
- postgresql - 如何生成多值 INSERT 的 postgresql 转储而不是 COPY 并将插入批处理到显式事务中?
- date - 添加秒和纪元以获得日期时间
- reactjs - 如何从本地加载antd字体?
- image - 保持图像纵横比
- typescript - 带有增强类型的 Typescript 属性增强
- javascript - 我怎么能看到我的卷轴是否达到了 ref ?反应