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


一般常用到的指數平滑法爲一次指數平滑、二次指數平滑和三次指數平滑,高次指數平滑一般比較難見到,因此本文着重介紹了一次、二次和三次指數平滑的特點與不同。

一次指數平滑一般應用於直線型數據,且一次指數平滑具有滯後性,可以說明有明顯的時間性、季節性。

二次指數平滑一般也應用於直線型,但是效果會比一次指數平滑好很多,也就相當於加強版的一次指數平滑。

三次指數平滑可以應用於拋物線型的數據,因爲數據在二次平滑過後還是具有斜率,那麼可以繼續使用三次指數平滑。

初值:不管什麼指數平滑都會有個初值,假如數據大於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 = 020             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 + MSE24                 # 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 = 040             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 + MSE47             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 / 310             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 = 053             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 + MSE60             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%

 由此可見預測效果非常好

文章出處:https://www.cnblogs.com/TTyb/p/5716125.html

附上完整代碼:

  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 = 0105             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 + MSE112             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 = 0137             for n in range(0, 3):138                 x = x + float(info_data_sales[m][n])139             x = x / 3140             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 = 0183             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 + MSE190             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]))
發佈了6 篇原創文章 · 獲贊 18 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章