【问题标题】:Scipy sigmoid curve fittingScipy sigmoid 曲线拟合
【发布时间】:2018-11-20 00:29:07
【问题描述】:

我有一些数据点,想找到一个拟合函数,我想累积高斯 sigmoid 函数会拟合,但我真的不知道如何实现。

这就是我现在拥有的:

import numpy as np
import pylab
from scipy.optimize import curve_fit

def sigmoid(x, a, b):
     y = 1 / (1 + np.exp(-b*(x-a)))
     return y

xdata = np.array([400, 600, 800, 1000, 1200, 1400, 1600])
ydata = np.array([0, 0, 0.13, 0.35, 0.75, 0.89, 0.91])
         
popt, pcov = curve_fit(sigmoid, xdata, ydata)
print(popt)

x = np.linspace(-1, 2000, 50)
y = sigmoid(x, *popt)

pylab.plot(xdata, ydata, 'o', label='data')
pylab.plot(x,y, label='fit')
pylab.ylim(0, 1.05)
pylab.legend(loc='best')
pylab.show()

但我收到以下警告:

.../scipy/optimize/minpack.py:779:OptimizeWarning:无法估计参数的协方差 类别=优化警告)

有人可以帮忙吗? 我也愿意接受任何其他可能性!我只需要以任何方式拟合这些数据的曲线。

【问题讨论】:

  • 如果它可能有一些用处,我使用缩放的 Weibull 累积分布“y = Scale * (1.0 - exp(-(x/b)^a)”非常适合所有数据点)" R-Squared = 0.9978 和 RMSE = 0.01423 使用参数 a = 6.4852359831229389E+00, b = 1.1063972566493285E+03, 和 Scale = 9.0659231615116531E-01
  • 此发行版的 scipy 文档链接以及相关的拟合细节已从我的评论中删除,因此我无法协助使用 scipy 拟合您的数据 - 这是如何 我导出了这些参数值。我不知道如何在没有删除链接的情况下重现我发布的拟合结果。

标签: python scipy curve-fitting


【解决方案1】:

您可以为参数设置一些合理的界限,例如,做

def fsigmoid(x, a, b):
    return 1.0 / (1.0 + np.exp(-a*(x-b)))

popt, pcov = curve_fit(fsigmoid, xdata, ydata, method='dogbox', bounds=([0., 600.],[0.01, 1200.]))

我有输出

[7.27380294e-03 1.07431197e+03]

曲线看起来像

(400,0) 处的第一个点被删除为无用。您可以添加它,但结果不会有太大变化...

更新

注意,边界设置为 ([low_a,low_b],[high_a,high_b]),所以我要求比例在 [0...0.01] 范围内,位置在 [600...1200 ]

【讨论】:

  • 非常感谢!请问你是怎么想出这些界限的?只是通过反复试验?他们到底是做什么的?
  • @JohannaKöllner 不客气。好吧,不完全是通过反复试验。对于位置,它是x,其中曲线将穿过 0.5,因此查看图表,我选择了x 范围,y 大约在 0.2 到 0.8 之间。对于规模,很明显它应该非常小,因为 1 的指数变化大约是 3。所以如果我们从 ~1100 的中心开始,y 是 0.5,然后除以 3 (所以y 约为 0.15),并检查横坐标是否相距 200,那么很明显比例参数必须在 0.005 左右。
  • @JohannaKöllner And what exactly do they do? 你能澄清一下这个问题吗?通常b 是位置参数,a 是比例参数,但要获得真正的意义,我必须知道横坐标的单位,y 是什么,你如何收集/计算它等等。
  • 我以前做过类似的事情,有一些情节没有收敛,或者迭代次数太多,所以我循环了一些起始值的可能性以找到一些东西有效 - 这也是找到平均模型的好方法
【解决方案2】:

您可能已经注意到结果拟合完全不正确。 尝试使用p0 参数将一些不错的初始参数传递给curve_fit

popt, pcov = curve_fit(sigmoid, xdata, ydata, p0=[1000, 0.001])

应该更适合,而且可能也没有警告。

(默认的起始参数为[1, 1];与实际参数相差太远,无法获得良好的拟合。)

【讨论】:

  • 你从哪里得到p0=[1000, 0.001]?您如何确定这些是良好的起始参数?
  • @tommy.carstensen 有两个部分:从函数本身来看,移位a 很容易看出是 1000,因为这大致是上下点之间的中间,因此曲线的拐点。 b 有点难以观察,但是在点上绘制一条固定 a 和 b 的随机曲线,变化 b(例如,10 步),将很快给出 b 的大致估计。所以,有一点手动“拟合”或目测,然后让curve_fit 接管。熟悉要拟合的功能有很大帮助。
猜你喜欢
  • 2021-03-21
  • 2017-04-21
  • 2019-06-19
  • 1970-01-01
  • 2014-08-30
  • 2013-10-10
  • 1970-01-01
  • 2021-11-01
  • 2016-11-29
相关资源
最近更新 更多