【问题标题】:Fitting a function with a heavyside step function用重质阶跃函数拟合函数
【发布时间】:2017-11-15 12:14:42
【问题描述】:

我正在尝试将函数拟合到下图中的一部分:

我想找出信号开始呈指数增长的时间。为此,我将指数曲线拟合到数据中,并乘以重阶阶跃函数。

def fit(x, a, b, c, d, e):
    return np.heaviside(x-a, 0.5)*b*np.exp(c*x-d)+e

parameter, covariance = curve_fit(fit, fitx, fity)

x = np.linspace(min(fitx), max(fitx), 1000)
plt.plot(fitx, fity)
plt.plot(x, fit(x, *parameter), 'b-', label='fit')
plt.show()

结果是一条直线

当我只拟合指数部分时,我得到下图:

我希望 x 轴是一条直线,然后是图 2 中的指数图。有人知道我哪里出错了吗?

【问题讨论】:

  • 可能你需要为你的参数a提供一个合理的起点。
  • @IgnacioVergaraKausel 帮助很大,谢谢!
  • 我会说 70% 的拟合问题是错误的起点,其余大部分是定义错误的拟合函数。我会把评论作为答案。
  • 你说的指数增长是什么意思?首先它会减少,然后随着一些振荡而增加。你想适合哪一边?如果函数的类型是( 1 - exp( -x ) ),那么阶梯函数是否更适合括号外?此外,拟合阶跃函数总是有点棘手,因为位置偏移小于数据密度不会改变chi**2。不过,SE 上有几篇文章处理这个问题。

标签: python scipy curve-fitting


【解决方案1】:

最有可能的情况是参数的收敛有问题。在大多数情况下,这种收敛问题是由于参数的起点不好。

由于它在没有重载函数的情况下按预期工作,我猜你应该在curve_fit 函数调用中为参数a 提供一个合理的起点。

【讨论】:

  • 为了帮助寻找非线性求解器的起点,scipy 添加了 scipy.optimize.differential_evolution 遗传算法模块。因为它使用拉丁超立方算法来确保对参数空间的彻底搜索,所以它需要对可能的参数值进行搜索,但这些范围可能非常大。我已经使用这个 scipy 模块生成初始参数估计,用于将双洛伦兹峰方程拟合到碳纳米管的拉曼光谱数据:bitbucket.org/zunzuncode/ramanspectroscopyfit
  • 很高兴知道这一点。
【解决方案2】:

您说您想找到“信号开始呈指数增长的时间”,但绘制的信号并未呈指数增长。事实上,它会减少(至少随着时间的增加和从左到右)。并且看起来像峰顶。你的意思是你想为那个drop添加一些功能吗?

我猜高斯可能会很好用。使用阶跃函数也可能没问题,但可能不太适合 t=1e-8 左右。

你没有包含数据或完整的代码,所以很难给出一个具体的例子。但是您可能会发现 lmfit 包在这里很有帮助。它有一个内置的阶梯模型,可以使用线性或误差函数或逻辑曲线。见http://lmfit.github.io/lmfit-py/builtin_models.html#step-like-models。这可能与您想要做的很接近。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-16
    • 2015-10-27
    相关资源
    最近更新 更多