个人博客转至:tybai.com

无聊就想打码,打码使我快乐


Fork me on GitHub

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

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

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

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

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

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

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

一次指数平滑:

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

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

 

二次指数平滑:

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

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

其中:

三次指数平滑:

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

 

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

 

其中:

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

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

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

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

但是:

python没有线性规划的包,所以就没有细致的代码写出来了,不过经过手动计算尝试这样子是可行的

 

python3下编程,一次指数平滑代码为:

 1         S1_1 = []
 2         for m in range(0, len(info_data_id)):
 3             S1_1_empty = []
 4             x = 0
 5             for n in range(0, 3):
 6                 x = x + int(info_data_sales[m][n])
 7             x = x / 3
 8             S1_1_empty.append(x)
 9             S1_1.append(S1_1_empty)
10         # print(S1_1)
11 
12         a = []  ##这是用来存放阿尔法的数组
13         info_MSE = []  ##计算均方误差来得到最优的a(阿尔法)
14         for i in range(0, len(info_data_sales)):
15             v = input('请输入第' + str(i + 1) + '组数据的a:')
16             a.append(v)
17 
18         for i in range(0, len(info_data_sales)):
19             MSE = 0
20             for j in range(0, len(info_data_sales[i])):
21                 S1_1[i].append(
22                     float(a[i]) * int(info_data_sales[i][j]) + (1 - float(a[i])) * int(S1_1[i][j]))  ##计算预估值
23                 MSE = (int(S1_1[i][j]) - int(info_data_sales[i][j])) ** 2 + MSE
24                 # print(info_data_sales[i][j], S1_1[i][j])
25             MSE = (MSE ** (1 / 2)) / int(len(info_data_sales[i]))  ##得到均方误差
26             info_MSE.append(MSE)
27         # print(info_MSE)
28         # print(S1_1)
29         for i in range(0, len(S1_1)):
30             print('' + str(i + 1) + '组的一次平滑预估值为:' + str(S1_1[i][len(S1_1[i]) - 1]) + ';均方误差为:' + str(info_MSE[i]))    

二次指数平滑代码为:

 1         S2_1 = []
 2         S2_2 = []
 3         for m in range(0, len(info_data_id)):
 4             S2_1_empty = []
 5             x = 0
 6             for n in range(0, 3):
 7                 x = x + float(info_data_sales[m][n])
 8             x = x / 3
 9             S2_1_empty.append(x)
10             S2_1.append(S2_1_empty)
11             S2_2.append(S2_1_empty)
12         # print(S2_2)
13         a = []  ##这是用来存放阿尔法的数组
14         info_MSE = []  ##计算均方误差来得到最优的a(阿尔法)
15         for i in range(0, len(info_data_sales)):
16             v = float(input('请输入第' + str(i + 1) + '组数据的a:'))
17             a.append(v)
18 
19         ##下面是计算一次指数平滑的值
20         S2_1_new1 = []
21         for i in range(0, len(info_data_sales)):
22             S2_1_new = [[]] * len(info_data_id)
23             for j in range(0, len(info_data_sales[i])):
24                 if j == 0:
25                     S2_1_new[i].append(
26                         float(a[i]) * float(info_data_sales[i][j]) + (1 - float(a[i])) * float(S2_1[i][j]))
27                 else:
28                     S2_1_new[i].append(float(a[i]) * float(info_data_sales[i][j]) + (1 - float(a[i])) * float(
29                         S2_1_new[i][j - 1]))  ##计算一次指数的值
30             S2_1_new1.append(S2_1_new[i])
31         # print(S2_1_new1)
32         # print(len(S2_1_new1[i]))
33 
34         ##下面是计算二次指数平滑的值
35         S2_2_new1 = []
36         info_MSE = []  ##计算均方误差来得到最优的a(阿尔法)
37         for i in range(0, len(info_data_sales)):
38             S2_2_new = [[]] * len(info_data_id)
39             MSE = 0
40             for j in range(0, len(info_data_sales[i])):
41                 if j == 0:
42                     S2_2_new[i].append(float(a[i]) * float(S2_1_new1[i][j]) + (1 - float(a[i])) * float(S2_2[i][j]))
43                 else:
44                     S2_2_new[i].append(float(a[i]) * float(S2_1_new1[i][j]) + (1 - float(a[i])) * float(
45                         S2_2_new[i][j - 1]))  ##计算二次指数的值
46                 MSE = (int(S2_2_new[i][j]) - int(info_data_sales[i][j])) ** 2 + MSE
47             MSE = (MSE ** (1 / 2)) / int(len(info_data_sales[i]))
48             info_MSE.append(MSE)
49             S2_2_new1.append(S2_2_new[i])
50         # print(S2_2_new1)
51         # print(len(S2_2_new1[i]))
52 
53         ##下面是计算At、Bt以及每个预估值Xt的值,直接计算预估值,不一一列举Xt的值了
54         u = input('你要预估多少期?')
55         Xt = []
56         for i in range(0, len(info_data_sales)):
57             At = (float(S2_1_new1[i][len(S2_1_new1[i]) - 1]) * 2 - float(S2_2_new1[i][len(S2_2_new1[i]) - 1]))
58             Bt = (float(a[i]) / (1 - float(a[i])) * (
59             float(S2_1_new1[i][len(S2_1_new1[i]) - 1]) - float(S2_2_new1[i][len(S2_2_new1[i]) - 1])))
60             Xt.append(At + Bt * int(u))
61             print('' + str(i + 1) + '组的二次平滑预估值为:' + str(Xt[i]) + ';均方误差为:' + str(info_MSE[i]))

三次指数平滑代码为:

 

 1         S3_1 = []
 2         S3_2 = []
 3         S3_3 = []
 4         for m in range(0, len(info_data_id)):
 5             S3_1_empty = []
 6             x = 0
 7             for n in range(0, 3):
 8                 x = x + float(info_data_sales[m][n])
 9             x = x / 3
10             S3_1_empty.append(x)
11             S3_1.append(S3_1_empty)
12             S3_2.append(S3_1_empty)
13             S3_3.append(S3_1_empty)
14         # print(S3_1)
15         a = []  ##这是用来存放阿尔法的数组
16         info_MSE = []  ##计算均方误差来得到最优的a(阿尔法)
17         for i in range(0, len(info_data_sales)):
18             v = float(input('请输入第' + str(i + 1) + '组数据的a:'))
19             a.append(v)
20 
21         ##下面是计算一次指数平滑的值
22         S3_1_new1 = []
23         for i in range(0, len(info_data_sales)):
24             S3_1_new = [[]] * len(info_data_id)
25             for j in range(0, len(info_data_sales[i])):
26                 if j == 0:
27                     S3_1_new[i].append(
28                         float(a[i]) * float(info_data_sales[i][j]) + (1 - float(a[i])) * float(S3_1[i][j]))
29                 else:
30                     S3_1_new[i].append(float(a[i]) * float(info_data_sales[i][j]) + (1 - float(a[i])) * float(
31                         S3_1_new[i][j - 1]))  ##计算一次指数的值
32             S3_1_new1.append(S3_1_new[i])
33 
34         ##下面是计算二次指数平滑的值
35         S3_2_new1 = []
36         info_MSE = []  ##计算均方误差来得到最优的a(阿尔法)
37         for i in range(0, len(info_data_sales)):
38             S3_2_new = [[]] * len(info_data_id)
39             for j in range(0, len(info_data_sales[i])):
40                 if j == 0:
41                     S3_2_new[i].append(float(a[i]) * float(S3_1_new1[i][j]) + (1 - float(a[i])) * float(S3_2[i][j]))
42                 else:
43                     S3_2_new[i].append(float(a[i]) * float(S3_1_new1[i][j]) + (1 - float(a[i])) * float(
44                         S3_2_new[i][j - 1]))  ##计算二次指数的值
45             S3_2_new1.append(S3_2_new[i])
46 
47         ##下面是计算二次指数平滑的值
48         S3_3_new1 = []
49         info_MSE = []  ##计算均方误差来得到最优的a(阿尔法)
50         for i in range(0, len(info_data_sales)):
51             S3_3_new = [[]] * len(info_data_id)
52             MSE = 0
53             for j in range(0, len(info_data_sales[i])):
54                 if j == 0:
55                     S3_3_new[i].append(float(a[i]) * float(S3_2_new1[i][j]) + (1 - float(a[i])) * float(S3_3[i][j]))
56                 else:
57                     S3_3_new[i].append(float(a[i]) * float(S3_2_new1[i][j]) + (1 - float(a[i])) * float(
58                         S3_3_new[i][j - 1]))  ##计算三次指数的值
59                 MSE = (int(S3_3_new[i][j]) - int(info_data_sales[i][j])) ** 2 + MSE
60             MSE = (MSE ** (1 / 2)) / int(len(info_data_sales[i]))
61             info_MSE.append(MSE)
62             S3_3_new1.append(S3_3_new[i])
63             # print(S3_3_new1)
64 
65         ##下面是计算At、Bt、Ct以及每个预估值Xt的值,直接计算预估值,不一一列举Xt的值了
66         u = input('你要预估多少期?')
67         Xt = []
68         for i in range(0, len(info_data_sales)):
69             At = (
70             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(
71                 S3_3_new1[i][len(S3_3_new1[i]) - 1]))
72             Bt = ((float(a[i]) / (2 * ((1 - float(a[i])) ** 2))) * ((6 - 5 * float(a[i])) * (
73             float(S3_1_new1[i][len(S3_1_new1[i]) - 1]) - 2 * (5 - 4 * float(a[i])) * float(
74                 S3_2_new1[i][len(S3_2_new1[i]) - 1]) + (4 - 3 * float(a[i])) * float(
75                 S3_3_new1[i][len(S3_3_new1[i]) - 1]))))
76             Ct = (((float(a[i])) ** 2) / (2 * ((1 - float(a[i])) ** 2))) * (
77             float(S3_1_new1[i][len(S3_1_new1[i]) - 1]) - float(S3_2_new1[i][len(S3_2_new1[i]) - 1])*2 + float(
78                 S3_3_new1[i][len(S3_3_new1[i]) - 1]))
79             Xt.append(At + Bt * int(u) + Ct * (int(u) ** 2))
80             print('' + str(i + 1) + '组的三次平滑预估值为:' + str(Xt[i]) + ';均方误差为:' + str(info_MSE[i]))

由于注释写得很清楚了,就不一段一段的解释了

明显看出数列为线性的数列,所以用二次指数平滑会更好

得到的二次平滑结果如下:

误差判断:

误差判断

预估值

实际值

误差

数列1

1193179

1192201

0.08%

数列2

1250

1371

9.68%

 由此可见预测效果非常好

附上完整代码:

 

  1 from openpyxl import load_workbook
  2 import xlsxwriter
  3 
  4 if __name__ == '__main__':
  5     judge = input('请选择使用几次指数平滑:一次请按1;二次请按2;三次请按3:')
  6     ##这里是打开excel将数据储存到数组里面
  7     wb = load_workbook(filename=r'C:\Users\Administrator\Desktop\data.xlsx')  ##读取路径
  8     ws = wb.get_sheet_by_name("Sheet1")  ##读取名字为Sheet1的sheet表
  9     info_data_id = []
 10     info_data_sales = []
 11 
 12     for row_A in range(1, 3):  ## 遍历第1行到2行
 13         id = ws.cell(row=row_A, column=1).value  ## 遍历第1行到2行,第1列
 14         info_data_id.append(id)
 15     for row_num_BtoU in range(1, len(info_data_id) + 1):  ## 遍历第1行到2行
 16         row_empty = []  ##建立一个空数组作为临时储存地,每次换行就被清空
 17         for i in range(2, 20):  ## 遍历第1行到2行,第1到19列
 18             data = ws.cell(row=row_num_BtoU, column=i).value
 19             if data == None:
 20                 pass
 21             else:
 22                 row_empty.append(data)  ##将单元格信息储存进去
 23         info_data_sales.append(row_empty)  ##row_empty每次储存完1到19列后压给info_data_sales,然后row_empty被清空
 24     # print(info_data_id)
 25     # print(info_data_sales)
 26     if judge == '1':
 27         ##############################下面是计算St(1)下面写为S1_t_######################################
 28         print('你选择了一次指数平滑预测')
 29         ##一次指数平滑的初值为S1_1,用S1_1来储存每一组数据的一次平滑的数值
 30         S1_1 = []
 31         for m in range(0, len(info_data_id)):
 32             S1_1_empty = []
 33             x = 0
 34             for n in range(0, 3):
 35                 x = x + int(info_data_sales[m][n])
 36             x = x / 3
 37             S1_1_empty.append(x)
 38             S1_1.append(S1_1_empty)
 39         # print(S1_1)
 40 
 41         a = []  ##这是用来存放阿尔法的数组
 42         info_MSE = []  ##计算均方误差来得到最优的a(阿尔法)
 43         for i in range(0, len(info_data_sales)):
 44             v = input('请输入第' + str(i + 1) + '组数据的a:')
 45             a.append(v)
 46 
 47         for i in range(0, len(info_data_sales)):
 48             MSE = 0
 49             for j in range(0, len(info_data_sales[i])):
 50                 S1_1[i].append(
 51                     float(a[i]) * int(info_data_sales[i][j]) + (1 - float(a[i])) * int(S1_1[i][j]))  ##计算预估值
 52                 MSE = (int(S1_1[i][j]) - int(info_data_sales[i][j])) ** 2 + MSE
 53                 # print(info_data_sales[i][j], S1_1[i][j])
 54             MSE = (MSE ** (1 / 2)) / int(len(info_data_sales[i]))  ##得到均方误差
 55             info_MSE.append(MSE)
 56         # print(info_MSE)
 57         # print(S1_1)
 58         for i in range(0, len(S1_1)):
 59             print('' + str(i + 1) + '组的一次平滑预估值为:' + str(S1_1[i][len(S1_1[i]) - 1]) + ';均方误差为:' + str(info_MSE[i]))
 60 
 61     if judge == '2':
 62         ##############################下面是计算St(2)下面写为S2_t_######################################
 63         print('你选择了二次指数平滑预测')
 64 
 65         ##二次指数平滑的初值为S2_1,用S2_1_new来储存每一组数据的一次平滑的数值
 66         S2_1 = []
 67         S2_2 = []
 68         for m in range(0, len(info_data_id)):
 69             S2_1_empty = []
 70             x = 0
 71             for n in range(0, 3):
 72                 x = x + float(info_data_sales[m][n])
 73             x = x / 3
 74             S2_1_empty.append(x)
 75             S2_1.append(S2_1_empty)
 76             S2_2.append(S2_1_empty)
 77         # print(S2_2)
 78         a = []  ##这是用来存放阿尔法的数组
 79         info_MSE = []  ##计算均方误差来得到最优的a(阿尔法)
 80         for i in range(0, len(info_data_sales)):
 81             v = float(input('请输入第' + str(i + 1) + '组数据的a:'))
 82             a.append(v)
 83 
 84         ##下面是计算一次指数平滑的值
 85         S2_1_new1 = []
 86         for i in range(0, len(info_data_sales)):
 87             S2_1_new = [[]] * len(info_data_id)
 88             for j in range(0, len(info_data_sales[i])):
 89                 if j == 0:
 90                     S2_1_new[i].append(
 91                         float(a[i]) * float(info_data_sales[i][j]) + (1 - float(a[i])) * float(S2_1[i][j]))
 92                 else:
 93                     S2_1_new[i].append(float(a[i]) * float(info_data_sales[i][j]) + (1 - float(a[i])) * float(
 94                         S2_1_new[i][j - 1]))  ##计算一次指数的值
 95             S2_1_new1.append(S2_1_new[i])
 96         # print(S2_1_new1)
 97         # print(len(S2_1_new1[i]))
 98 
 99         ##下面是计算二次指数平滑的值
100         S2_2_new1 = []
101         info_MSE = []  ##计算均方误差来得到最优的a(阿尔法)
102         for i in range(0, len(info_data_sales)):
103             S2_2_new = [[]] * len(info_data_id)
104             MSE = 0
105             for j in range(0, len(info_data_sales[i])):
106                 if j == 0:
107                     S2_2_new[i].append(float(a[i]) * float(S2_1_new1[i][j]) + (1 - float(a[i])) * float(S2_2[i][j]))
108                 else:
109                     S2_2_new[i].append(float(a[i]) * float(S2_1_new1[i][j]) + (1 - float(a[i])) * float(
110                         S2_2_new[i][j - 1]))  ##计算二次指数的值
111                 MSE = (int(S2_2_new[i][j]) - int(info_data_sales[i][j])) ** 2 + MSE
112             MSE = (MSE ** (1 / 2)) / int(len(info_data_sales[i]))
113             info_MSE.append(MSE)
114             S2_2_new1.append(S2_2_new[i])
115         # print(S2_2_new1)
116         # print(len(S2_2_new1[i]))
117 
118         ##下面是计算At、Bt以及每个预估值Xt的值,直接计算预估值,不一一列举Xt的值了
119         u = input('你要预估多少期?')
120         Xt = []
121         for i in range(0, len(info_data_sales)):
122             At = (float(S2_1_new1[i][len(S2_1_new1[i]) - 1]) * 2 - float(S2_2_new1[i][len(S2_2_new1[i]) - 1]))
123             Bt = (float(a[i]) / (1 - float(a[i])) * (
124             float(S2_1_new1[i][len(S2_1_new1[i]) - 1]) - float(S2_2_new1[i][len(S2_2_new1[i]) - 1])))
125             Xt.append(At + Bt * int(u))
126             print('' + str(i + 1) + '组的二次平滑预估值为:' + str(Xt[i]) + ';均方误差为:' + str(info_MSE[i]))
127 
128     if judge == '3':
129         ##############################下面是计算St(3)下面写为S3_t_######################################
130         print('你选择了三次指数平滑预测')
131         S3_1 = []
132         S3_2 = []
133         S3_3 = []
134         for m in range(0, len(info_data_id)):
135             S3_1_empty = []
136             x = 0
137             for n in range(0, 3):
138                 x = x + float(info_data_sales[m][n])
139             x = x / 3
140             S3_1_empty.append(x)
141             S3_1.append(S3_1_empty)
142             S3_2.append(S3_1_empty)
143             S3_3.append(S3_1_empty)
144         # print(S3_1)
145         a = []  ##这是用来存放阿尔法的数组
146         info_MSE = []  ##计算均方误差来得到最优的a(阿尔法)
147         for i in range(0, len(info_data_sales)):
148             v = float(input('请输入第' + str(i + 1) + '组数据的a:'))
149             a.append(v)
150 
151         ##下面是计算一次指数平滑的值
152         S3_1_new1 = []
153         for i in range(0, len(info_data_sales)):
154             S3_1_new = [[]] * len(info_data_id)
155             for j in range(0, len(info_data_sales[i])):
156                 if j == 0:
157                     S3_1_new[i].append(
158                         float(a[i]) * float(info_data_sales[i][j]) + (1 - float(a[i])) * float(S3_1[i][j]))
159                 else:
160                     S3_1_new[i].append(float(a[i]) * float(info_data_sales[i][j]) + (1 - float(a[i])) * float(
161                         S3_1_new[i][j - 1]))  ##计算一次指数的值
162             S3_1_new1.append(S3_1_new[i])
163 
164         ##下面是计算二次指数平滑的值
165         S3_2_new1 = []
166         info_MSE = []  ##计算均方误差来得到最优的a(阿尔法)
167         for i in range(0, len(info_data_sales)):
168             S3_2_new = [[]] * len(info_data_id)
169             for j in range(0, len(info_data_sales[i])):
170                 if j == 0:
171                     S3_2_new[i].append(float(a[i]) * float(S3_1_new1[i][j]) + (1 - float(a[i])) * float(S3_2[i][j]))
172                 else:
173                     S3_2_new[i].append(float(a[i]) * float(S3_1_new1[i][j]) + (1 - float(a[i])) * float(
174                         S3_2_new[i][j - 1]))  ##计算二次指数的值
175             S3_2_new1.append(S3_2_new[i])
176 
177         ##下面是计算二次指数平滑的值
178         S3_3_new1 = []
179         info_MSE = []  ##计算均方误差来得到最优的a(阿尔法)
180         for i in range(0, len(info_data_sales)):
181             S3_3_new = [[]] * len(info_data_id)
182             MSE = 0
183             for j in range(0, len(info_data_sales[i])):
184                 if j == 0:
185                     S3_3_new[i].append(float(a[i]) * float(S3_2_new1[i][j]) + (1 - float(a[i])) * float(S3_3[i][j]))
186                 else:
187                     S3_3_new[i].append(float(a[i]) * float(S3_2_new1[i][j]) + (1 - float(a[i])) * float(
188                         S3_3_new[i][j - 1]))  ##计算三次指数的值
189                 MSE = (int(S3_3_new[i][j]) - int(info_data_sales[i][j])) ** 2 + MSE
190             MSE = (MSE ** (1 / 2)) / int(len(info_data_sales[i]))
191             info_MSE.append(MSE)
192             S3_3_new1.append(S3_3_new[i])
193             # print(S3_3_new1)
194 
195         ##下面是计算At、Bt、Ct以及每个预估值Xt的值,直接计算预估值,不一一列举Xt的值了
196         u = input('你要预估多少期?')
197         Xt = []
198         for i in range(0, len(info_data_sales)):
199             At = (
200             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(
201                 S3_3_new1[i][len(S3_3_new1[i]) - 1]))
202             Bt = ((float(a[i]) / (2 * ((1 - float(a[i])) ** 2))) * ((6 - 5 * float(a[i])) * (
203             float(S3_1_new1[i][len(S3_1_new1[i]) - 1]) - 2 * (5 - 4 * float(a[i])) * float(
204                 S3_2_new1[i][len(S3_2_new1[i]) - 1]) + (4 - 3 * float(a[i])) * float(
205                 S3_3_new1[i][len(S3_3_new1[i]) - 1]))))
206             Ct = (((float(a[i])) ** 2) / (2 * ((1 - float(a[i])) ** 2))) * (
207             float(S3_1_new1[i][len(S3_1_new1[i]) - 1]) - float(S3_2_new1[i][len(S3_2_new1[i]) - 1])*2 + float(
208                 S3_3_new1[i][len(S3_3_new1[i]) - 1]))
209             Xt.append(At + Bt * int(u) + Ct * (int(u) ** 2))
210             print('' + str(i + 1) + '组的三次平滑预估值为:' + str(Xt[i]) + ';均方误差为:' + str(info_MSE[i]))

 

 

 

posted on 2016-07-28 20:18  TTyb  阅读(29680)  评论(7编辑  收藏  举报

导航


不用多久

我就会升职加薪

当上总经理

出任CEO

迎娶白富美

走上人生巅峰

Pulpit rock