I am having trouble fitting a curve for some data, but I cannot decide where I am going wrong.
In the past, I did this with numpy.linalg.lstsq for exponential functions and scipy.optimize.curve_fit for sigmoid functions. This time I wanted to create a script that would allow me to specify various functions, define the parameters, and check their compliance with the data. While doing this, I noticed that Scipy leastsq and Numpy lstsq seem to provide different answers for the same dataset and function. The function is simply y = e^(l*x) and is bounded in such a way that y=1 at x=0 .
The Excel trend line is consistent with the result of Numpy lstsq , but since Scipy leastsq can take any function, it would be nice to decide what the problem is.
import scipy.optimize as optimize import numpy as np import matplotlib.pyplot as plt ## Sampled data x = np.array([0, 14, 37, 975, 2013, 2095, 2147]) y = np.array([1.0, 0.764317544, 0.647136491, 0.070803763, 0.003630962, 0.001485394, 0.000495131]) # function fp = lambda p, x: np.exp(p*x) # error function e = lambda p, x, y: (fp(p, x) - y) # using scipy least squares l1, s = optimize.leastsq(e, -0.004, args=(x,y)) print l1 # [-0.0132281] # using numpy least squares l2 = np.linalg.lstsq(np.vstack([x, np.zeros(len(x))]).T,np.log(y))[0][0] print l2 # -0.00313461628963 (same answer as Excel trend line) # smooth x for plotting x_ = np.arange(0, x[-1], 0.2) plt.figure() plt.plot(x, y, 'rx', x_, fp(l1, x_), 'b-', x_, fp(l2, x_), 'g-') plt.show()
Edit - Additional Information
The above MWE contains a small sample of the data set. When selecting the actual data, the scipy.optimize.curve_fit curve represents R ^ 2 0.82, and the numpy.linalg.lstsq curve, which coincides with the one calculated by Excel, has R ^ 2 from 0.41.