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)
In [2]: y[0]
Out[2]: 7.9955238269969806
In [3]: y[48]
Out[3]: 2.0044761730030203
从通用的双极Sigmoid函数:
f(x,m,b)= 2/(1+exp(-b*(x-m))) - 1
有两个参数和两个未知数 - 位移 m
和比例 b
您有两个条件:f(0) = 8,f(48) = 2
针对第一个条件,表达 b
相较于 m
,结合第二个条件编写非线性函数以求解,然后使用 SciPy 中的 fsolve
对其进行数值求解,并恢复出 b
和 m
。
这里提供了类似方法的问题和答案:How to random sample lognormal data in Python using the inverse CDF and specify target percentiles?">
另外,您还可以使用 curve_fit
,如果您有不止两个数据点,则可能会很方便。输出如下:
正如您所看到的,图表包含所需的数据点。我使用了@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()
atan
和atanh
是常用的Sigmoid函数。 - f5r5e5d