Search code examples
python-3.xcurve-fittingscipy-optimize

Fitting logistic function giving strainght line in python?


I am trying to fit a logistic function to the data below. I am not able to understand why I get a straight line with fitted parameters? Can someone please help me with this?

x = [473,523,573,623,673]
y = [104,103,95,79,83]

x = np.array(x)
y = np.array(y)

def f(x,a,b,c,d):
    return a/(1+np.exp(-c*(x-d))) + b

popt, pcov = opt.curve_fit(f,x,y,method="trf")
y_fit = f(x,*popt)
plt.plot(x,y,'o')
plt.plot(x,y_fit,'-')
plt.show()

Solution

  • A good choice of initial values can make the difference between a successful optimization and one that fails. For this particular problem I would suggest the initial values that you can find in the code below (p0 list). These values allows to properly estimate the covariance.

    Moreover, you don't need to use the trf algorithm since you are not providing any bound (see docs). The Levenberg–Marquardt algorithm is the right tool for this case.

    import numpy as np
    from matplotlib import pyplot as plt
    from scipy.optimize import curve_fit
    
    x = [473, 523, 573, 623, 673]
    y = [104, 103, 95, 79, 83]
    
    x = np.array(x)
    y = np.array(y)
    
    
    def f(x, a, b, c, d):
        return a / (1 + np.exp(-c * (x - d))) + b
    
    p0 = [20.0, 0.0, 0.0, 0.0]
    
    popt, pcov = curve_fit(f, x, y, p0=p0)
    y_fit = f(x, *popt)
    plt.plot(x, y, "o")
    plt.plot(x, y_fit, "-")
    plt.show()
    

    enter image description here

    If possible I would also suggest to increase the number of observations.