[SciPy-User] Sigmoid Curve Fitting

Warren Weckesser warren.weckesser at enthought.com
Tue Sep 21 12:16:40 EDT 2010


  On 9/21/10 10:24 AM, Chris Spencer wrote:
> Is it possible to get it to determine the asymptotes as well? It seems
> to assume the curve will be bounded between y=0 and 1, whereas my data
> can have arbitrary limits. I tried changing sigmoid() to:
>
> def sigmoid(x, x0, k, a):
>     y = a * 1 / (1 + np.exp(-k*(x-x0)))
>     return y
>
> but that only results in a curve of f(x)=0.5.
>

The following is a variation that includes more parameters in the family 
of sigmoid functions.  But bear in mind, I chose this family of 
functions just as a demonstration of curve_fit.  I don't know if it 
makes sense to use this family for your data.  The appropriate family to 
use depends on the nature of the data.

-----
import numpy as np
import pylab
from scipy.optimize import curve_fit

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

xdata = np.array([0.0,   1.0,  3.0,  4.3,  7.0,   8.0,   8.5, 10.0,  
12.0, 14.0])
ydata = np.array([0.11, 0.12, 0.14, 0.21, 0.83,  1.45,   1.78,  1.9, 
1.98, 2.02])

popt, pcov = curve_fit(sigmoid, xdata, ydata)
print "Fit:"
print "x0 =", popt[0]
print "k  =", popt[1]
print "a  =", popt[2]
print "c  =", popt[3]
print "Asymptotes are", popt[3], "and", popt[3] + popt[2]

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, 2.05)
pylab.legend(loc='upper left')
pylab.grid(True)
pylab.show()
-----


Warren


> Regards,
> Chris
>
> On Mon, Sep 20, 2010 at 11:54 PM, Warren Weckesser
> <warren.weckesser at enthought.com>  wrote:
>>   On 9/20/10 8:38 PM, Chris Spencer wrote:
>>> Hi,
>>>
>>> Does Scipy contain the ability to fit a sigmoid curve to a set of data
>>> points?
>>>
>>> I found some Numpy code
>>>
>>> (http://pingswept.org/2009/01/24/least-squares-polynomial-fitting-in-python/)
>>> for fitting curves using the least squares method, but it only seems
>>> to fit parabolas to my sigmoid data.
>>>
>> You can use curve_fit (scipy.optimize.curve_fit).
>>
>> Which family of sigmoid functions do you want to use?
>> See http://en.wikipedia.org/wiki/Sigmoid_function for a few possibilities.
>>
>> If, for example, you want to fit the following family to your data:
>>
>> f(x) = 1/(1 + exp(-k*(x-x0)))
>>
>> (which has two parameters, k and x0), you can do something like this:
>>
>> -----
>> import numpy as np
>> 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()
>> -----
>>
>> This script generates the attached plot.
>>
>>
>> Warren
>>
>>
>> _______________________________________________
>> SciPy-User mailing list
>> SciPy-User at scipy.org
>> http://mail.scipy.org/mailman/listinfo/scipy-user
>>
>>
> _______________________________________________
> SciPy-User mailing list
> SciPy-User at scipy.org
> http://mail.scipy.org/mailman/listinfo/scipy-user




More information about the SciPy-User mailing list