7

Running the scipy.minimize function "I get TypeError: 'numpy.float64' object is not callable". Specifically during the execution of:

    .../scipy/optimize/optimize.py", line 292, in function_wrapper
return function(*(wrapper_args + args))

I already looked at previous similar topics here and usually this problem occurs due to the fact that as first input parameter of .minimize is not a function. I have difficulties in figure it out, because "a" is function. What do you think?

    ### "data" is a pandas data frame of float values
    ### "w" is a numpy float array i.e. [0.11365704 0.00886848 0.65302202 0.05680696 0.1676455 ]

    def a(data, w):
        ### Return a negative float value from position [2] of an numpy array of float values calculated via the "b" function i.e -0.3632965490830499 
        return -b(data, w)[2]

    constraint = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})

    ### i.e ((0, 1), (0, 1), (0, 1), (0, 1), (0, 1))
    bound = tuple((0, 1) for x in range (len(symbols)))

    opts = scipy.minimize(a(data, w), len(symbols) * [1. / len(symbols),], method = 'SLSQP', bounds = bound, constraints = constraint)
Nipper
  • 207
  • 2
  • 15
  • Basically, the problem is that `a(data, w)` is a function call, not a function. Just `a` by itself is a function, ie without the parenthesis `(...)`. – tel Apr 11 '18 at 13:29

2 Answers2

5

Short answer

It should instead be:

opts = scipy.minimize(a, len(symbols) * [1. / len(symbols),], args=(w,), method='SLSQP', bounds=bound, constraints=constraint)

Details

a(data, w) is not a function, it's a function call. In other words a(data, w) effectively has the value and type of the return value of the function a. minimize needs the actual function without the call (ie without the parentheses (...) and everything in-between), as its first parameter.

From the scipy.optimize.minimize docs:

scipy.optimize.minimize(fun, x0, args=(), method=None, jac=None, hess=None, hessp=None, bounds=None, constraints=(), tol=None, callback=None, options=None)

...

fun : callable

The objective function to be minimized. Must be in the form f(x, *args). The optimizing argument, x, is a 1-D array of points, and args is a tuple of any additional fixed parameters needed to completely specify the function.

...

args : tuple, optional

Extra arguments passed to the objective function...

So, assuming w is fixed (at least with respect to your desired minimization), you would pass it to minimize via the args parameter, as I've done above.

Community
  • 1
  • 1
tel
  • 13,005
  • 2
  • 44
  • 62
  • `line 99 opts = opt.minimize(a, args = (data, w), len(symbols) * [1. / len(symbols),], method = 'SLSQP', bounds = bound, constraints = constraint) ^ SyntaxError: positional argument follows keyword argument ` This is the output. – Nipper Apr 11 '18 at 13:35
  • @Nipper It looks like you're using Raubtaube's answer, which has invalid syntax (which is why you're getting the error message). Try the one I posted. – tel Apr 11 '18 at 13:39
  • Sorry I did not read carefully. Just done as you suggested and the result is `line 99 opts = opt.minimize(a, len(symbols) * [1. / len(symbols),], args = (, weights), method = 'SLSQP', bounds = bound, constraints = constraint) ^ SyntaxError: invalid syntax` I need to swap the position of w in args because the b function first input is data which is a data frame (b function can not perform operation such as .shift() on w which is a numpy.array). – Nipper Apr 11 '18 at 13:51
  • @Nipper You don't need to swap the position of `w`, `minimize` will do that for you. `args = (, weights)` is also not valid Python syntax. `len(symbols) * [1. / len(symbols),]` is your initial guess for `data`. `minimize` does not need anything else. It knows that the first entry in `args` is supposed to be the second argument passed to `a` – tel Apr 11 '18 at 14:02
  • `opts = opt.minimize(a, len(symbols) * [1. / len(symbols),], args = (w, ), method = 'SLSQP', bounds = bound, constraints = constraint) ERROR line 16, in b r1d = np.log(data / data.shift(1)) AttributeError: 'numpy.ndarray' object has no attribute 'shift'` – Nipper Apr 11 '18 at 14:05
  • @Nipper your error message changed. That's good! It means you're making progress. It looks like you solved your original "not callable" problem. The issue now is that `minimize` will always pass `data` in as a `numpy` array, not as a pandas dataframe. You'll need to add a line to the start of `a` that will perform the array to dataframe conversion when it's needed. – tel Apr 11 '18 at 14:14
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/168747/discussion-between-nipper-and-tel). – Nipper Apr 11 '18 at 14:18
1

You're not passing the function, but the evaluated result to minimize.

opts = scipy.minimize(a,  len(symbols) * [1. / len(symbols),], method = 'SLSQP', bounds = bound, constraints = constraint, args = (data,w))

Should work.

Edit: Fixed stupid syntax error.

mgutsche
  • 465
  • 1
  • 9
  • 20
  • `line 99 opts = opt.minimize(a, args = (data, w), len(symbols) * [1. / len(symbols),], method = 'SLSQP', bounds = bound, constraints = constraint) ^ SyntaxError: positional argument follows keyword argument ` This is the output. – Nipper Apr 11 '18 at 13:33
  • The syntax isn't valid. You need to swap `args = (data,w)` and `len(symbols) * [1. / len(symbols),]`. Also, it should be `args=(w,)`. `minimize` needs to be able to freely manipulate the first argument to `a` – tel Apr 11 '18 at 13:41