前言

  每年(或许是从11月份开始,或许是从9月份开始),企业中层管理人员都要忙于做预算了。
  预算的重中之重,自然是销售预算。
  尽管理论上有零基预算、弹性预算等等,但是在实际操作上,恐怕使用最多的方法还是“拍脑袋预算”!
  什么是“拍脑袋预算”呢?
  就是高层简单粗暴地要求:明年的销售收入预算,要比今年增长40%、60%,或者80%......
  从前一位集团董事长和下属公司总经理编制年度预算,董事长因势利导引诱总经理多次拔高销售预测...结果,年终将近,预算没有实现,董事长责怪总经理没有完成预算,总经理委屈地说:“当初我们就没有定那么高的预算,是您一再要求我们,说是即便达不到,但是目标还是可以放高远一点的嘛......”
  这不是一个笑话!特别是绩效考核与预算实现程度挂钩的情况下,这事儿更加纠结......
  这年头和钱有关的还有什么事情是确定的呢?政策、市场、跨界打劫者、双边多边关系...瞬息万变,预算到底应该定到多高,谁能知道呢?

把责任推给自动化

  如果有一种大家都认可的方法,可以自动计算出预算值,那就好了!

焦点转移

  100%完全自动化是不可能的,也不符合直觉。
  但是,可以转移争议的焦点,从争论预算值是高了还是低了?,转移为应该更加关注过去,还是关注现在
  或者也可以说,是当前期间数据对预测值的影响更大,还是前期历史数据对预测值的影响更大?

客观确定 $\alpha$ 值

  这个焦点,就是 $\alpha$ 值的确定。

  1. 当时间序列呈现较稳定的水平趋势时,应选较小的 $\alpha$ ,一般可在0.05~0.20之间取值
  2. 当时间序列有波动,但长期趋势变化不大时,可选稍大的 $\alpha$ 值,常在0.1~0.4之间取值
  3. 当时间序列波动很大,长期趋势变化幅度较大,呈现明显且迅速的上升或下降趋势时,宜选择较大的 $\alpha$ 值,如可在0.6~0.8间选值,以使预测模型灵敏度高些,能迅速跟上数据的变化
  4. 当时间序列数据是上升(或下降)的发展趋势类型,$\alpha$ 应取较大的值,在0.6~1之间

时间序列分析方法

  时间序列就是按时间顺序排列的,随时间变化的数据序列。譬如我们熟知的GDP,CPI、销售额,顾客数,访问量...
  随机过程的特征包括均值、方差、协方差等。如果随机过程的特征随着时间变化,则称此过程是非平稳的;如果随机过程的特征不随时间而变化,就称此过程是平稳的。
  非平稳时间序列分析时,如果导致非平稳的原因是确定的,可以用的方法主要有趋势拟合模型、季节调整模型、移动平均、指数平滑等方法。如果导致非平稳的原因是随机的,方法主要有ARIMA(autoregressive integrated moving average)及自回归条件异方差模型等。

均值

$$\overline{X} = \frac{\sum_{i=1}^n X_i}{n}$$

方差

  方差用于描述随机变量对于数学期望的偏离程度,等于各个数据与其算术平均数的离差平方和的平均数,分离散型和连续型两种,称为标准差或均方差。

  标准差:$$s = \sqrt{ \frac{\sum_{i=1}^n (X_i-\overline{X})^2}{n-1} }$$

  方差:$$s^2 = \frac{\sum_{i=1}^n (X_i-\overline{X})^2}{n-1}$$

协方差

  标准差和方差描述的是一维数据,而协方差是用来度量两个随机变量关系的统计量。大于两个随机变量的就是协方差矩阵。

  协方差统计结果的意义
   如果结果为正值,说明两者是正相关的
  
如果结果为负值,说明两者是负相关的
   * 如果结果为0,说明两者不线性相关

$$cov(X,Y)=\frac{\sum_{i=1}^n (X_i-\overline{X})(Y_i-\overline{Y})}{n-1}$$

自动化模型的选择

  一方面,导致非平稳的原因,于汇市、股市而言是不确定的,因为很难有一股决定性力量可以左右大势(A股或许除外),而企业销售额,固然市场千变万化,但是一般情况下主要还是可以由产品特性、市场营销等手段来主导。所以,导致非平稳的原因,于企业销售额而言是基本可确定的。
  另一方面,趋势拟合只是对不具有线性关系的离散点拟合出一条逼近直线、简单移动平均因为缺乏权数调整而与现实不符、季节性调整在月份预测中有效,但年度预测无效。或许经济周期可以是一个考虑因素,但对于仅仅预测一年或者两年,则经济周期的影响非常有限。
  综上所述,指数平滑方法对于企业销售是一种最有效的方法。

准备数据

  已知数据:从1997年到2016年,每年的销售额如下图所示:

In [582]:
import pandas as pd 
import numpy as np 
import matplotlib.pyplot as plt 
import statsmodels.api as sm 
annual= ['2016','2015','2014','2013','2012','2011','2010','2009','2008','2007','2006','2005','2004','2003','2002','2001','2000','1999','1998','1997']
incoming=[12.95,12.07,12.37,12.08,12.10,11.93,11.90,11.95,12.14,12.10,12.09,12.40,12.29,12.41,12.86,13.38,14.03,14.64,15.64,16.57]
annual.reverse()
incoming.reverse()
time_series = pd.Series(incoming) 
time_series.index = pd.Index(sm.tsa.datetools.dates_from_range('1997','2016')) 
time_series.plot(figsize=(12,6)) 
plt.show()

一次指数平滑

配置一次指数平滑函数

In [583]:
def exSm(a):
    se=[]
    for i in range(len(annual)):
        pre=0.
        if not i == 0:
            pre = a * incoming[i]+(1-a)*se[i-1]
        else:
            pre = a*incoming[i] + (1-a)*(incoming[0]+incoming[1]+incoming[2])/3
        se.append(round(pre,2))
    predict=a*incoming[-1]+(1-a)*se[-1]
    newyear=['2017']
    annual_pre=annual+newyear
    i=[]
    i.append(incoming[-1])
    incom_pre=incoming+i
    se.append(predict)
    x = annual_pre
    y1= incom_pre
    y2= se
    xmark=[annual[-1],annual[-1]]
    ymark=[min(se),max(se)]
    fig = plt.figure(figsize=(12,6))
    l1, = plt.plot(x, y1, 'r--', label="imcoming", marker ='o')
    l2, = plt.plot(x, y2, 'g-', label="$ES^{(1)}$", marker ='o')
    l3, = plt.plot(xmark, ymark, 'b-')
    plt.legend(handles=[l1, l2], loc = 0, frameon=False, fontsize=16)
    plt.grid(True)
    plt.show()

一次指数平滑效果图

$\alpha=0.2$

In [584]:
exSm(0.2)

$\alpha=0.5$

In [585]:
exSm(0.5)

$\alpha=0.8$

In [586]:
exSm(0.8)

二次指数平滑

  因为一次指数平滑法不适用于呈斜坡型线性变动的历史数据,所以我们选择使用二次指数平滑法。

配置二次指数平滑函数

In [587]:
def exSm(a):
    se=[]
    for i in range(len(annual)):
        pre=0.
        if not i == 0:
            pre = a * incoming[i]+(1-a)*se[i-1]
        else:
            pre = a*incoming[i] + (1-a)*(incoming[0]+incoming[1]+incoming[2])/3
        se.append(round(pre,2))
    pred=a*incoming[-1]+(1-a)*se[-1]
    se2=[]
    se2.append(se[0])
    for j in range(1, len(annual)):
        pre2=a * se[j] + (1-a) * se2[j-1]
        se2.append(round(pre2,2))        
    at = 2*se[-1]-se2[-1]
    bt = a/(1-a) * (se[-1]-se2[-1])
    Y_next = round((at+bt*1),2)
    Y_next_next = round((at+bt*2),2)    
    newyear=['2017','2018']
    annual_pre=annual+newyear
    i=[]
    i.append(incoming[-1])
    i.append(incoming[-1])
    incom_pre=incoming+i
    se.append(pred)
    se.append(pred)
    se2.append(Y_next)
    se2.append(Y_next_next)
    x = annual_pre
    y1= incom_pre
    y2= se
    y3=se2
    xmark=[annual[-1],annual[-1]]
    ymark=[min(se2)*0.95,max(se2)]    
    fig = plt.figure(figsize=(12,6))
    l1, = plt.plot(x, y1, 'r--', label="imcoming", marker ='o')
    l2, = plt.plot(x, y2, 'g--', label="$ES^{(1)}$", marker ='o')
    l3, = plt.plot(x, y3, 'k-', label="$ES^{(2)}$", marker ='o')
    l4, = plt.plot(xmark, ymark, 'b-')
    plt.legend(handles=[l1, l2, l3], loc = 0, frameon=False, fontsize=16)
    plt.grid(True)
    plt.show()   
    mm=pd.DataFrame(x,columns=['x'])
    mm=pd.concat([mm,pd.DataFrame(y1,columns=['y1'])],axis=1)
    mm=pd.concat([mm,pd.DataFrame(y2,columns=['y2'])],axis=1)
    mm=pd.concat([mm,pd.DataFrame(y3,columns=['y3'])],axis=1)
    print(mm)

二次指数平滑效果图

$\alpha=0.3$

In [588]:
exSm(0.3)
       x     y1      y2     y3
0   1997  16.57  15.900  15.90
1   1998  15.64  15.820  15.88
2   1999  14.64  15.470  15.76
3   2000  14.03  15.040  15.54
4   2001  13.38  14.540  15.24
5   2002  12.86  14.040  14.88
6   2003  12.41  13.550  14.48
7   2004  12.29  13.170  14.09
8   2005  12.40  12.940  13.74
9   2006  12.09  12.680  13.42
10  2007  12.10  12.510  13.15
11  2008  12.14  12.400  12.93
12  2009  11.95  12.260  12.73
13  2010  11.90  12.150  12.56
14  2011  11.93  12.080  12.42
15  2012  12.10  12.090  12.32
16  2013  12.08  12.090  12.25
17  2014  12.37  12.170  12.23
18  2015  12.07  12.140  12.20
19  2016  12.95  12.380  12.25
20  2017  12.95  12.551  12.57
21  2018  12.95  12.551  12.62

$\alpha=0.5$

In [589]:
exSm(0.5)
       x     y1      y2     y3
0   1997  16.57  16.090  16.09
1   1998  15.64  15.870  15.98
2   1999  14.64  15.250  15.62
3   2000  14.03  14.640  15.13
4   2001  13.38  14.010  14.57
5   2002  12.86  13.430  14.00
6   2003  12.41  12.920  13.46
7   2004  12.29  12.610  13.04
8   2005  12.40  12.500  12.77
9   2006  12.09  12.290  12.53
10  2007  12.10  12.200  12.36
11  2008  12.14  12.170  12.27
12  2009  11.95  12.060  12.16
13  2010  11.90  11.980  12.07
14  2011  11.93  11.960  12.02
15  2012  12.10  12.030  12.02
16  2013  12.08  12.050  12.04
17  2014  12.37  12.210  12.12
18  2015  12.07  12.140  12.13
19  2016  12.95  12.540  12.34
20  2017  12.95  12.745  12.94
21  2018  12.95  12.745  13.14

$\alpha=0.7$

In [590]:
exSm(0.7)
       x     y1      y2     y3
0   1997  16.57  16.280  16.28
1   1998  15.64  15.830  15.96
2   1999  14.64  15.000  15.29
3   2000  14.03  14.320  14.61
4   2001  13.38  13.660  13.95
5   2002  12.86  13.100  13.36
6   2003  12.41  12.620  12.84
7   2004  12.29  12.390  12.53
8   2005  12.40  12.400  12.44
9   2006  12.09  12.180  12.26
10  2007  12.10  12.120  12.16
11  2008  12.14  12.130  12.14
12  2009  11.95  12.000  12.04
13  2010  11.90  11.930  11.96
14  2011  11.93  11.930  11.94
15  2012  12.10  12.050  12.02
16  2013  12.08  12.070  12.05
17  2014  12.37  12.280  12.21
18  2015  12.07  12.130  12.15
19  2016  12.95  12.700  12.54
20  2017  12.95  12.875  13.23
21  2018  12.95  12.875  13.61

指数平滑模型

模型计算公式

一次指数平滑公式

$$\gamma_{t+1}^*=\alpha \gamma_{t}+(1-\alpha)\gamma_t^*$$

其中:

符号 含义
$\gamma_{t+1}^*$ t+1 期的预测值(或称本期 ( t 期)的平滑值 $S_t$)
$\gamma_t$ t 期的实际值
$\gamma_t^*$ t 期的预测值,即上期的平滑值 $S_{t-1}$

二次指数平滑公式

  利用滞后偏差的规律找出曲线的发展方向和发展趋势,然后建立直线趋势预测模型,故称为二次指数平滑法。

$$S_t^{(2)}=\alpha S_t^{(1)}+(1-\alpha)S_{t-1}^{(2)}$$

其中:

符号 含义
$S_t^{(2)}$ 第 t 周期的二次指数平滑值
$S_t^{(1)}$ 第 t 周期的一次指数平滑值
$S_{t-1}^{(2)}$ 第 t-1 周期的二次指数平滑值
$\alpha$ 加权系数(也称为平滑系数)

二次指数平滑预测公式

  二次平滑指数不能单独地进行预测,必须与一次指数平滑法配合,建立预测的数学模型,然后运用数学模型确定预测值。

$$\hat{Y}_{t+T}=a_t + b_t\bullet T$$

  其中:

符号 含义
$\hat{Y}_{t+T}$ t+T 的预测值
$T$ t 期到预测期的间隔期数
$a_t , b_t$ 参数

其中参数$a_t$和$b_t$的计算公式为:
\begin{equation} \left\{ \begin{array}{lr} a_t=2S_t^{(1)}-S_t^{(2)} & \\ b_t=\dfrac{\alpha}{1-\alpha}(S_t^{(1)}-S_t^{(2)}) & \\ \end{array} \right. \end{equation}

其中$S_t^{(1)}$和$S_t^{(2)}$分别为一次和二次指数平滑值,其计算公式为: $$S_t^{(1)}=\alpha x_t^{(1)}+(1-\alpha)S_{t-1}^{(1)}$$

$$S_t^{(2)}=\alpha S_t^{(1)}+(1-\alpha)S_{t-1}^{(2)}$$

模型理论基础

爱与彼岸财经分析团队编制

爱与彼岸财经分析