适合双极Sigmoid的Python代码

4

我在尝试拟合一个双极S形曲线,我想要以下的曲线:

enter image description here

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

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

我需要使用双极Sigmoid函数在48个周期内将数值从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)])

atanatanh是常用的Sigmoid函数。 - f5r5e5d
3个回答

3
你可以重新定义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

从通用的双极Sigmoid函数:

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

有两个参数和两个未知数 - 位移 m 和比例 b

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

针对第一个条件,表达 b 相较于 m,结合第二个条件编写非线性函数以求解,然后使用 SciPy 中的 fsolve 对其进行数值求解,并恢复出 bm

这里提供了类似方法的问题和答案:How to random sample lognormal data in Python using the inverse CDF and specify target percentiles?">


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()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接