【问题标题】:Fitting a sigmoid curve (Python)拟合 sigmoid 曲线 (Python)
【发布时间】:2021-03-21 03:32:52
【问题描述】:

我正在尝试将 sigmoid 曲线和 3 次多项式拟合到我的数据(成本与收入),然后找到拐点/收益递减点。

这是我到目前为止的代码,不太合适。任何建议都会很有帮助,谢谢!

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

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

xdata = [ 404.91,  731.89,  804.23,    0.  ,  954.72,  954.72,  954.72, 744.54,  744.54,  498.5 ,  355.03,
         359.61,    0.  ,    0.  , 0.  ,  753.77, 1116.02,  557.07,  589.06,  761.86,  722.97, 162.69, 
         354.47,  474.  ,  306.83,  538.57,  134.26,  134.26, 134.26,  134.26,  134.26,  652.29, 1296.26,
         547.78,  845.22, 872.62,  881.59,  556.23,  500.2 ,  569.97,  679.46,  679.46, 623.08,  628.33,
         754.88, 2014.12, 1870.43, 1444.69,  826.05, 1071.03,  816.74]
ydata = [ 6986.97, 36591.27, 23702.95,  6380.01, 26873.68, 19398.27,24693.5 , 18435.52, 19066.1 ,  8534.14,  8534.14,  8534.14,
          2032.07,   567.26,  7544.64, 21051.07, 21051.07, 18592.84,18592.84, 18592.84, 19566.14,  4787.51,  7269.55,
         11596.66, 9083.43, 13260.51,  6280.95,  4112.17,  6004.46,  7613.15, 6436.83, 10726.22, 20430.67,  8265.88,
         15344.32, 30246.91,29928.96, 12215.02,  7776.27,  9714.94, 16642.3 , 29493.06,15496.04, 15496.04, 15496.04,
         33397.61, 33397.61, 33397.61, 22525.93, 22525.93, 48941.98]

#fit 3rd order polynomial
p = np.poly1d(np.polyfit(x, y, 3))
second_deriv = p.deriv(2)
inflection = -second_deriv[0]/second_deriv[1]
print("polynomial inflection point:", inflection)

#fitting a sigmoid curve
popt, pcov = curve_fit(sigmoid, xdata, ydata,  method='dogbox', p0=[1000, 0.6])
estimated_k, estimated_x0 = popt
print("sigmoid inflection point:", estimated_x0)

x = np.linspace(0, int(max(xdata)), len(ydata))
y = sigmoid(x, *popt)*max(ydata)

t = np.linspace(0, int(np.max(xdata)), int(np.max(xdata)))
plt.plot(xdata, ydata, 'o', label='data')
plt.plot(p(t), 'b-', label="polynomial")
plt.plot(x,y, label='sigmoid')
plt.legend(loc='best')
plt.show()

【问题讨论】:

    标签: python numpy curve-fitting data-fitting scipy-optimize


    【解决方案1】:

    我在您的帖子中看不到任何问题,因此我将其解释为“我如何才能更好地适应?”。如果不是这种情况,请编辑您的问题。


    据我所知,存在三个问题:

    第一个是 sigmoid 总是介于 0 和 1 之间,因此很难适应那些非常高的值(考虑在 sigmoid 函数中添加一个额外的参数来与结果相乘);

    第二个是“b”的 p0 太高,因此 curve_fit 可能会陷入某些局部最优值(使用您的数据,我发现 0.003-ish 是一个不错的数字);

    最后,使用这些 x 值,您的 sigmoid 函数中的指数非常小(小于 exp(-1000)),这可能会在某些时候导致问题。尝试使这些 x 值更小,或使用 mpmath 之类的东西。

    【讨论】:

    • 除了最后一个都可以。 b 应该是这样的 b*x 将具有合理的值,即指数的参数可能是好的。
    【解决方案2】:

    数据高度分散。根据所选择的拟合标准(最小均方误差,或最小均方相对误差,或最小均方绝对误差等)获得一致的结果是令人怀疑的。同样对于使用迭代方法的常用软件,猜测参数的方便初始值可能是不确定的。

    所以,我站在这里不是要回答您的问题,而是要将您的结果与另一种非常不同且不寻常的拟合方法的结果进行比较。此方法不是迭代的,不需要对参数进行初始猜测。理论见https://fr.scribd.com/doc/14674814/Regressions-et-equations-integrales中的第37-38页

    【讨论】:

      猜你喜欢
      • 2019-06-19
      • 2018-11-20
      • 2014-08-30
      • 2013-11-08
      • 2017-06-20
      • 2019-09-07
      • 2021-08-07
      • 1970-01-01
      • 2020-12-06
      相关资源
      最近更新 更多