Search code examples
pythonmatplotlibcurve-fittingscipy-optimizesigmoid

"'numpy.float64' object is not callable"-Error when using scipy.optimize curve_fit with multiple parameters in function


I am new to python and programming. Apologies in advance if this question has been answered before, I've checked all I could find but I couldn't work my way through it.

I am trying to approximate a sigmoid function (used in innovation diffusion forecasting), the Bass model to be precise, with a limited number of values (both historic and future predicitons).

The function used is in the code below.

The variables have the following meaning: y: diffusion of market 0≤y≤1, t: years

The parameters have the following meaning: m: Maximum Maket Size, p: early adopters / innovators, q: immitators

Now, I am getting the following error: 'numpy.float64' object is not callable

What do I need to change in my code so that it runs well?

import numpy as np
import matplotlib.pyplot as plt
import scipy.optimize
from scipy.optimize import curve_fit
import pylab as p

t_data = np.array([2016, 2017, 2018, 2019, 2020, 2025, 2030, 2035, 2040, 2045])
y_data = np.array([0.0015, 0.0027, 0.0042, 0.0066, 0.0164, 0.1389, 0.3889, 0.6667, 0.8611, 0.99])
def bass(t, *args):
    m, p, q = args
    t_0 = 2011
    return m*(1-np.exp(-(p+q)*(t-t_0)))/(1+(p/q)*np.exp(-(p+q)*(t-t_0)))
popt, pcov = curve_fit(bass, t_data, y_data, p0=[1, 1, 1])
plt.plot(t_data, y_data, 'o')
plt.plot(t_data, func_nl_lsq(t_data, *popt), '-')
plt.show()

This is the error I receive in full length:

<ipython-input-30-3b4f9481e8a6>:6: RuntimeWarning: overflow encountered in exp
  return m*(1-np.exp(-(p+q)*(t-t_0)))/(1+(p/q)*np.exp(-(p+q)*(t-t_0)))
<ipython-input-30-3b4f9481e8a6>:6: RuntimeWarning: invalid value encountered in true_divide
  return m*(1-np.exp(-(p+q)*(t-t_0)))/(1+(p/q)*np.exp(-(p+q)*(t-t_0)))

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-30-3b4f9481e8a6> in <module>
      7 popt, pcov = curve_fit(bass, t_data, y_data, p0=[1, 1, 1])
      8 plt.plot(t_data, y_data, 'o')
----> 9 plt.plot(t_data, func_nl_lsq(t_data, *popt), '-')
     10 plt.show()

<ipython-input-17-286e00184588> in func_nl_lsq(t, *args)
      4     m, p, q = args
      5     t_0 = 2011
----> 6     return m*((1-np.exp(-(p+q)(t-t_0)))/(1+(p/q)*np.exp(-(p+q)(t-t_0))))
      7 popt, pcov = curve_fit(func_nl_lsq, t_data, y_data, p0=[1, 1, 1])
      8 plt.plot(t_data, y_data, 'o')

TypeError: 'numpy.float64' object is not callable


Solution

  • Looks like you also need to include the arguments when you're calling the bass function. Something like: curve_fit(bass(t_data, args), rest of curve_fit arguments...)