Sigmoidal曲线拟合,当y = 0.5时如何得到x的值

时间:2016-05-06 20:42:05

标签: python numpy math scipy mathematical-optimization

我想解决以下函数,以便在拟合之后,我想在x时得到y=0.5的值。

功能:

import numpy as np
from scipy.optimize import curve_fit

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

x_data = [4, 6, 8, 10]
y_data = [0.86, 0.73, 0.53, 0.3]

popt, pcov = curve_fit(sigmoid, x_data, y_data,(28.14,-0.25))

请解释如何使用python执行此操作! 谢谢!

1 个答案:

答案 0 :(得分:1)

当我运行您的代码时,我会收到警告,popt与您的初始猜测(28.14, -0.25)相同。如果您尝试绘制此图,您会发现它基本上是y == 1的直线,根本不适合您的数据:

from matplotlib import pyplot as plt

x = np.linspace(4, 10, 1000)
y = sigmoid(x, *popt)

fig, ax = plt.subplots(1, 1)
ax.hold(True)
ax.scatter(x_data, y_data, s=50, zorder=20)
ax.plot(x, y, '-k', lw=2)

enter image description here

问题是您正在使用b参数的负值进行初始化。请记住,b被否定,因此您实际上会将x次数取幂,这会打破您的分母。相反,您希望使用b值初始化,但可能是c的负值(为了给出负斜率):

popt2, pcov2 = curve_fit(sigmoid, x_data, y_data, (-0.5, 0.1))
y2 = sigmoid(x, *popt2)

ax.plot(x, y2, '-r', lw=2)

enter image description here

要使用非线性优化获得x y == 0.5的值,您需要定义一个目标函数,该函数可以是0.5sigmoid(x, b, c)之差的平方:

def objective(x, b, c):
    return (0.5 - sigmoid(x, b, c)) ** 2

然后,您可以使用scipy.optimize.minimizescipy.optimize.minimize_scalar查找最小化目标函数的x值:

from scipy.optimize import minimize_scalar

res = minimize_scalar(objective, bracket=(4, 10), args=tuple(popt2))
ax.annotate("$y = 0.5$", (res.x, 0.5), (30, 30), textcoords='offset points',
            arrowprops=dict(facecolor='black', shrink=0.05), fontsize='x-large')

enter image description here