我在两个不同的实验区域内拟合一组实验数据 ( sample ),可以用两个数学函数表示如下:
第一个区域:
y = m*x + c ( the slope can be constrained to zero)
第二个区域:
y = d*exp(-k*x)
实验数据如下图,我用python编码如下:
def func(x, m, c, d, k):
return m*x+ c + d*np.exp(-k*x)
popt, pcov = curve_fit(func, t, y)
不幸的是,我的数据没有正确拟合并且拟合(返回)参数没有意义(见下图)。
我们将不胜感激。
最佳答案
非常有趣的问题。正如 a_guest 所说,您必须分别适应这两个区域。但是,我认为您可能还希望这两个区域在 t0
点平滑连接,我们从一个模型切换到另一个模型的点。为此,我们需要在点 t0
处添加 y1 == y2
的约束。
要使用 scipy
执行此操作,请使用 SLSQP 方法查看 scipy.optimize.minimize
。但是,我写了一个 scipy
包装器来简化这种事情,称为 symfit
。我将向您展示如何使用 symfit
执行此操作,因为我认为它更适合该任务,但是通过这个示例,您也应该能够使用纯 scipy
来实现它如果您愿意。
from symfit import parameters, variables, Fit, Piecewise, exp, Eq
import numpy as np
import matplotlib.pyplot as plt
t, y = variables('t, y')
m, c, d, k, t0 = parameters('m, c, d, k, t0')
# Help the fit by bounding the switchpoint between the models
t0.min = 0.6
t0.max = 0.9
# Make a piecewise model
y1 = m * t + c
y2 = d * exp(- k * t)
model = {y: Piecewise((y1, t <= t0), (y2, t > t0))}
# As a constraint, we demand equality between the two models at the point t0
# to do this, we substitute t -> t0 and demand equality using `Eq`
constraints = [Eq(y1.subs({t: t0}), y2.subs({t: t0}))]
# Read the data
tdata, ydata = np.genfromtxt('Experimental Data.csv', delimiter=',', skip_header=1).T
fit = Fit(model, t=tdata, y=ydata, constraints=constraints)
fit_result = fit.execute()
print(fit_result)
plt.scatter(tdata, ydata)
plt.plot(tdata, fit.model(t=tdata, **fit_result.params).y)
plt.show()
关于python - 拟合两个不同区域内的实验数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52030866/