0

I am experimenting with Python to fit curves to a series of data-points, summary below:

enter image description here

From the below, it would seem that polynomials of order greater than 2 are the best fit, followed by linear and finally exponential which has the overall worst outcome.

While I appreciate this might not be exponential growth, I just wanted to know whether you would expect the exponential function perform so badly (basically the coefficient of x,b, has been set to 0 and an arbitrary point has been picked on the curve to intersect) or if I have somehow done something wrong in my code to fit.

The code I'm using to fit is as follows:

# Fitting
def exponenial_func(x,a,b,c):
    return a*np.exp(-b*x)+c

def linear(x,m,c):
    return m*x+c

def quadratic(x,a,b,c):
    return a*x**2 + b*x+c

def cubic(x,a,b,c,d):
    return a*x**3 + b*x**2 + c*x + d

x = np.array(x)
yZero = np.array(cancerSizeMean['levelZero'].values)[start:]

print len(x)
print len(yZero)

popt, pcov = curve_fit(exponenial_func,x, yZero, p0=(1,1,1))
expZeroFit = exponenial_func(x, *popt)
plt.plot(x, expZeroFit, label='Control, Exponential Fit')

popt, pcov = curve_fit(linear, x, yZero, p0=(1,1))
linearZeroFit = linear(x, *popt)
plt.plot(x, linearZeroFit, label = 'Control, Linear')

popt, pcov = curve_fit(quadratic, x, yZero, p0=(1,1,1))
quadraticZeroFit = quadratic(x, *popt)
plt.plot(x, quadraticZeroFit, label = 'Control, Quadratic')

popt, pcov = curve_fit(cubic, x, yZero, p0=(1,1,1,1))
cubicZeroFit = cubic(x, *popt)
plt.plot(x, cubicZeroFit, label = 'Control, Cubic')

*Edit: curve_fit is imported from the scipy.optimize package

from scipy.optimize import curve_fit
3
  • Your exponential function approaches zero as x approaches positive infinity. In other words, it looks more like 1/x, not x. Commented Apr 21, 2018 at 19:29
  • 1
    curve_fit tends to perform poorly if you give it a poor initial guess with functions like the exponential that could end up with very large numbers. You could try altering the maxfev input so that it runs more iterations. otherwise, I would suggest trying with with something like p0=(1000,-.005,0) -.01, since it ~doubles from 300 to 500 and you have -b in your eqn, 100 0 since it is ~3000 at 300 (1.5 doublings from 0). See how that turns out Commented Apr 21, 2018 at 19:29
  • @DavidL yep, that actually did it, if you add your answer as an actual answer I'll accept it :) Commented Apr 21, 2018 at 19:31

2 Answers 2

2

curve_fit tends to perform poorly if you give it a poor initial guess with functions like the exponential that could end up with very large numbers. You could try altering the maxfev input so that it runs more iterations. otherwise, I would suggest trying with with something like:

p0=(1000,-.005,0)

-.01, since it ~doubles from 300 to 500 and you have -b in your eqn, 100 0 since it is ~3000 at 300 (1.5 doublings from 0). See how that turns out

As for why the initial exponential doesn't work at all, your initial guess is b=1, and x is in range of (300,1000) or range. This means python is calculating exp(-300) which either throws an exception or is set to 0. At this point, whether b is increased or decreased, the exponential is going to still be set to 0 for any value in the general vicinity of the initial estimate.

Basically, python uses a numerical method with limited precision, and the exponential estimate went outside of the range of values it can handle

Sign up to request clarification or add additional context in comments.

Comments

0

I'm not sure how you're fitting the curves -- are you using polynomial least squares? In that case, you'd expect the fit to improve with each additional degree of flexibility, and you choose the power based on diminishing marginal improvement / outside theory.

The improving fit should look something like this.

I actually wrote some code to do Polynomial Least Squares in python for a class a while back, which you can find here on Github. It's a bit hacky though and loosely commented since I was just using it to solve exercises. Hope it's helpful.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.