使用scipy.optimize优化3个系数

1 投票
1 回答
1332 浏览
提问于 2025-04-17 22:30

我一直在尝试优化三个系数,但遇到了一些错误,解决不了。以下是我的代码。'y' 是一个预测函数,它接收一组时间序列数据和一个系数列表,然后经过计算返回一个预测结果列表。x 是历史数据,而 coeffList 是一个包含三个系数的列表。

'mape' 函数用来计算实际数据和预测数据之间的差异。在优化过程中,我想要最小化 'mape' 函数的输出。作为约束条件,这三个系数都必须大于0且小于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)

这是我遇到的错误信息:

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

我遇到了什么问题呢?如果你们能给我一些建议,我会非常感激。

1 个回答

1

产生这个错误 IndexError: index 4 is out of bounds for axis 0 with size 3 的原因是你在调用 minimize 函数的时候出现了问题。这个错误是因为你想要最小化的目标函数试图去最小化第一个参数。

从你的边界设置来看,你似乎想要最小化 coeff(这是一个三维的东西),但实际上你现在是在尝试最小化 mape 的第一个参数,也就是 x。所以,你的函数输入参数的顺序是错的。你可以通过简单的修改来解决这个问题,比如说(或者重新定义 mape,把第一行改成 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')

撰写回答