我需要适合像这样的tanh曲线:
import numpy as np
import matplotlib.pyplot as plt
from lmfit import Model
def f(x, a1=0.00010, a2=0.00013, a3=0.00013, teta1=1, teta2=0.00555, teta3=0.00555, phi1=-50, phi2=600, phi3=-900,
a=0.000000019, b=0):
formule = a1 * np.tanh(teta1 * (x + phi1)) + a2 * np.tanh(teta2 * (x + phi2)) + a3 * np.tanh(
teta3 * (x + phi3)) + a * x + b
return formule
# generate points used to plot
x_plot = np.linspace(-10000, 10000, 1000)
gmodel = Model(f)
result = gmodel.fit(f(x_plot), x=x_plot, a1=1,a2=1,a3=1,teta1=1,teta2=1,teta3=1,phi1=0,phi2=0,phi3=0)
plt.plot(x_plot, f(x_plot), 'bo')
plt.plot(x_plot, result.best_fit, 'r-')
plt.show()
我尝试做那样的事,但我得到了这个结果:
还有另一种方法可以拟合这条曲线吗?我不知道我做错了什么?
4 回答
你的功能有点混乱,你没有真正的功能值 . 你基本上想要适应你自己的功能 . 理想情况下,您希望用真实的实验数据替换
curve_fit()
中的f(x_plot)
.适合函数的好方法是使用
scipy.optimize.curve_fit
结果看起来像这样
与真实数据:
我试试这个:
R平方:0.9978,不完美,但不是那么糟糕
enter image description here
基本上你的拟合很好(虽然从编码的角度来看不是很好) . 像往常一样,非线性拟合强烈依赖于初始参数 . 你的选择很糟糕 . 您可以考虑如何手动确定它们,或者使用
differential_evolution
中的differential_evolution
预制包 . 我没有使用这个包,但你可以在SE上找到一个例子here我同意mikuszefski和F. Win的答案,但我想补充一点 .
您的模型包括3行tanh函数 . 数据支持许多不同的tanh功能并不完全清楚 . 如果是这样(并回应mikuszefki),你需要告诉它们这些不相同 . 你的例子开始它们是相同的,这将使适合找到一个好的解决方案非常困难 . 无论哪种方式,能够轻松测试是否真的有1,2,3或更多tanh函数可能会有所帮助 .
您可能还希望不仅为参数提供初始值,还要为它们提供真实的边界,以便tanh函数清晰分离,并且不会偏离它们应该的位置太远 .
要清理代码并更好地允许您更改使用的tanh函数的数量并放置边界约束,我建议制作单独的模型并将其添加为:
现在您可以轻松创建参数了
通过定义fit参数,您可以使用以下边界放置边界:
我认为所有这些都将帮助您更好地探索数据及其适应性 . 把这一切放在一起,你可能会:
这将给出良好的拟合和绘图,并在噪声水平内找到预期值 . 希望有助于您指出正确的方向 .