适合双极S型蟒蛇

时间:2017-04-04 16:42:39

标签: python numpy scipy

我试图拟合双极S形曲线 - 我希望得到以下曲线:

enter image description here

但是我需要它移动和伸展。我有以下输入:

x[0] = 8, x[48] = 2

因此超过48个周期我需要使用双极S型函数从8下降到2来近似一个很好的平滑衰减。有什么想法我如何得出适合这些参数的曲线?

这是我到目前为止所做的,但我需要改变sigmoid函数:

import math

def sigmoid(x):
  return 1 / (1 + math.exp(-x))


plt.plot([sigmoid(float(z)) for z in range(1,48)])

3 个答案:

答案 0 :(得分:2)

你可以像这样重新定义sigmoid函数

def sigmoid(x, a, b, c, d):
    """ General sigmoid function
    a adjusts amplitude
    b adjusts y offset
    c adjusts x offset
    d adjusts slope """
    y = ((a-b) / (1 + np.exp(x-(c/2))**d)) + b
    return y

x = np.arange(49)
y = sigmoid(x, 8, 2, 48, 0.3)

plt.plot(x, y)

Severin的答案可能更强大,但如果你想要的只是一个快速而肮脏的解决方案,这应该没问题。

In [2]: y[0]
Out[2]: 7.9955238269969806

In [3]: y[48]
Out[3]: 2.0044761730030203

enter image description here

答案 1 :(得分:1)

来自通用双极S形函数:

f(x,m,b)= 2/(1+exp(-b*(x-m))) - 1

有两个参数和两个未知数 - 转换m和比例b

你有两个条件:f(0)= 8,f(48)= 2

采取第一个条件,表达b vs m,连同第二个条件写非线性函数来解决,然后使用SciPy中的fsolve以数字方式解决它,然后恢复bm

此处通过类似的方法问答:How to random sample lognormal data in Python using the inverse CDF and specify target percentiles?

答案 2 :(得分:1)

或者,您也可以使用curve_fit,如果您有两个以上的数据点,这可能会派上用场。输出如下:

enter image description here

如您所见,图表包含所需的数据点。我使用了@ lanery的功能;你当然可以选择你喜欢的任何功能。这是包含一些内联注释的代码:

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

def sigmoid(x, a, b, c, d):
    return ((a - b) / (1. + np.exp(x - (c / 2)) ** d)) + b

# one needs at least as many data points as parameters, so I just duplicate the data
xdata = [0., 48.] * 2
ydata = [8., 2.] * 2

# plot data
plt.plot(xdata, ydata, 'bo', label='data')

# fit the data
popt, pcov = curve_fit(sigmoid, xdata, ydata, p0=[1., 1., 50., 0.5])

# plot the result
xdata_new = np.linspace(0, 50, 100)
plt.plot(xdata_new, sigmoid(xdata_new, *popt), 'r-', label='fit')
plt.legend(loc='best')
plt.show()