python - 通过使用 lmfit 优化变量以同时对两条曲线进行最佳拟合
问题描述
假设我们有两条具有相同变量的不同曲线。如何优化变量以同时对两条曲线进行最佳拟合?我可以分别优化每条曲线,但获得的值不一定能为另一条曲线提供最佳拟合。
import numpy as np
from scipy.optimize import minimize
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from lmfit import Model, Parameters
def f(wdata, a, b, c, d):
return ( a+b*wdata + c*d*wdata )
def g(wdata, a, b, c, d):
return ( a**2*(wdata)**2/a*b*wdata*(c)**2 )
wdata = (1, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100)
wdata= np.asarray(wdata)
ydata1 = f(wdata, -19, -60, 9, 100)
ydata2 = g(wdata, -19, -60, 9, 100)
fmodel = Model(f)
gmodel = Model(g)
params = Parameters()
params.add('a', value=-19, max = 0, vary=False)
params.add('b', value=-60, vary=True)
params.add('c', value=9, min = 0, vary=True)
params.add('xangle', value=0.05, vary=True, min=-np.pi/2, max=np.pi/2)
params.add('d', expr='(c*a/b)*sin(xangle)')
resultf = fmodel.fit(ydata1, params, wdata=wdata, method='leastsq')
print(resultf.fit_report())
plt.plot(wdata, ydata1, 'bo')
plt.plot(wdata, resultf.init_fit, 'k--')
plt.plot(wdata, resultf.best_fit, 'r-')
resultg = gmodel.fit(ydata2, params, wdata=wdata, method='leastsq')
print(resultg.fit_report())
plt.plot(wdata, ydata2, 'bo')
plt.plot(wdata, resultg.init_fit, 'k--')
plt.plot(wdata, resultg.best_fit, 'r-')
plt.show()
解决方案
我认为您想要做的是创建一个模型函数,该函数对数组和数据的连接进行建模。也许是这样的:f
g
def f_and_g(wdata, a, b, c, d):
fmodel = f(wdata, a, b, c, d)
gmodel = g(wdata, a, b, c, d)
return np.concatenate((fmodel, gmodel))
# turn that into a model
fg_model = Model(f_and_g)
# same parameters as before:
params = Parameters()
params.add('a', value=-19, max = 0, vary=False)
params.add('b', value=-60, vary=True)
params.add('c', value=9, min = 0, vary=True)
params.add('xangle', value=0.05, vary=True, min=-np.pi/2, max=np.pi/2)
params.add('d', expr='(c*a/b)*sin(xangle)')
# concatenate data to build a 1D array to be modeled:
fdata = f(wdata, -19, -60, 9, 100) + np.normal(scale=0.1, size=len(wdata))
gdata = g(wdata, -19, -60, 9, 100) + np.normal(scale=0.1, size=len(wdata))
fg_data = np.concatenate((fdata, gdata))
# now fit the concatenated data to the concatenated model
result = fg_model.fit(fg_data, params, wdata=wdata, method='leastsq')
print(result.fit_report())
# to plot individual results, you'll have to untangle the concatenated data:
plt.plot(wdata, fdata, 'bo', label='f data')
plt.plot(wdata, result.best_fit[:len(wdata)], 'b--', label='f fit')
plt.plot(wdata, rgdata, 'ro', label='g data')
plt.plot(wdata, result.best_fit[len(wdata):], 'r--', label='g fit')
plt.legend()
plt.show()
这里假设的一件事是f
数据和g
数据是同等规模和重要的。情况并非总是如此。如果不是这种情况,您可能需要为模型添加权重(请参阅 lmfit 文档和示例)。通常,这种加权将反映每个数据点的不确定性变化(即,数据中的标准误差在哪里)weight=1./stderr
。stderr
但是对于多数据集拟合,您可能需要更改它,以便比其他部分更强调一个数据集(甚至一个数据集的一部分)。
推荐阅读
- python-3.x - PyCharm (Python 3.6) 控制台中的全局变量值
- javascript - 将类添加到
- 包含标签的元素
- firebase - 如何在 Firebase 中按关键字过滤?
- javascript - 删除多个数组并更新redux中的状态
- postgresql - PostgreSQL HashAggregate 性能不足
- php - 数据未显示在 jquery DataTable 中
- java - 文件通配符使用 *
- android - Android DialogFlow V2 SDK Java 客户端库 Grpc Google Cloud Platform 从实时音频流中检测意图
- mongodb - MongoDB 关闭并显示代码:12
- feathersjs - 在羽毛钩子中获取内容类型