0

I am trying to use scipy's basinhopping in conjunction with a function that I created. Although my question is related to this thread, the difference is that my function does not return a single value, but rather a python series

from scipy.optimize import basinhopping

############     Simple DataFrame     ###########
data = pd.DataFrame({'def': [0, 0, 1, 1, 1], 'amt': [40, 20, 30, 50, 60], 
                    'prob': [0.20, 0.10, 0.15, 0.30, 0.28], 
                    'cost': [0.05, 0.01, 0.02, 0.09, 0.08],
                    'rate': [0.98, 0.75, 0.95, 0.76, 0.89]})

############     Function      ############
def pred_money(row):
    if (row["def"] == 0):
        money = (row["amt"] * row["cost"]) * (1 - row["prob"])
        return money
    else:
        money = row["amt"] * row["rate"] * row["prob"]
        return money

I have tried using the optimization function as follows:

x0=[1.]
minimizer_kwargs = {"method": "BFGS", "args":(something_goes_here)}
ret = basinhopping(func=pred_money, x0=x0, 
minimizer_kwargs=minimizer_kwargs,niter=200)

According to the basinhopping documentation other arguments of the function can be passed as part of the minimizer_kwargs dictionary. It is left blank in the code above because I simply do not know what goes in there. My suspicion is that it does not return a single value. I could be wrong.

Most examples in the documentation are fairly straight forward functions that does not have anything to do with a dataframe. Any help is appreciated. Thank you.

hpaulj
  • 221,503
  • 14
  • 230
  • 353
xyz
  • 31
  • 5
  • Your code optimizes`expected_profit` which is not defined. So it's unclear what you are doing. But if you ask to minimize a function which has no scalar-objective, scipy can't help you (last time i checked). In those cases it's unclear how solutions are ordered? Which output is better? Compare with [wiki's vector opt page](https://en.wikipedia.org/wiki/Vector_optimization). Model-wie your problem might be as simple as collapsing into a min-norm model of your time-series like predictions (like least-squares), but that's guessing. – sascha Sep 02 '18 at 18:59
  • `scipy` built on `numpy`, but doesn't 'know' anything about `pandas`. Neither the documentation or the code treats a DataFrame in special way. It's either just another python object, or it may try to turn it into an array. – hpaulj Sep 02 '18 at 19:00
  • You could pass a dataframe to your function via the `args` parameter - provided your function knows how to use it. But make sure you are passing a tuple, e.g. `args: (df,)` (the comma matters if there's only one element). – hpaulj Sep 02 '18 at 19:02
  • I've corrected the name of the objective function @sacha – xyz Sep 02 '18 at 19:04
  • You are giving an initial value of `x0`, a list with number 1. But it looks like `pred_money` expects a row of `data`, the dataframe. The optimizing code varies that `x0` seeking to minimize the `func`. So `pred_money(np.array(x0))` should run and produce a meaningful initial objective vaue. – hpaulj Sep 02 '18 at 19:11
  • Thank you @hpaulj I will implement your suggestions. It looks to me like two things: use tuples and correct the initial parameters to be the length of the dataframe. – xyz Sep 02 '18 at 19:15
  • So when I make the following changes: x0=[0 for i in data] minimizer_kwargs = {"method": "BFGS", "args":(data, )} ret = basinhopping(func=pred_money, x0=x0, minimizer_kwargs=minimizer_kwargs,niter=200) I get the following error message: TypeError: pred_money() takes exactly 1 argument (2 given) – xyz Sep 02 '18 at 19:45
  • Your `pred_money` doesn't look like the function the linked answer. You may need to work through some more examples to get a clear idea of what kinds of parameters get passed to the objective function. – hpaulj Sep 02 '18 at 21:41
  • It often helps to first write down a proper mathematical model. One of the most common mistakes is to start coding before you rally know how the optimization model looks likes. – Erwin Kalvelagen Sep 03 '18 at 15:15

0 Answers0