如何在使用numpy曲线拟合后找到50%点

2 投票
1 回答
542 浏览
提问于 2025-04-17 21:29

我在Python中使用numpy来把我的数据拟合成一个S形曲线。请问在数据拟合完成后,如何找到曲线上y值为50%时对应的x值呢?

enter code here`import numpy as np
enter code here`import pylab
from scipy.optimize import curve_fit

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

xdata = np.array([0.0,   1.0,  3.0, 4.3, 7.0,   8.0,   8.5, 10.0, 12.0])
ydata = np.array([0.01, 0.02, 0.04, 0.11, 0.43,  0.7, 0.89, 0.95, 0.99])

popt, pcov = curve_fit(sigmoid, xdata, ydata)
print popt

x = np.linspace(-1, 15, 50)
y = sigmoid(x, *popt)

pylab.plot(xdata, ydata, 'o', label='data')
pylab.plot(x,y, label='fit')
pylab.ylim(0, 1.05)
pylab.legend(loc='best')
pylab.show()

1 个回答

1

你只需要解决你找到的函数,使得 y(x) = 0.50。你可以使用 scipy中的根查找工具,不过这些工具只能找到零点,所以你需要给你的函数加个偏移量:

def sigmoid(x, x0, k, y0=0):
   y = 1 / (1 + np.exp(-k*(x-x0))) + y0
   return y

接下来,只需调用你选择的根查找方法就可以了:

from scipy.optimize import brentq

a = np.min(xdata)
b = np.max(xdata)
x0, k = popt
y0 = -0.50

solution = brentq(sigmoid, a, b, args=(x0, k, y0))  # = 7.142

关于你的评论:

我上面的代码使用了你代码计算出来的原始 popt。如果你用更新后的 sigmoid 函数(带偏移)进行曲线拟合,popt 也会包含一个适合 y0 的参数。

可能你不想这样……你会希望曲线是以 y0=0 来拟合的。这可以通过给 curve_fit 提供两个值的猜测来实现。这样,sigmoid 函数的默认 y0 值就会被使用:

popt, pcov = curve_fit(sigmoid, xdata, ydata, p0 = (1,1))

另外,你也可以声明两个独立的 sigmoid 函数,一个带偏移,一个不带偏移。

撰写回答