最小化指数平滑中的alpha值

1 投票
2 回答
2354 浏览
提问于 2025-04-17 21:34

我刚开始使用Python中的scipy和numpy。

我想问的是:我怎么才能用一个最优的alpha(平滑常数)来最小化误差函数(具体来说是平均绝对百分比误差,简称MAPE)呢?所以,我想通过MAPE来找到最优的alpha。

这是我的数学公式:

x = [ 3, 4, 5, 6]
y0 = x0
y1 = x0*alpha+ (1-alpha)*y0

MAPE = (y-x)/x [ This is an objective function and I am trying to solve for alpha here]

Constraints1: alpha<1
Constrants2 : alpha>0

2 个回答

0

在编程中,有时候我们会遇到一些问题,比如代码运行不正常或者出现错误。这些问题可能是因为我们没有正确理解某些概念,或者在写代码时犯了一些小错误。

例如,变量就是一个很重要的概念。简单来说,变量就像一个盒子,我们可以把数据放进去,给它起个名字,方便我们在需要的时候取出来。想象一下,如果你有一个装糖果的盒子,你可以随时打开它,看看里面有什么,或者拿出一些糖果来吃。

另外,函数也是一个常用的概念。函数就像是一个小工具箱,里面有一些可以重复使用的工具。你只需要告诉它你想要做什么,它就会帮你完成。这样,你就不用每次都从头开始写代码,节省了很多时间。

总之,编程就像是在解决一个个小谜题,理解这些基础概念会让你在写代码的时候更加得心应手。如果遇到问题,不要着急,慢慢分析,找出错误的地方,通常就能找到解决办法。

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)
    #if xlen % c !=0:
    #    return None
    fc =float(c)
    xbar2 =sum([x[i] for i in range(c, 2 * c)])/ fc
    xbar1 =sum([x[i] for i in range(c)]) / fc
    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)
    a0 =xbar1  - b0 * tbar
    if debug: print ("a0 = ", a0)

    #Compute for initial indices
    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

    #Normalize so S[i] for i in [0, c)  will add to c.
    tS =c / sum([S[i] for i in range(c)])
    for i in range(c):
        S[i] *=tS
        if debug: print ("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
        Btm1 =Bt
        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


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("test : ",test)

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

opt = result.x
print("opt : ", result.x)
1

这个方法应该是可行的。我觉得没有比我写的递归循环更好的方法来找到 y 了。基本的思路是,你需要把想要最小化的东西变成一个关于最小化参数(alpha)和其他任何东西(x)的函数。所以,我把这个叫做 mape。你需要把 alpha 的初始猜测和额外的参数(x)传递给最小化器。由于你的约束条件只是一些边界,如果你使用 method='SLSQP',这就很简单。

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

def y(alpha, x):
    y = np.empty(len(x), float)
    y[0] = x[0]
    for i in xrange(1, len(x)):
        y[i] = x[i-1]*alpha + y[i-1]*(1-alpha)
    return y

def mape(alpha, x):
    diff = y(alpha, x) - x
    return np.mean(diff/x)

x = np.array([ 3, 4, 5, 6])
guess = .5
result = minimize(mape, guess, (x,), bounds=[(0,1)], method='SLSQP')

要获取你的信息,你可以这样做:

print result
[alpha_opt] = result.x

如果有什么地方让你感到困惑,请留言!

撰写回答