通常經常使用到的指數平滑法爲一次指數平滑、二次指數平滑和三次指數平滑,高次指數平滑通常比較難見到,所以本文着重介紹了一次、二次和三次指數平滑的特色與不一樣。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]))