1

I am trying to optimize forecast parameters with scipy.optimize. I followed tutorial and also found some nice example here on stackoverflow but I am facing an issue that I cannot resolve. I am starting to wonder whether using pandas is a poor choice with scipy?

I have set up my code as follow:

import simpy
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
import pandas as pd
import statistics as stat
import math as m
#from sklearn.grid_search import ParameterGrid
from scipy.optimize import minimize

###dataframe for the simulation

df = pd.read_csv('simulation_df_data_2018_2.csv')
with pd.option_context("max_rows", None,"max_columns", None):
    print(df.head())


for i in df.index:
    alpha = 0.2
    beta = 0.3
    
    x = np.array([alpha, beta])

 
    def holts(x):

        LO = np.int(df['average_demand'].loc[i])
        print(type(LO))

        TO = ((df['m2'].loc[i] - df['m3'].loc[i]) + (df['m1'].loc[i] - df['m2'].loc[i])) / 2
        L1 = round(x[0] * df['m3'].loc[i] + (1 - x[0]) * (
                LO + TO))
        T1 = x[1] * (L1 - LO) + (1 - x[1]) * TO

        L2 = round(x[0] * df['m2'].loc[i] + (1 - x[0]) * (
                L1 + T1))
        T2 = x[1] * (L2 - L1) + (1 - x[1]) * T1
        L3 = round(x[0] * df['m1'].loc[i] + (1 - x[0]) * (
                L2 + T2))
        T3 = beta * (L3 - L2) + (1 - beta) * T2
        LT1 = round(L3 + 1 * T3)
        MSE = ((df['m3'].loc[i] - L1) + (df['m2'].loc[i] - L2) + (
                df['m2'].loc[i] - L3)) ** 2 / 3

        return MSE
    #print(holts(x))

    x0 = [0.1,0.1]

    result = minimize(holts, x0, bounds=[(0,1),(0,1)], method="SLSQP")
    print(result)
    print(x)

and df looks like this:

     m1     m2     m3     m4     m5     m6     m7     m8     m9    m10    m11  \
0   0.0    8.0    2.0    0.0   14.0    0.0    5.0    2.0    4.0    4.0   10.0   
1   4.0   55.0    2.0   72.0   38.0   87.0  113.0    2.0    0.0  165.0    2.0   
2  18.0   34.0    6.0   63.0   14.0   18.0   33.0   35.0   51.0    0.0   24.0   
3   0.0   21.0    3.0   10.0   15.0    0.0   32.0    1.0    3.0   17.0    0.0   
4  96.0  106.0  237.0  136.0  138.0  116.0  167.0  158.0  110.0  115.0  161.0   

     m12   m13   m14   m15   m16    m17   m18   m19   m20    m21    m22  \
0    0.0   6.0  10.0   0.0   2.0    2.0  17.0   0.0   0.0    0.0    0.0   
1   35.0   7.0  88.0   6.0   3.0  103.0  18.0  59.0   6.0   20.0  152.0   
2    6.0   5.0  99.0   7.0  17.0   15.0   8.0   3.0  21.0    6.0    4.0   
3   30.0   5.0  88.0   1.0   6.0   10.0   9.0  17.0   9.0    0.0    1.0   
4  116.0  77.0  48.0  96.0  69.0   77.0  96.0  74.0  94.0  101.0  115.0   

     m23    m24  average_demand  low_demand  high_demand  
0    0.0    0.0        3.583333         0.0         17.0  
1    6.0    0.0       43.458333         0.0        165.0  
2   14.0   12.0       21.375000         0.0         99.0  
3    0.0    0.0       11.583333         0.0         88.0  
4  158.0  167.0      117.833333        48.0        237.0  

I am very confused about the error I keep getting, here is the traceback

Traceback (most recent call last):
  File "/Users/pierre/Desktop/simul/forecast_holts_alpha.py", line 121, in <module>
    result = minimize(holts, x0, args= coef_list,bounds=[(0,1),(0,1)], method="SLSQP")
  File "/Users/pierre/Desktop/Django-app/lib/python3.7/site-packages/scipy/optimize/_minimize.py", line 618, in minimize
    constraints, callback=callback, **options)
  File "/Users/pierre/Desktop/Django-app/lib/python3.7/site-packages/scipy/optimize/slsqp.py", line 399, in _minimize_slsqp
    fx = func(x)
  File "/Users/pierre/Desktop/Django-app/lib/python3.7/site-packages/scipy/optimize/optimize.py", line 327, in function_wrapper
    return function(*(wrapper_args + args))
  File "/Users/pierre/Desktop/simul/forecast_holts_alpha.py", line 63, in holts
    LO = np.int(df['average_demand'].loc[i])
IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices

I don't get why this error is popping up there, especially because if I search the type of LO I get this:

print(type(LO))

<class 'int'>

I am not an experience programmer so I struggle to figure out what is going on, any help would be appreciated!

UPDATE:

   fun: 56.333333333333336
     jac: array([0., 0.])
 message: 'Optimization terminated successfully.'
    nfev: 4
     nit: 1
    njev: 1
  status: 0
 success: True
       x: array([0.1, 0.1])
[0.2,0.3]

OUTPUT looks like this but does not seem to be optimizing anything

19
  • I think docs for scipy.optimize.minimize can be helpful. Your holts function signature is not matched with the doc, which should be fun(x, *args) -> float. Since x0 = [0.1, 0.1] in your code, I think x should be 1-D array with shape (2,). Commented Jul 31, 2020 at 14:43
  • thank you for the link, it helped, but I don't get much out of "where x is an 1-D array with shape (n,) and args is a tuple of the fixed parameters needed to completely specify the function." beside that x needs to be an array and not a dataframe, would you be able to tell me what X needs to be? Commented Jul 31, 2020 at 14:51
  • In the function signiture fun(x, *args) -> float, x should be the variables of the function you want to minimize. In your code, you want to minimize holts function and holts(df, coef_list) function has df in the place for the variables x, which seems to be wrong. For what variables do you want to minimize holts function? Your holts function seems to have no variables. Commented Jul 31, 2020 at 15:07
  • I am trying to minimize MSE by optimizing the variable alpha and beta. If i understand you, x needs to be an array with alpha and beta? Commented Jul 31, 2020 at 15:10
  • Yes. If alpha and beta is the variable, x needs to be an array with alpha and beta. Commented Jul 31, 2020 at 15:18

1 Answer 1

2

Since I don't know about what your code is exactly doing, I can't tell whether the following code is doing right. But just for a guide to how to use scipy.optimize.minimize function, it should be something like the following:

import numpy as np
import pandas as pd
from scipy.optimize import minimize

df = pd.read_csv('simulation_df_data_2018_2.csv')

for i in df.index:
    # Since you said "alpha" and "beta" are the variable of "holts" function
    # I changed all "alpha" and "beta" to "x[0]" and "x[1]" respectively.
    def holts(x):
        LO = np.int(df['average_demand'].loc[i])
        TO = ((df['m2'].loc[i] - df['m3'].loc[i]) + (df['m1'].loc[i] - df['m2'].loc[i])) / 2
        L1 = x[0] * df['m3'].loc[i] + (1 - x[0]) * (LO + TO)
        T1 = x[1] * (L1 - LO) + (1 - x[1]) * TO
        L2 = x[0] * df['m2'].loc[i] + (1 - x[0]) * (L1 + T1)
        T2 = x[1] * (L2 - L1) + (1 - x[1]) * T1
        L3 = x[0] * df['m1'].loc[i] + (1 - x[0]) * (L2 + T2)
        MSE = ((df['m3'].loc[i] - L1) + (df['m2'].loc[i] - L2) + (df['m2'].loc[i] - L3)) ** 2 / 3
        return MSE


    x0 = np.array([0.1, 0.1])  # initial guess for the points "x" which "holts(x)" attains its minimum.

    result = minimize(holts, x0, bounds=[(0, 1), (0, 1)], method="SLSQP", options={'disp': True})
    print(result)
    print()

which prints

Optimization terminated successfully    (Exit mode 0)
            Current function value: 16.921875002444228
            Iterations: 5
            Function evaluations: 15
            Gradient evaluations: 5
     fun: 16.921875002444228
     jac: array([ 8.06808472e-04, -6.23427415e+00])
 message: 'Optimization terminated successfully'
    nfev: 15
     nit: 5
    njev: 5
  status: 0
 success: True
       x: array([0.75000606, 1.        ])

Optimization terminated successfully    (Exit mode 0)
            Current function value: 3.0792324286388828e-09
            Iterations: 7
            Function evaluations: 24
            Gradient evaluations: 7
     fun: 3.0792324286388828e-09
     jac: array([-0.00833083, -0.00081578])
 message: 'Optimization terminated successfully'
    nfev: 24
     nit: 7
    njev: 7
  status: 0
 success: True
       x: array([0.1495232 , 0.25665903])

Optimization terminated successfully    (Exit mode 0)
            Current function value: 1.9951658230345873e-10
            Iterations: 9
            Function evaluations: 32
            Gradient evaluations: 9
     fun: 1.9951658230345873e-10
     jac: array([0.03791677, 0.00858221])
 message: 'Optimization terminated successfully'
    nfev: 32
     nit: 9
    njev: 9
  status: 0
 success: True
       x: array([0.37155192, 0.19218713])

Optimization terminated successfully    (Exit mode 0)
            Current function value: 114.53090716252409
            Iterations: 11
            Function evaluations: 37
            Gradient evaluations: 11
     fun: 114.53090716252409
     jac: array([ 3.06129456e-04, -3.04457455e+01])
 message: 'Optimization terminated successfully'
    nfev: 37
     nit: 11
    njev: 11
  status: 0
 success: True
       x: array([0.7171298, 1.       ])

Optimization terminated successfully    (Exit mode 0)
            Current function value: 33.333333333333336
            Iterations: 2
            Function evaluations: 6
            Gradient evaluations: 2
     fun: 33.333333333333336
     jac: array([-403.33331966,   -0.        ])
 message: 'Optimization terminated successfully'
    nfev: 6
     nit: 2
    njev: 2
  status: 0
 success: True
       x: array([1., 1.])

UPDATE: It seems that the round function is the reason minimize function is not working, since round function would create many plateaus on the graph of holts function. I removed the round functions and updated the result printed.

Sign up to request clarification or add additional context in comments.

2 Comments

that does not make the trick, x being the optimized values are always the same as the orginal ([0.1, 0.1]) for me and go to 1 for you as you initianilized them with [30,50] so they go to the upper bound. I am not sure what is going on
Oh, right. My guess [30, 50] is beyond the upper bound, lol. I should fix it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.