KJ1*_*KJ1 5 python curve-fitting scipy
我正在两个不同的实验区域内拟合一组实验数据(样本),可以用两个数学函数表示如下:
第一区域:
y = m*x + c ( the slope can be constrained to zero)
Run Code Online (Sandbox Code Playgroud)
第二区:
y = d*exp(-k*x)
Run Code Online (Sandbox Code Playgroud)
实验数据如下所示,我用python编码如下:
def func(x, m, c, d, k):
return m*x+ c + d*np.exp(-k*x)
popt, pcov = curve_fit(func, t, y)
Run Code Online (Sandbox Code Playgroud)
不幸的是,我的数据没有正确拟合,并且拟合(返回)的参数没有意义(见下图)。
任何帮助将不胜感激。

非常有趣的问题。正如 a_guest 所说,您必须分别适应这两个区域。但是,我认为您可能还希望这两个区域在 点(t0我们从一种模型切换到另一种模型的点)处顺利连接。为了做到这一点,我们需要y1 == y2在点 处添加约束t0。
为了使用 来做到这一点scipy,请查看scipy.optimize.minimizeSLSQP 方法。然而,我编写了一个scipy包装器来使这种事情变得更容易,称为symfit. 我将向您展示如何使用 执行此操作,因为我认为它更适合该任务,但通过此示例,如果您愿意,symfit您也应该能够使用 pure 来实现它。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()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2371 次 |
| 最近记录: |