(转)一次、二次、三次指数平滑计算思想及代码
一般常用到的指数平滑法为一次指数平滑、二次指数平滑和三次指数平滑,高次指数平滑一般比较难见到,因此本文着重介绍了一次、二次和三次指数平滑的特点与不同。
一次指数平滑一般应用于直线型数据,且一次指数平滑具有滞后性,可以说明有明显的时间性、季节性。
二次指数平滑一般也应用于直线型,但是效果会比一次指数平滑好很多,也就相当于加强版的一次指数平滑。
三次指数平滑可以应用于抛物线型的数据,因为数据在二次平滑过后还是具有斜率,那么可以继续使用三次指数平滑。
初值:不管什么指数平滑都会有个初值,假如数据大于20项,那么初值就可以认定为第一个数据,或者利用下列公式计算也行;假如数据小于20项,则初始值为:
低于20项一般取3,大于20的看着取就行了。
指数平滑系数α的确定
(1)经验判断
1、当时间序列呈现较稳定的水平趋势时,应选较小的α,一般可在0.05~0.20之间取值‘
2、当时间序列有波动,但长期趋势变化不大时,可选稍大的α值,常在0.1~0.4之间取值;
3、当时间序列波动很大,长期趋势变化幅度较大,呈现明显且迅速的上升或下降趋势时,宜选择较大的α值,如可在0.6~0.8间选值。以使预测模型灵敏度高些,能迅速跟上数据的变化。
4、当时间序列数据是上升(或下降)的发展趋势类型,α应取较大的值,在0.6~1之间。
一次指数平滑:
一次指数平滑需要滞后一期,给定平滑系数,那么一次指数平滑的计算公式为:
预测第期的数值则是上一期的实际值与预测值的加权平均,预测公式为:
二次指数平滑:
给定平滑系数,那么二次指数平滑的计算公式为:
预测未来期的值的计算公式为:
其中:
三次指数平滑:
给定平滑系数,那么三次指数平滑的计算公式为:
预测未来期的值的计算公式为:
其中:
下面举例说明,数据如下:
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 |
引入均方误差概念来判断平滑系数是否准确:
要使最小则构成了一个关于的函数,由此可以得到最优的平滑系数,这里可以引入线性规划的思想来求得最优解
一次指数平滑代码:
S1_1 = [] for m in range(0, len(info_data_id)): S1_1_empty = [] x = 0 for n in range(0, 3): x = x + int(info_data_sales[m][n]) x = x / 3 S1_1_empty.append(x) S1_1.append(S1_1_empty) # print(S1_1) a = [] ##这是用来存放阿尔法的数组 info_MSE = [] ##计算均方误差来得到最优的a(阿尔法) for i in range(0, len(info_data_sales)): v = input('请输入第' + str(i + 1) + '组数据的a:') a.append(v) for i in range(0, len(info_data_sales)): MSE = 0 for j in range(0, len(info_data_sales[i])): S1_1[i].append( float(a[i]) * int(info_data_sales[i][j]) + (1 - float(a[i])) * int(S1_1[i][j])) ##计算预估值 MSE = (int(S1_1[i][j]) - int(info_data_sales[i][j])) ** 2 + MSE # print(info_data_sales[i][j], S1_1[i][j]) MSE = (MSE ** (1 / 2)) / int(len(info_data_sales[i])) ##得到均方误差 info_MSE.append(MSE) # print(info_MSE) # print(S1_1) for i in range(0, len(S1_1)): print('第' + str(i + 1) + '组的一次平滑预估值为:' + str(S1_1[i][len(S1_1[i]) - 1]) + ';均方误差为:' + str(info_MSE[i]))
二次指数平滑代码:
S2_1 = [] S2_2 = [] for m in range(0, len(info_data_id)): S2_1_empty = [] x = 0 for n in range(0, 3): x = x + float(info_data_sales[m][n]) x = x / 3 S2_1_empty.append(x) S2_1.append(S2_1_empty) S2_2.append(S2_1_empty) # print(S2_2) a = [] ##这是用来存放阿尔法的数组 info_MSE = [] ##计算均方误差来得到最优的a(阿尔法) for i in range(0, len(info_data_sales)): v = float(input('请输入第' + str(i + 1) + '组数据的a:')) a.append(v) ##下面是计算一次指数平滑的值 S2_1_new1 = [] for i in range(0, len(info_data_sales)): S2_1_new = [[]] * len(info_data_id) for j in range(0, len(info_data_sales[i])): if j == 0: S2_1_new[i].append( float(a[i]) * float(info_data_sales[i][j]) + (1 - float(a[i])) * float(S2_1[i][j])) else: S2_1_new[i].append(float(a[i]) * float(info_data_sales[i][j]) + (1 - float(a[i])) * float( S2_1_new[i][j - 1])) ##计算一次指数的值 S2_1_new1.append(S2_1_new[i]) # print(S2_1_new1) # print(len(S2_1_new1[i])) ##下面是计算二次指数平滑的值 S2_2_new1 = [] info_MSE = [] ##计算均方误差来得到最优的a(阿尔法) for i in range(0, len(info_data_sales)): S2_2_new = [[]] * len(info_data_id) MSE = 0 for j in range(0, len(info_data_sales[i])): if j == 0: S2_2_new[i].append(float(a[i]) * float(S2_1_new1[i][j]) + (1 - float(a[i])) * float(S2_2[i][j])) else: S2_2_new[i].append(float(a[i]) * float(S2_1_new1[i][j]) + (1 - float(a[i])) * float( S2_2_new[i][j - 1])) ##计算二次指数的值 MSE = (int(S2_2_new[i][j]) - int(info_data_sales[i][j])) ** 2 + MSE MSE = (MSE ** (1 / 2)) / int(len(info_data_sales[i])) info_MSE.append(MSE) S2_2_new1.append(S2_2_new[i]) # print(S2_2_new1) # print(len(S2_2_new1[i])) ##下面是计算At、Bt以及每个预估值Xt的值,直接计算预估值,不一一列举Xt的值了 u = input('你要预估多少期?') Xt = [] for i in range(0, len(info_data_sales)): At = (float(S2_1_new1[i][len(S2_1_new1[i]) - 1]) * 2 - float(S2_2_new1[i][len(S2_2_new1[i]) - 1])) Bt = (float(a[i]) / (1 - float(a[i])) * ( float(S2_1_new1[i][len(S2_1_new1[i]) - 1]) - float(S2_2_new1[i][len(S2_2_new1[i]) - 1]))) Xt.append(At + Bt * int(u)) print('第' + str(i + 1) + '组的二次平滑预估值为:' + str(Xt[i]) + ';均方误差为:' + str(info_MSE[i]))
三次指数平滑代码
S3_1 = [] S3_2 = [] S3_3 = [] for m in range(0, len(info_data_id)): S3_1_empty = [] x = 0 for n in range(0, 3): x = x + float(info_data_sales[m][n]) x = x / 3 S3_1_empty.append(x) S3_1.append(S3_1_empty) S3_2.append(S3_1_empty) S3_3.append(S3_1_empty) # print(S3_1) a = [] ##这是用来存放阿尔法的数组 info_MSE = [] ##计算均方误差来得到最优的a(阿尔法) for i in range(0, len(info_data_sales)): v = float(input('请输入第' + str(i + 1) + '组数据的a:')) a.append(v) ##下面是计算一次指数平滑的值 S3_1_new1 = [] for i in range(0, len(info_data_sales)): S3_1_new = [[]] * len(info_data_id) for j in range(0, len(info_data_sales[i])): if j == 0: S3_1_new[i].append( float(a[i]) * float(info_data_sales[i][j]) + (1 - float(a[i])) * float(S3_1[i][j])) else: S3_1_new[i].append(float(a[i]) * float(info_data_sales[i][j]) + (1 - float(a[i])) * float( S3_1_new[i][j - 1])) ##计算一次指数的值 S3_1_new1.append(S3_1_new[i]) ##下面是计算二次指数平滑的值 S3_2_new1 = [] info_MSE = [] ##计算均方误差来得到最优的a(阿尔法) for i in range(0, len(info_data_sales)): S3_2_new = [[]] * len(info_data_id) for j in range(0, len(info_data_sales[i])): if j == 0: S3_2_new[i].append(float(a[i]) * float(S3_1_new1[i][j]) + (1 - float(a[i])) * float(S3_2[i][j])) else: S3_2_new[i].append(float(a[i]) * float(S3_1_new1[i][j]) + (1 - float(a[i])) * float( S3_2_new[i][j - 1])) ##计算二次指数的值 S3_2_new1.append(S3_2_new[i]) ##下面是计算二次指数平滑的值 S3_3_new1 = [] info_MSE = [] ##计算均方误差来得到最优的a(阿尔法) for i in range(0, len(info_data_sales)): S3_3_new = [[]] * len(info_data_id) MSE = 0 for j in range(0, len(info_data_sales[i])): if j == 0: S3_3_new[i].append(float(a[i]) * float(S3_2_new1[i][j]) + (1 - float(a[i])) * float(S3_3[i][j])) else: S3_3_new[i].append(float(a[i]) * float(S3_2_new1[i][j]) + (1 - float(a[i])) * float( S3_3_new[i][j - 1])) ##计算三次指数的值 MSE = (int(S3_3_new[i][j]) - int(info_data_sales[i][j])) ** 2 + MSE MSE = (MSE ** (1 / 2)) / int(len(info_data_sales[i])) info_MSE.append(MSE) S3_3_new1.append(S3_3_new[i]) # print(S3_3_new1) ##下面是计算At、Bt、Ct以及每个预估值Xt的值,直接计算预估值,不一一列举Xt的值了 u = input('你要预估多少期?') Xt = [] for i in range(0, len(info_data_sales)): At = ( 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( S3_3_new1[i][len(S3_3_new1[i]) - 1])) Bt = ((float(a[i]) / (2 * ((1 - float(a[i])) ** 2))) * ((6 - 5 * float(a[i])) * ( float(S3_1_new1[i][len(S3_1_new1[i]) - 1]) - 2 * (5 - 4 * float(a[i])) * float( S3_2_new1[i][len(S3_2_new1[i]) - 1]) + (4 - 3 * float(a[i])) * float( S3_3_new1[i][len(S3_3_new1[i]) - 1])))) Ct = (((float(a[i])) ** 2) / (2 * ((1 - float(a[i])) ** 2))) * ( float(S3_1_new1[i][len(S3_1_new1[i]) - 1]) - float(S3_2_new1[i][len(S3_2_new1[i]) - 1])*2 + float( S3_3_new1[i][len(S3_3_new1[i]) - 1])) Xt.append(At + Bt * int(u) + Ct * (int(u) ** 2)) print('第' + str(i + 1) + '组的三次平滑预估值为:' + str(Xt[i]) + ';均方误差为:' + str(info_MSE[i]))