Introduction
Many workforce management software systems also use this time-series process as a base for forecasting, so understanding this process may help you better understand how your software works and more easily explain the results to others.
-
trend: simply the rate of change of call history. (trend rate 大部分是正的,但也有负增长率)
While most trend rates tend to be positive and growing, the trend rate could also be a declining rate.The standard way to calculate trend is to first look at an annual trend rate and then to break the annual trend into monthly numbers.
-
seasonality: because any given month’s data will contain the effects of both trend and seasonality, it is important to remove the trend as an influence so seasonal influences can be isolated and viewed more clearly. (需要将第一部分的 trend 因素移除,使得季节性因素能够独立分析)
“Monthly Trend and Seasonal Factor”算法比较简单,本文提供的代码也相对简单,一步一步实现,目的是尽可能详细记录过程但可能有些繁琐。
steps
1)Calculating trend:根据历史数据计算趋势增长率(正增长、负增长)得到 monthly rate,如:2016年:2015年;
2)Detrend:抵消历史数据中 trend 趋势因素,使得后续能够独立比较季节性的因素,获得 avg_detrended_value;This detrending happens by factoring in a monthly trend factor to each month of data to bring all call history up to current levels.
3)Seasonal factors:当 detrending 完成后,计算季节性因子,获得每个月对应的 seasonal_factors;
4)根据 monthly_rate, avg_detrended_value, seasonal_factors 进行预测:如, 预测2018年6月份 predict_6_month = avg_detrended_value * ( monthly_rate )^ 6 * seasonal_factors(6月份);注意式中是使用去趋势化后的所有月份的均值 avg_detrended_value,而不是使用当月份(如,6月份)的实际值。
Script
# -*- coding: utf-8 -*-
# @Date : 20180620 - afternoon
# @Language : Python3.6
# @author : 初类
from matplotlib import pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
import xlrd
import xlwt
import numpy as np
# =============================================================================
# plot
# =============================================================================
def plot_results_multiple(data_year_list, class_name):
fig = plt.figure(facecolor='white')
## real data
ax11 = fig.add_subplot(321)
ax11.plot(x_lable, data_year_list[0], label='2013-real data')
ax11.plot(x_lable, data_year_list[1], label='2014-real data')
ax11.plot(x_lable, data_year_list[2], label='2015-real data')
ax11.plot(x_lable, data_year_list[3], label='2016-real data')
ax11.plot(x_lable, data_year_list[4], label='2017-real data')
# ax11.plot(np.arange(1, len(data_year_list[5])+1), data_year_list[5], label='2018-real data')
ax11.set_ylabel('GMV: Gross Merchandise Volume')
ax11.set_title(u'{}'.format(class_name))
ax11.xaxis.grid()
plt.legend()
## error
ax12 = fig.add_subplot(322)
ax12.scatter(x_lable, data_year_list[10], label='2015-error')
ax12.scatter(x_lable, data_year_list[11], label='2016-error')
ax12.scatter(x_lable, data_year_list[12], label='2017-error')
# ax12.plot(np.arange(1, len(data_year_list[13])+1), data_year_list[13], label='2018-error')
ax12.set_xlabel('Month from 1 to 12')
ax12.set_ylabel('predict error')
ax12.xaxis.grid()
plt.legend()
## predict-real:2015
ax21 = fig.add_subplot(323)
ax21.bar(x_lable, data_year_list[2], alpha=0.8, label='2015-real data')
ax21.bar(x_lable, data_year_list[6], alpha=0.5, label='2015-predict data')
plt.legend(loc='upper left')
ax21_2 = ax21.twinx()
ax21_2.plot(x_lable, data_year_list[10], 'r', label='2015-error')
ax21.xaxis.grid()
plt.legend(loc='upper right')
## predict-real:2016
ax22 = fig.add_subplot(324)
ax22.bar(x_lable, data_year_list[3], alpha=0.8, label='2016-real data')
ax22.bar(x_lable, data_year_list[7], alpha=0.5, label='2016-predict data')
plt.legend(loc='upper left')
ax22_2 = ax22.twinx()
ax22_2.plot(x_lable, data_year_list[11], 'r', label='2016-error')
ax22.xaxis.grid()
plt.legend(loc='upper right')
## predict-real:2017
ax31 = fig.add_subplot(325)
ax31.bar(x_lable, data_year_list[4], alpha=0.8, label='2017-real data')
ax31.bar(x_lable, data_year_list[8], alpha=0.5, label='2017-predict data')
plt.legend(loc='upper left')
ax31_2 = ax31.twinx()
ax31_2.plot(x_lable, data_year_list[12], 'r', label='2017-error')
ax31.xaxis.grid()
plt.legend(loc='upper right')
# =============================================================================
# ## predict-real:2018
# ax32 = fig.add_subplot(326)
# ax32.bar(np.arange(1, len(data_year_list[5])+1), data_year_list[5], alpha=0.8, labe