user3424557
user3424557

Reputation: 11

optimization of 3 coefficients by using scipy.optimize

I've been trying to optimize three coefficients. But I cannot solve the error I faced. The following is the codes. 'y' is the forecasting function whcih takes a list of time series data and a coefficient list and then returns a list of forecasts after calculation. x is the historical data. and coeffList is a list which has 3 coefficients as a value.

'mape' function calculates the difference between actual and forecasted data. In the optimization, I'm trying to minimize the output from the 'mape' function. As constraints, all three coefficients are greater than 0 and less than 1.

from __future__ import division
import numpy as np
from scipy.optimize import minimize



#coeffList[0] = alpha
#coeffList[1] = beta
#coeffList[2] =gamma

def mape(x, coeffList):
    diff = abs(y(x,coeffList)-x)
    print("np.mean(diff/x) : ", np.mean(diff/x))
    return np.mean(diff/x)


#Holt Winters-Multiplicative



def y(x, coeffList , debug=True):

    c =4 
    #Compute initial b and intercept using the first two complete c periods.
    xlen =len(x)
    print("xlen : ", xlen)
    #if xlen % c !=0:
    #    return None
    fc =float(c)
    xbar2 =sum([x[i] for i in range(c, 2 * c)])/ fc
    print("xbar2 : ",xbar2)

    xbar1 =sum([x[i] for i in range(c)]) / fc


    print("xbar1 : ", xbar1)
    b0 =(xbar2 - xbar1) / fc
    if debug: print ("b0 = ", b0)

    #Compute for the level estimate a0 using b0 above.
    tbar  =sum(i for i in range(1, c+1)) / fc
    print("tbar : ",tbar)
    a0 =xbar1  - b0 * tbar
    if debug: print ("a0 = ", a0)

    #Compute for initial indices - seasonality
    I =[x[i] / (a0 + (i+1) * b0) for i in range(0, xlen)]
    if debug: print ("Initial indices = ", I)

    S=[0] * (xlen+ c)

    for i in range(c):
        S[i] =(I[i] + I[i+c]) / 2.0
        print ("S[",i,"]=", S[i])

    #Normalize so S[i] for i in [0, c)  will add to c.
    tS =c / sum([S[i] for i in range(c)])
    print("tS : ", tS)
    for i in range(c):
        S[i] *=tS
        if debug: print ("Normalized S[",i,"]=", S[i])

    # Holt - winters proper ...
    if debug: print( "Use Holt Winters formulae")


    At =a0
    Bt =b0
    #y =[0] * (xlen) 
    y = np.empty(len(x),float)
    for i in range(xlen):
        Atm1 =At # a[0] = a0
        Btm1 =Bt # b[0] = b0

        At =coeffList[0] * x[i] / S[i] + (1.0-coeffList[0]) * (Atm1 + Btm1)


        Bt =coeffList[1] * (At - Atm1) + (1- coeffList[1]) * Btm1

        S[i+c] =coeffList[2] * x[i] / At + (1.0 - coeffList[2]) * S[i]




        y[i]=(a0 + b0 * (i+1)) * S[i]

    return y

# the time-series data.
coeff = [0.2, 0.3, 0.4]

x =[146, 96, 59, 133, 192, 127, 79, 186, 272, 155, 98, 219]
test = y(x,coeff)
print("x : ", x)
print("y : ",test)


#optimization


result = minimize(mape, coeff, (x,), bounds =[(0,1),(0,1), (0,1)], method='SLSQP')
opt = result.x
print("opt : ", result.x)

And this is the error message I have :

Traceback (most recent call last):
  File "C:\Users\SEC\Desktop\HDWeathProgram\testing_Optimization_HWM.py", line 135, in <module>
    result = minimize(mape, coeff, (x,), bounds =[(0,1),(0,1), (0,1)], method='SLSQP')
  File "C:\Python27\lib\site-packages\scipy\optimize\_minimize.py", line 364, in minimize
    constraints, **options)
  File "C:\Python27\lib\site-packages\scipy\optimize\slsqp.py", line 354, in _minimize_slsqp
    fx = func(x)
  File "C:\Python27\lib\site-packages\scipy\optimize\optimize.py", line 261, in function_wrapper
    return function(x, *args)
  File "C:\Users\SEC\Desktop\HDWeathProgram\testing_Optimization_HWM.py", line 12, in mape
    diff = abs(y(x,coeffList)-x)
  File "C:\Users\SEC\Desktop\HDWeathProgram\testing_Optimization_HWM.py", line 30, in y
    xbar2 =sum([x[i] for i in range(c, 2 * c)])/ fc
IndexError: index 4 is out of bounds for axis 0 with size 3

What kind of problems do I have? I will really appreciate any kind of your comments

Upvotes: 1

Views: 1375

Answers (1)

dr jimbob
dr jimbob

Reputation: 17711

The call that generates the IndexError: index 4 is out of bounds for axis 0 with size 3 is the minimize call. This is because your objective function you are minimizing tries minimizing the first parameter.

You appear by your bounds to want to minimize the coeff (a three dimensional thing), but currently you are trying to minimize the first parameter of mape which is x. Thus, your function has its input parameters in the wrong order. You can fix this quickly with say (or by redefining mape (change first line to def mape(x, coeffList):).

def mape_reversed(coeffList, x):                                                         
    return mape(x, coeffList)

result = minimize(mape_reversed, coeff, (x,),  bounds =[(0,1),(0,1), (0,1)], method='SLSQP')

Upvotes: 1

Related Questions