指数平滑法

(转)一次、二次、三次指数平滑计算思想及代码

一般常用到的指数平滑法为一次指数平滑、二次指数平滑和三次指数平滑,高次指数平滑一般比较难见到,因此本文着重介绍了一次、二次和三次指数平滑的特点与不同。

一次指数平滑一般应用于直线型数据,且一次指数平滑具有滞后性,可以说明有明显的时间性、季节性。

二次指数平滑一般也应用于直线型,但是效果会比一次指数平滑好很多,也就相当于加强版的一次指数平滑。

三次指数平滑可以应用于抛物线型的数据,因为数据在二次平滑过后还是具有斜率,那么可以继续使用三次指数平滑。

初值:不管什么指数平滑都会有个初值,假如数据大于20项,那么初值就可以认定为第一个数据,或者利用下列公式计算也行;假如数据小于20项,则初始值为:

 

低于20项一般取3,大于20的看着取就行了。

指数平滑系数α的确定

(1)经验判断

1、当时间序列呈现较稳定的水平趋势时,应选较小的α,一般可在0.05~0.20之间取值‘

2、当时间序列有波动,但长期趋势变化不大时,可选稍大的α值,常在0.1~0.4之间取值;

3、当时间序列波动很大,长期趋势变化幅度较大,呈现明显且迅速的上升或下降趋势时,宜选择较大的α值,如可在0.6~0.8间选值。以使预测模型灵敏度高些,能迅速跟上数据的变化。

4、当时间序列数据是上升(或下降)的发展趋势类型,α应取较大的值,在0.6~1之间。

一次指数平滑:

一次指数平滑需要滞后一期,给定平滑系数,那么一次指数平滑的计算公式为:

 

预测第期的数值则是上一期的实际值与预测值的加权平均,预测公式为:

 

二次指数平滑:

给定平滑系数,那么二次指数平滑的计算公式为:

 

预测未来期的值的计算公式为:

 

其中:

三次指数平滑:

 给定平滑系数,那么三次指数平滑的计算公式为:

 

预测未来期的值的计算公式为:

 

其中:

下面举例说明,数据如下:

253993

275396.2

315229.5

356949.6

400158.2

442431.7

495102.9

570164.8

640993.1

704250.4

767455.4

781807.8

776332.3

794161.7

834177.7

931651.5

1028390

1114914

133

88

150

123

404

107

674

403

243

257

900

1043

1156

895

1200

1038

1024

1283

引入均方误差概念来判断平滑系数是否准确:

 

要使最小则构成了一个关于的函数,由此可以得到最优的平滑系数,这里可以引入线性规划的思想来求得最优解

一次指数平滑代码:

        S1_1 = []
        for m in range(0, len(info_data_id)):
            S1_1_empty = []
            x = 0
            for n in range(0, 3):
                x = x + int(info_data_sales[m][n])
            x = x / 3
            S1_1_empty.append(x)
            S1_1.append(S1_1_empty)
        # print(S1_1)

        a = []  ##这是用来存放阿尔法的数组
        info_MSE = []  ##计算均方误差来得到最优的a(阿尔法)
        for i in range(0, len(info_data_sales)):
            v = input('请输入第' + str(i + 1) + '组数据的a:')
            a.append(v)

        for i in range(0, len(info_data_sales)):
            MSE = 0
            for j in range(0, len(info_data_sales[i])):
                S1_1[i].append(
                    float(a[i]) * int(info_data_sales[i][j]) + (1 - float(a[i])) * int(S1_1[i][j]))  ##计算预估值
                MSE = (int(S1_1[i][j]) - int(info_data_sales[i][j])) ** 2 + MSE
                # print(info_data_sales[i][j], S1_1[i][j])
            MSE = (MSE ** (1 / 2)) / int(len(info_data_sales[i]))  ##得到均方误差
            info_MSE.append(MSE)
        # print(info_MSE)
        # print(S1_1)
        for i in range(0, len(S1_1)):
            print('' + str(i + 1) + '组的一次平滑预估值为:' + str(S1_1[i][len(S1_1[i]) - 1]) + ';均方误差为:' + str(info_MSE[i]))

二次指数平滑代码:

        S2_1 = []
        S2_2 = []
        for m in range(0, len(info_data_id)):
            S2_1_empty = []
            x = 0
            for n in range(0, 3):
                x = x + float(info_data_sales[m][n])
            x = x / 3
            S2_1_empty.append(x)
            S2_1.append(S2_1_empty)
            S2_2.append(S2_1_empty)
        # print(S2_2)
        a = []  ##这是用来存放阿尔法的数组
        info_MSE = []  ##计算均方误差来得到最优的a(阿尔法)
        for i in range(0, len(info_data_sales)):
            v = float(input('请输入第' + str(i + 1) + '组数据的a:'))
            a.append(v)

        ##下面是计算一次指数平滑的值
        S2_1_new1 = []
        for i in range(0, len(info_data_sales)):
            S2_1_new = [[]] * len(info_data_id)
            for j in range(0, len(info_data_sales[i])):
                if j == 0:
                    S2_1_new[i].append(
                        float(a[i]) * float(info_data_sales[i][j]) + (1 - float(a[i])) * float(S2_1[i][j]))
                else:
                    S2_1_new[i].append(float(a[i]) * float(info_data_sales[i][j]) + (1 - float(a[i])) * float(
                        S2_1_new[i][j - 1]))  ##计算一次指数的值
            S2_1_new1.append(S2_1_new[i])
        # print(S2_1_new1)
        # print(len(S2_1_new1[i]))

        ##下面是计算二次指数平滑的值
        S2_2_new1 = []
        info_MSE = []  ##计算均方误差来得到最优的a(阿尔法)
        for i in range(0, len(info_data_sales)):
            S2_2_new = [[]] * len(info_data_id)
            MSE = 0
            for j in range(0, len(info_data_sales[i])):
                if j == 0:
                    S2_2_new[i].append(float(a[i]) * float(S2_1_new1[i][j]) + (1 - float(a[i])) * float(S2_2[i][j]))
                else:
                    S2_2_new[i].append(float(a[i]) * float(S2_1_new1[i][j]) + (1 - float(a[i])) * float(
                        S2_2_new[i][j - 1]))  ##计算二次指数的值
                MSE = (int(S2_2_new[i][j]) - int(info_data_sales[i][j])) ** 2 + MSE
            MSE = (MSE ** (1 / 2)) / int(len(info_data_sales[i]))
            info_MSE.append(MSE)
            S2_2_new1.append(S2_2_new[i])
        # print(S2_2_new1)
        # print(len(S2_2_new1[i]))

        ##下面是计算At、Bt以及每个预估值Xt的值,直接计算预估值,不一一列举Xt的值了
        u = input('你要预估多少期?')
        Xt = []
        for i in range(0, len(info_data_sales)):
            At = (float(S2_1_new1[i][len(S2_1_new1[i]) - 1]) * 2 - float(S2_2_new1[i][len(S2_2_new1[i]) - 1]))
            Bt = (float(a[i]) / (1 - float(a[i])) * (
            float(S2_1_new1[i][len(S2_1_new1[i]) - 1]) - float(S2_2_new1[i][len(S2_2_new1[i]) - 1])))
            Xt.append(At + Bt * int(u))
            print('' + str(i + 1) + '组的二次平滑预估值为:' + str(Xt[i]) + ';均方误差为:' + str(info_MSE[i]))

三次指数平滑代码

       S3_1 = []
        S3_2 = []
        S3_3 = []
        for m in range(0, len(info_data_id)):
            S3_1_empty = []
            x = 0
            for n in range(0, 3):
                x = x + float(info_data_sales[m][n])
            x = x / 3
            S3_1_empty.append(x)
            S3_1.append(S3_1_empty)
            S3_2.append(S3_1_empty)
            S3_3.append(S3_1_empty)
        # print(S3_1)
        a = []  ##这是用来存放阿尔法的数组
        info_MSE = []  ##计算均方误差来得到最优的a(阿尔法)
        for i in range(0, len(info_data_sales)):
            v = float(input('请输入第' + str(i + 1) + '组数据的a:'))
            a.append(v)

        ##下面是计算一次指数平滑的值
        S3_1_new1 = []
        for i in range(0, len(info_data_sales)):
            S3_1_new = [[]] * len(info_data_id)
            for j in range(0, len(info_data_sales[i])):
                if j == 0:
                    S3_1_new[i].append(
                        float(a[i]) * float(info_data_sales[i][j]) + (1 - float(a[i])) * float(S3_1[i][j]))
                else:
                    S3_1_new[i].append(float(a[i]) * float(info_data_sales[i][j]) + (1 - float(a[i])) * float(
                        S3_1_new[i][j - 1]))  ##计算一次指数的值
            S3_1_new1.append(S3_1_new[i])

        ##下面是计算二次指数平滑的值
        S3_2_new1 = []
        info_MSE = []  ##计算均方误差来得到最优的a(阿尔法)
        for i in range(0, len(info_data_sales)):
            S3_2_new = [[]] * len(info_data_id)
            for j in range(0, len(info_data_sales[i])):
                if j == 0:
                    S3_2_new[i].append(float(a[i]) * float(S3_1_new1[i][j]) + (1 - float(a[i])) * float(S3_2[i][j]))
                else:
                    S3_2_new[i].append(float(a[i]) * float(S3_1_new1[i][j]) + (1 - float(a[i])) * float(
                        S3_2_new[i][j - 1]))  ##计算二次指数的值
            S3_2_new1.append(S3_2_new[i])

        ##下面是计算二次指数平滑的值
        S3_3_new1 = []
        info_MSE = []  ##计算均方误差来得到最优的a(阿尔法)
        for i in range(0, len(info_data_sales)):
            S3_3_new = [[]] * len(info_data_id)
            MSE = 0
            for j in range(0, len(info_data_sales[i])):
                if j == 0:
                    S3_3_new[i].append(float(a[i]) * float(S3_2_new1[i][j]) + (1 - float(a[i])) * float(S3_3[i][j]))
                else:
                    S3_3_new[i].append(float(a[i]) * float(S3_2_new1[i][j]) + (1 - float(a[i])) * float(
                        S3_3_new[i][j - 1]))  ##计算三次指数的值
                MSE = (int(S3_3_new[i][j]) - int(info_data_sales[i][j])) ** 2 + MSE
            MSE = (MSE ** (1 / 2)) / int(len(info_data_sales[i]))
            info_MSE.append(MSE)
            S3_3_new1.append(S3_3_new[i])
            # print(S3_3_new1)

        ##下面是计算At、Bt、Ct以及每个预估值Xt的值,直接计算预估值,不一一列举Xt的值了
        u = input('你要预估多少期?')
        Xt = []
        for i in range(0, len(info_data_sales)):
            At = (
            float(S3_1_new1[i][len(S3_1_new1[i]) - 1]) * 3 - float(S3_2_new1[i][len(S3_2_new1[i]) - 1]) * 3 + float(
                S3_3_new1[i][len(S3_3_new1[i]) - 1]))
            Bt = ((float(a[i]) / (2 * ((1 - float(a[i])) ** 2))) * ((6 - 5 * float(a[i])) * (
            float(S3_1_new1[i][len(S3_1_new1[i]) - 1]) - 2 * (5 - 4 * float(a[i])) * float(
                S3_2_new1[i][len(S3_2_new1[i]) - 1]) + (4 - 3 * float(a[i])) * float(
                S3_3_new1[i][len(S3_3_new1[i]) - 1]))))
            Ct = (((float(a[i])) ** 2) / (2 * ((1 - float(a[i])) ** 2))) * (
            float(S3_1_new1[i][len(S3_1_new1[i]) - 1]) - float(S3_2_new1[i][len(S3_2_new1[i]) - 1])*2 + float(
                S3_3_new1[i][len(S3_3_new1[i]) - 1]))
            Xt.append(At + Bt * int(u) + Ct * (int(u) ** 2))
            print('' + str(i + 1) + '组的三次平滑预估值为:' + str(Xt[i]) + ';均方误差为:' + str(info_MSE[i]))
原文地址:https://www.cnblogs.com/zlyblog/p/6589208.html