【问题标题】:optimization of variables to have the best fit for two curves at the same time, by using lmfit通过使用 lmfit 优化变量以同时对两条曲线进行最佳拟合
【发布时间】:2019-08-13 23:58:44
【问题描述】:

假设我们有两条具有相同变量的不同曲线。如何优化变量以同时对两条曲线进行最佳拟合?我可以分别优化每条曲线,但获得的值不一定能为另一条曲线提供最佳拟合。

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()

【问题讨论】:

  • 你可以阅读多目标最大化。一个简单的事情就是优化误差函数的总和。

标签: python optimization curve-fitting lmfit


【解决方案1】:

我认为您想要做的是创建一个模型函数,该模型函数对 连接 fg 数据的数组进行建模。也许是这样的:

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 是数据中的标准误差)。但是对于多数据集拟合,您可能需要对其进行更改,以便比其他部分更强调一个数据集(甚至是一个数据集的一部分)。

【讨论】:

    猜你喜欢
    • 2018-07-27
    • 2015-07-04
    • 1970-01-01
    • 2021-11-01
    • 2020-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多