Fit sigmoid function ("S" shape curve) to data using Python
After great help from @Brenlla the code was modified to:
def sigmoid(x, L ,x0, k, b):
y = L / (1 + np.exp(-k*(x-x0))) + b
return (y)
p0 = [max(ydata), np.median(xdata),1,min(ydata)] # this is an mandatory initial guess
popt, pcov = curve_fit(sigmoid, xdata, ydata,p0, method='dogbox')
The parameters optimized are L, x0, k, b
, who are initially assigned in p0
, the point the optimization starts from.
-
L
is responsible for scaling the output range from [0,1] to [0,L] -
b
adds bias to the output and changes its range from [0,L] to [b,L+b] -
k
is responsible for scaling the input, which remains in (-inf,inf) -
x0
is the point in the middle of the Sigmoid, i.e. the point where Sigmoid should originally output the value1/2
[since if x=x0, we get 1/(1+exp(0)) = 1/2].
And the result:
user88484
Updated on February 13, 2022Comments
-
user88484 over 2 years
I'm trying to fit a sigmoid function to some data I have but I keep getting:
ValueError: Unable to determine number of fit parameters.
My data looks like this:
My code is:
from scipy.optimize import curve_fit def sigmoid(x): return (1/(1+np.exp(-x))) popt, pcov = curve_fit(sigmoid, xdata, ydata, method='dogbox')
Then I get:
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-5-78540a3a23df> in <module> 2 return (1/(1+np.exp(-x))) 3 ----> 4 popt, pcov = curve_fit(sigmoid, xdata, ydata, method='dogbox') ~\Anaconda3\lib\site-packages\scipy\optimize\minpack.py in curve_fit(f, xdata, ydata, p0, sigma, absolute_sigma, check_finite, bounds, method, jac, **kwargs) 685 args, varargs, varkw, defaults = _getargspec(f) 686 if len(args) < 2: --> 687 raise ValueError("Unable to determine number of fit parameters.") 688 n = len(args) - 1 689 else: ValueError: Unable to determine number of fit parameters.
I'm not sure why this does not work, it seems like a trivial action--> fit a curve to some point. The desired curve would look like this:
Sorry for the graphics.. I did it in PowerPoint...
How can I find the best sigmoid ("S" shape) curve?
UPDATE
Thanks to @Brenlla I've changed my code to:
def sigmoid(k,x,x0): return (1 / (1 + np.exp(-k*(x-x0)))) popt, pcov = curve_fit(sigmoid, xdata, ydata, method='dogbox')
Now I do not get an error, but the curve is not as desired:
x = np.linspace(0, 1600, 1000) y = sigmoid(x, *popt) plt.plot(xdata, ydata, 'o', label='data') plt.plot(x,y, label='fit') plt.ylim(0, 1.3) plt.legend(loc='best')
and the result is:
How can I improve it so it will fit the data better?
UPDATE2
The code is now:
def sigmoid(x, L,x0, k, b): y = L / (1 + np.exp(-k*(x-x0)))+b
But the result is still...