我想解决以下函数,以便在拟合之后,我想在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执行此操作! 谢谢!
答案 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)
问题是您正在使用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)
要使用非线性优化获得x
y == 0.5
的值,您需要定义一个目标函数,该函数可以是0.5
和sigmoid(x, b, c)
之差的平方:
def objective(x, b, c):
return (0.5 - sigmoid(x, b, c)) ** 2
然后,您可以使用scipy.optimize.minimize
或scipy.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')