一次、二次、三次指數平滑計算思想及代碼

通常經常使用到的指數平滑法爲一次指數平滑、二次指數平滑和三次指數平滑,高次指數平滑通常比較難見到,所以本文着重介紹了一次、二次和三次指數平滑的特色與不一樣。python

一次指數平滑通常應用於直線型數據,且一次指數平滑具備滯後性,能夠說明有明顯的時間性、季節性。編程

二次指數平滑通常也應用於直線型,可是效果會比一次指數平滑好不少,也就至關於增強版的一次指數平滑。數組

三次指數平滑能夠應用於拋物線型的數據,由於數據在二次平滑事後仍是具備斜率,那麼能夠繼續使用三次指數平滑。app

初值:無論什麼指數平滑都會有個初值,假如數據大於20項,那麼初值就能夠認定爲第一個數據,或者利用下列公式計算也行;假如數據小於20項,則初始值爲:函數

低於20項通常取3,大於20的看着取就好了。spa

一次指數平滑:3d

一次指數平滑須要滯後一期,給定平滑係數,那麼一次指數平滑的計算公式爲:excel

預測第期的數值則是上一期的實際值與預測值的加權平均,預測公式爲:code

 

二次指數平滑:orm

給定平滑係數,那麼二次指數平滑的計算公式爲:

預測將來期的值的計算公式爲:

其中:

三次指數平滑:

 給定平滑係數,那麼三次指數平滑的計算公式爲:

 

預測將來期的值的計算公式爲:

 

其中:

下面舉例說明,數據以下:

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]))
相關文章
相關標籤/搜索