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

您所在的位置:网站首页 十一点二除以二点4=几 一次、二次、三次指数平滑计算思想及代码

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

2024-05-10 05:14| 来源: 网络整理| 查看: 265

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

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

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

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

初值:不管什么指数平滑都会有个初值,假如数据大于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

引入均方误差概念来判断平滑系数

是否准确:

要使

最小则构成了一个

关于

的函数

,由此可以得到最优的平滑系数,这里可以引入线性规划的思想来求得最优解

但是:

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

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

代码语言:javascript复制 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]))

二次指数平滑代码为:

代码语言:javascript复制 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]))

三次指数平滑代码为:

代码语言:javascript复制 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%

 由此可见预测效果非常好

附上完整代码:

代码语言:javascript复制 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]))


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3