Search code examples
pythonnumpyoptimizationscipyminimization

Minimizing function by changing parameters using scipy


I want to minimize the next equation by changing the parameters B0, B1, B2, B3, T1, T2. The variable y just another variable to calculate the objective function. I just need help to minimize that function (used as an objective function) by changing the parameters but I can't get the results. I tried with scipy but I did not change the parameters. By running the function, I get the result that I want:

funcion_opt(B0, B1, B2, B3, T1, T2)
output:  64.30571361326217

But when I do the minimization, I get the next result:

res = optimize.minimize(funcion_opt, parameters, args=(beta0, beta1, beta2, 
beta3, tau1, tau2))
output: funcion_opt() takes 6 positional arguments but 7 were given

I know that the mistake is the way to introduce the parameters and there is where I need help. Sorry if it's not clear enough.

Small example of my issue:

y = np.array([98.494500, 97.828500, 97.610000, 97.314000, 97.014500, 
92.959000, 96.696222])
def objective(b0, b1, b2, b3, t1, t2):
    return (y * b0 + b1) - ( y * b2 + b3) + t1 + t2
    x0 = np.array([0.03, -0.03, 0, 0, 1, 1]) #Initial values of b0, b1...
    result = minimize(objective, x0, args=(b0, b1, b2, b3, t1, t2))

I know that the inputs in the function are wrong, the variables that are constant is y, and I want to change the values of the parameters b0, b1, b2, b3, t1, t2. So the minimize function I need is the one that takes the return of the function and by tuning the parameters, minimizes the error. So maybe the mistake is when setting the objective function.

This is a dummy function, the original one is the sum of square errors. After that I need to minimize tat function by changing the values of the parameters inside the return b0, b1, b2, b3, t1, t2 because in the function these parameters are set as. Discount factor is irrelevant I just need how to change the parameters to the ones that minimize the objective function:

When I try to minimize get the output that the error is the same and the parameters did not change. Any assistance with this would be much appreciated. Thanks in advance.


Solution

  • Your problem is in passing (b0, b1, b2, b3, t1, t2) as args - this should be the optimization vector, so it should be passed only in a form of initial x0 (which you did). Since you removed y from objective function, there is no need for args (which is for passing constant parameters of optimized function).

    This is what I think it should look like using objective function after fixing (I made it complete with import and everything so you can run it without modification):

    import numpy as np
    from scipy.optimize import minimize
    
    y = 10.0
    
    def objective(b0, b1, b2, b3, t1, t2):
        return (y * b0 + b1) - ( y * b2 + b3) + t1 + t2
    
    def objective_proxy(x):
        return objective(*x)
    
    x0 = np.array([0.03, -0.03, 0, 0, 1, 1])
    result = minimize(objective_proxy, x0)
    

    When you try it with the original function (which had y as last parameter), you may pass the y in args now, because it's constant and the result would look like this:

    y_value = np.array([98.494500, 97.828500, 97.610000, 97.314000, 97.014500, 
    92.959000, 96.696222])
    
    def function_opt(b0, b1, b2, b3, t1, t2, y):
        ...
        ...
        return ...
    
    def function_opt_proxy(x, y):
        args = list(x) + [y]
        return function_opt(*args)
    
    
    x0 = np.array([0.03, -0.03, 0, 0, 1, 1]) #Initial values of b0, b1...
    result = minimize(function_opt_proxy, x0, args=(y_value,)
    

    Note that I changed y to y_value to avoid confusion between function_opt parameter.

    fixed:

    I added proxy function which takes care of expanding parameters from iterable to individual parameters.