2016-05-06 49 views
-2

我想解决以下函数,以便在拟合后,我想在y=0.5时得到x的值。Sigmoidal曲线拟合,当y = 0.5时如何获得x的值

功能:

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

其中'curve_fit'哪里来的? – piRSquared

+0

@piRSquared它是'scipy.optimize.curve_fit'。 –

+0

[心理测量曲线拟合(Scipy)]的自由运行列表的延迟率和猜测率的可能的重复](http://stackoverflow.com/questions/37044905/generation-of-free-running-list-of-lapse - 速率和猜测率换心理-CU) –

回答

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


要得到的值xy == 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