I'm stuck with some seemingly easy task to fit nonlinear regression model. It worked normally until some new data came. Here is my code:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import leastsq
from scipy.optimize import curve_fit
x = [1, 8, 20, 40, 80, 125, 250, 500, 2500, 20000]
def f(x, a, b, c, d):
""" Function itself. """
return d + (a - d) / (1.0 + np.exp(b * (np.log(x) - np.log(c))))
def err(cfs, x, y):
""" Error function for 'leastsq'. """
y_hat = f(x, *cfs)
res = y_hat - y
return res
def synth(x, params):
""" Try some fitting on synthetic data. """
y = f(x, *params)
cfs, cov = curve_fit(f, x, y)
full_res = leastsq(err, np.ones_like(params), args=(x, y), full_output=True)
y_hat1 = f(x, *cfs)
y_hat2 = f(x, *full_res[0])
plt.plot(np.log(x), y, 'bo')
plt.plot(np.log(x), y_hat1, 'r')
plt.plot(np.log(x), y_hat2, 'go')
plt.grid(True)
plt.show()
def test():
synth(x, [40000.0, 2.0, 150.0, 4000.0])
if __name__ == '__main__':
test()
This is synthetic data, but other data I have looks very similar (and doesn't fit either), so I want to understand why that happens and extrapolate understanding to other data sets.
You can see that I tried two minimizers - "curve_fit" and "leastsq". I've also tried "fmin" (Nelder-Mead method), but it didn't help as well.
P.S. I know I can transform it taking log(y), but I wanted to get result on data "as is".