layout: true --- class: inverse, center, middle background-image: url(figures/titlepage16-9.png) background-size: cover <br> # 商业预测 ## 第二讲:商业预测基础 <img src="figures/qr.png" width="150px"/> #### 康雁飞 | 北航经管学院 | 数量经济与商务统计系 --- class: inverse, center, middle # 我们可以预测什么? --- # 许多情况下都需要预测: - 例如决定是否要在未来五年内建立另一个发电厂需要预测未来的用电需求量。 - 下周呼叫中心的人员日程安排,需要对呼叫量进行预测。 - 库存存货需要库存需求的预测。 - 预测可能是需要提前几年(如资本投资),或者是仅仅提前几分钟(如电信线路)。 --- # 可预测性 <img src="figures/easy_and_hard_to_forecast.png" width="800px"/> --- # 可预测性 可预测性取决于多个因素: 1. 我们对它的影响因素的了解程度; 2. 有多少数据是可用的; 3. 预测是否会影响我们试图预测的事物。 --- # 例:电力需求预测 电力需求可以非常准确地预测。 1. 电力需求很大程度上受温度影响,也受经济状况和日期的影响。 2. 假日,对电力需求的影响较小。 3. 假如有足够的电力需求和天气状况方面的历史数据,并且我们有能力建立一个合适的模型来连接电力需求和关键驱动变量的话,我们的预测可以非常准确。 --- # 例:货币汇率预测 1. 我们可以获取足够的可用的数据。 2. 但是我们对影响汇率的因素知之甚少,并且汇率的预测会对汇率本身产生影响。 3. 如果有明确的预测说汇率将会上涨,那么人们会立刻调整他们的心理价位。 4. 这是“有效市场假说”的一个例子。因此,预言汇率明天会是上涨还是下跌,就如同预言抛一枚硬币它落下将会是正面还是反面一样不可预测。 --- # 什么是好的预测? - 好的预测可以捕捉到历史数据中的真实模式和关系。 - 好的预测不是重复过去发生过未来不会再发生的事情。 - 我们将学习如何区分应该忽略的历史数据中的随机波动,和历史数据中应该建模推断的真实模式。 --- class: inverse, center, middle # 什么是时间序列预测? --- # 时间序列数据 时间序列数据样例包括: * IBM每日股票价格 * 每月降水量 * 亚马逊季度销售结果 * 谷歌年度利润 任何按照时间顺序观察的事物都是时间序列。我们将只考虑定期观察的时间序列 (例如,每小时、每天、每周、每月、每季度、每年)。 --- # 时间序列预测 预测应该是说管理决策中的一个主要组成部分,因为它在企业的很多地方都发挥着重要作用。现代企业组织需要短期、中期和长期预测, 具体预测什么取决于特定的应用场景。 - 短期预测 - 人员、生产和运输的安排调度需要短期预测。作为安排过程中的一部分,需求预测常常也是必须的。 - 中期预测 - 确定未来的资源需求需要中期预测,以便购买原材料、雇用人员或购买机器和设备。 - 长期预测 - 在战略规划中会使用长期预测。此类决定必须将市场机会、环境因素和内部资源纳入考量。 --- # 决定预测什么 - 在预测的初期阶段,需要决定应该预测的内容。例如,如果生产中的物料需要预测,应该探究以下问题是否要预测: 1. 用于每条产品线或一组产品? 2. 用于每个销售网点, 或按区域分组的网点, 或仅用于总销售额? 3. 每周数据、月度数据或年度数据? - 考虑预测的前景时段也十分必要。是需要提前1个月,提前6个月还是提前10年预测?根据哪个预测时长最为重要,我们需要不同种类的模型。 - 预测需要多频繁?需要经常进行的预测, 最好是使用自动化系统, 而不是需要仔细人工操作。 --- # 时间序列预测 1. 在大程度上,什么数据是可用的决定了适合什么合适的预测方法。 2. 如果没有可用的数据,或者如果可用的数据与预测无关,那么应该使用*定性预测*方法。这些方法不是纯粹的猜测---有完善的结构化方法来获得良好的预测, 而不使用历史数据。 3. 在满足以下两个条件的时候可以使用*定量预测* : 1. 关于过去的数字化信息是可以用的; 2. 有理由假设过去的一些模式会在未来延续下去。 --- # 时间序列预测 在预测时间序列数据时, 目的是**估计观测序列将如何持续到未来**。下图显示从1992年到2010年第二季度的澳大利亚季度啤酒产量。 <img src="BF-L2-basics_files/figure-html/beer-1.png" style="display: block; margin: auto;" /> --- # 案例 1 研究对象是一家生产餐巾纸和纸盘等一次性餐具的大型公司。他们每个月都需要对数百种产品进行预测,他们使用的方法如下: 1. 取过去12个月数据的平均值; 2. 取过去6个月数据的平均值; 3. 根据过去12个月数据拟合的直线回归进行预测; 4. 根据过去6个月数据拟合的直线回归进行预测; 5. 根据最后一次观测值和相应斜率得到的直线进行预测,其斜率等于今年观测值与去年对应月份观测值连线的平均斜率; 6. 根据最后一次观测值和相应斜率得到的直线进行预测,其斜率等于今年最近6个月观测值与去年对应月份观测值连线的平均斜率。 --- # 案例 2 在这个项目中,我们需要开发一个模型来预测澳大利亚主要航空公司的主要国内航线的周航空客运量。该公司要求对各主要国内航线及各类乘客(经济舱、商务舱和头等舱)的人数进行预测并向我们提供了前6年的航线周历史数据。 航空乘客人数会受到学校假期、重大体育赛事、广告活动、竞争行为等影响。一般情况下,澳大利亚不同城市的学校假期不会同时出现,体育赛事有时也会从一个城市转移到另一个城市。在历史数据相应期间发生过一场关键飞行员的罢工运动,其间几个月都没有相关航线运行,一条新的低价航线推出后也惨遭失败。在历史数据期间的末尾,航空公司将一些经济舱座位重新改造为商务舱和头等舱座位,然而几个月后,座位安排重新恢复到原来的状态。 --- class: inverse, center, middle # 预测的步骤 --- # 预测的步骤 1. 定义问题。最难的一步。需要沟通。 2. 收集信息。需要数据。 3. 初步(探索性)分析。看图形。有一致的模式吗?有明显的长期趋势吗?季节性重要吗?是否有证据表明商业周期存在?数据中是否包含需要专业知识解释的异常值?用于分析的变量之间的相关性有多强? 4. 选择及拟合模型。最佳模型的选择取决于历史数据的可用性、预测变量与各解释变量之间的相关性,以及预测的使用方式。比较两个或三个潜在的模型是很常见的。 5. 使用及评估预测模型。一旦模型及其参数确定后,该模型就可以用来进行预测。模型的预测效果只有用于预测的数据得到之后才能得到正确的评价。 --- # 统计预测观点 - 我们试图预测的东西是未知的(或者我们不能预测它),所以我们可以把它想象成一个*随机变量*。例如,下个月的总销售额可能会有一系列的可能值,直到月底我们把实际销售额加起来,我们才知道这个值会是多少。 - 因为下个月时间节点比较近,我们通常清楚销售量大概是多少。如果我们预测明年同一个月的销售情况,可能的销售量变动就会较大。在大多数预测情况下,随着事件的临近,预测对象的相关变动较小。换句话说,预测的越早,预测结果越不稳定。 --- # 统计预测观点 .pull-left[ - 我们可以想象许多可能性,每一个都为我们将要预测的事物带来不同的影响。右图是1980年到2015年澳大利亚的国际游客总数以及2016至2025年的10个可能的预测值。 - 我们进行预测的过程实际是寻找随机变量可能取值范围内的*中间值*。通常情况下,预测会伴随着一个预测区间,给出一个随机变量具有较高概率的范围值。例如,95%的预测区间包含一系列的值,这个预测区间包含实际未来值的概率为95%。] .pull-right[ <div class="figure" style="text-align: center"> <img src="BF-L2-basics_files/figure-html/austa1-1.png" alt="1980年到2015年澳大利亚的国际游客总数以及对2016至2025年的10个可能的预测值。" /> <p class="caption">1980年到2015年澳大利亚的国际游客总数以及对2016至2025年的10个可能的预测值。</p> </div> ] --- # 统计预测观点 .pull-left[ - 我们通常会给出这些预测区间,而不是图中显示的单个可能的预测值。 - 右图显示了未来澳大利亚国际游客的80%和95%的预测区间。 - 蓝线是可能的预测值的平均值,我们称之为“点预测”。 ] .pull-right[ <img src="BF-L2-basics_files/figure-html/austa2-1.png" style="display: block; margin: auto;" /> ] --- class: inverse, center, middle # 时间序列可视化 --- # `ts`对象 时间序列是一组按照时间发生先后顺序进行排列,并且包含一些信息的数据点序列。在R中,这些信息可以被储存在`ts`对象中。 假设我们有某个变量在过去几年中每年的观测值: <table> <thead> <tr> <th style="text-align:right;"> 年份 </th> <th style="text-align:right;"> 观测值 </th> </tr> </thead> <tbody> <tr> <td style="text-align:right;"> 2012 </td> <td style="text-align:right;"> 123 </td> </tr> <tr> <td style="text-align:right;"> 2013 </td> <td style="text-align:right;"> 39 </td> </tr> <tr> <td style="text-align:right;"> 2014 </td> <td style="text-align:right;"> 78 </td> </tr> <tr> <td style="text-align:right;"> 2015 </td> <td style="text-align:right;"> 52 </td> </tr> <tr> <td style="text-align:right;"> 2016 </td> <td style="text-align:right;"> 110 </td> </tr> </tbody> </table> 我们可以采用`ts()`函数将数据转化为`ts`类型: ```r y <- ts(c(123,39,78,52,110), start=2012) ``` --- # `ts`对象 假如一个变量的观测频率大于每年一次,我们可以通过设置`frequency`参数来设置频率。例如,如果我们的月度数据已经被储存在了数值型向量`z`中,那么我们可以用如下的方式将其转换为时间序列: ```r y <- ts(z, start=2003, frequency=12) ``` --- # 时间图 对于时间序列数据而言,我们从最简单的时间图开始。时间图是用将观测值与观测时间点作图,散点之间用直线连接。 .pull-left[ ```r autoplot(melsyd[,"Economy.Class"]) + ggtitle("墨尔本 - 悉尼经济舱乘客客流量") + xlab("年份") + ylab("千")+ theme(plot.title = element_text(hjust = 0.5)) ``` ] .pull-right[ <img src="BF-L2-basics_files/figure-html/ansett-out-1.png" style="display: block; margin: auto;" /> ] ??? 该时间图直观地展现出数据具有的一些特征: - 由于1989年当地的工业纠纷,当年的客流量为0。 - 在1992年中,由于一部分经济舱被商务舱取代,导致客流量大幅减少。 - 1991年下半年客流量大幅上升。 - 由于假日效应,在每年年初,客流量都会有一定幅度的下降。 - 这是序列存在长期波动,在1987年向上波动,在1988年向下波动,而在1990年和1991年又再次向上波动。 - 在某些时期存在缺失值。 --- # 时间序列模式 我们通常使用例如“趋势”、“季节性”等词语描述时间序列。在深入研究时间序列模式时,应该更精确的定义这些词语。 - 趋势:当一个时间序列数据长期增长或者长期下降时,表示该序列有 **趋势** 。在某些场合,趋势代表着“转换方向”。例如从增长的趋势转换为下降趋势。 - 季节性:当时间序列中的数据受到季节性因素(例如一年的时间或者一周的时间)的影响时,表示该序列具有 **季节性** 。 - 周期性:当时间序列数据存在不固定频率的上升和下降时,表示该序列有 **周期性** 。 --- # 它们的模式? <img src="BF-L2-basics_files/figure-html/6-decomp1-1.png" style="display: block; margin: auto;" /> ??? 1. 美国新建房屋销售额(左上)表现出强烈的年度季节性,以及周期为6~10年的周期性。但是数据并没有表现出明显的趋势。 2. 美国国债价格(右上)表示1981年美国国债在芝加哥市场连续100个交易日的价格。可以看出,该序列并没有季节性,但是有明显下降的趋势。假如我们拥有该序列更多的观测数据,我们可以看到这个下降的趋势是一个长期循环的一部分。但是现在我们只有连续100天的数据,它表现出下降的趋势。 3. 澳大利亚月度电力产值数据(左下)明显表现出向上增长的趋势,以及强季节性。但是并不存在周期性。 4. Google收盘股价格(右下)的价格波动没有趋势,季节性和周期性。随机波动没有良好的形态特性,不能很好地预测。 --- # 季节图 季节图和时间序列图很相似,不同之处是季节图是针对观察数据的“季节性”绘制的。下面的例子是降糖药物的销售情况。 .pull-left[ ```r ggseasonplot(a10, year.labels=TRUE, year.labels.left=TRUE) + xlab("月份")+ ylab("百万(美元)") + ggtitle("季节图:降糖药物销量")+ theme(plot.title = element_text(hjust = 0.5)) ``` ] .pull-right[ <img src="BF-L2-basics_files/figure-html/seasonplot1-out-1.png" style="display: block; margin: auto;" /> ] --- # 季节图(极坐标) .pull-left[ ```r ggseasonplot(a10, polar=TRUE) + xlab("月份")+ ylab("百万(美元)") + ggtitle("极坐标季节图:降糖药物销量")+ theme(plot.title = element_text(hjust = 0.5)) ``` ] .pull-right[ <img src="BF-L2-basics_files/figure-html/seasonplot2-out-1.png" style="display: block; margin: auto;" /> ] --- # 子序列季节图 .pull-left[ ```r ggsubseriesplot(a10) + xlab("月份")+ ylab("百万(每月)") + ggtitle("子序列季节图:降糖药物销量")+ theme(plot.title = element_text(hjust = 0.5)) ``` ] .pull-right[ <img src="BF-L2-basics_files/figure-html/subseasonplot1-out-1.png" style="display: block; margin: auto;" /> ] --- # 实验2 1. 使用帮助函数了解 `gold`、`woolyrnq` 和 `gas` 时间序列 - 使用 `autoplot()` 分别绘制上述序列。 - 各个序列的频率是多少? 提示:运用 `frequency()` 函数。 2. `arrivals` 数据包括从日本、新西兰、英国和美国到达澳大利亚的人数(千)。请使用 `autoplot()` 和 `ggseasonplot()` 函数比较四个国家到达澳大利亚人数的不同之处。你对这些时间序列有什么认识? --- class: inverse, center, middle # 一些简单的预测方法 --- # 均值法 此方法中,所有未来值的预测值等于历史数据的平均值。我们把历史数据记作 `\(y_{1},\dots,y_{T}\)`,预测值就可以表示为: `$$\hat{y}_{T+h|T} = \bar{y} = (y_{1}+\dots+y_{T})/T.$$` ```r meanf(y, h) # y 历史数据时间序列 # h 预测期数 ``` --- # Naïve 方法 在 naïve 预测方法中,我们简单地将所有预测值设为最后一次的观测值,即: `$$\hat{y}_{T+h|T} = y_{T}.$$` 这种方法在很多经济和金融时间序列预测中表现得非常好。 ```r naive(y, h) rwf(y, h) # 二者等价 ``` --- # 季节性 Naïve 方法 季节性 Naïve 方法与 Naïve 方法类似,它适用于季节性变化剧烈的数据。我们将每个预测值设为同一季节的前一期观测值(例如:去年的同一个月)。那么: `$$\hat{y}_{T+h|T} = y_{T+h-km},$$` 等式中 `\(m\)` 为周期长度, `\(k\)` 是 `\((h-1)/m\)` 的整数部分(也就是在 `\(T + h\)` 时刻前预测期所包含的整年数)。 ```r snaive(y, h) ``` --- # 漂移法 相对于 Naïve 方法,趋势法(漂移法)允许预测值随着时间的推移增大或减小,并且我们假定单位时间改变量(称作 “漂移”)等于历史数据的平均改变量,因此 `\(T+h\)` 时刻的预测值可以表示为: `$$\hat{y}_{T+h|T} = y_{T} + \frac{h}{T-1}\sum_{t=2}^T (y_{t}-y_{t-1}) = y_{T} + h \left( \frac{y_{T} -y_{1}}{T-1}\right).$$` 这相当于把第一个观测点和最后一个观测点连成一条直线并延伸到未来预测点。 ```r rwf(y, h, drift=TRUE) ``` --- # 例:啤酒销量预测 .pull-left[ ```r # 设定1992年至2007年为训练数据 beer2 <- window(ausbeer,start=1992,end=c(2007,4)) # 画出预测图 autoplot(beer2) + autolayer(meanf(beer2, h=11)$mean, series="均值") + autolayer(naive(beer2, h=11)$mean, series="Naïve") + autolayer(snaive(beer2, h=11)$mean, series="季节性 naïve") + ggtitle("啤酒季度销量的预测") + xlab("年份") + ylab("百万升") + guides(colour=guide_legend(title="预测")) + theme(plot.title = element_text(hjust = 0.5)) ``` ] .pull-right[ <img src="BF-L2-basics_files/figure-html/beerf-out-1.png" style="display: block; margin: auto;" /> ] --- # 例:谷歌股票收盘价预测 .pull-left[ ```r # 画出预测图 autoplot(goog200) + autolayer(meanf(goog200, h=40), PI=FALSE, series="均值") + autolayer(rwf(goog200, h=40), PI=FALSE, series="Naïve") + autolayer(rwf(goog200, drift=TRUE, h=40), PI=FALSE, series="漂移") + ggtitle("每日谷歌股票收盘价(截止到2013年12月6日)的预测") + xlab("天") + ylab("收盘价 (美元)") + guides(colour=guide_legend(title="预测")) + theme(plot.title = element_text(hjust = 0.5)) ``` ] .pull-right[ <img src="BF-L2-basics_files/figure-html/googf-out-1.png" style="display: block; margin: auto;" /> ] -- - 有时候这些最简单的方法可能会是最好的预测方法。 - 但是在很多情况下,这些方法只是作为基准方法而不是被直接运用。 --- # 评估预测精度 - 使用真实的预测来评估预测精度是很重要的。 - 残差的大小并不能很好地表示真实预测误差的大小。 - 评估模型预测精度只能通过模型在新数据中的预测效果决定。 - 在选择模型时,通常我们会将可用数据分成训练数据集和测试数据集两部分,其中训练数据集用于估计预测方法中的任意参数,而测试数据集用于评估预测精度。 - 由于训练数据集并没有用于确定预测模型,因此它能可靠地检验模型对于新数据的预测准确性。 --- # 评估预测精度 ```r googfc1 <- meanf(goog200, h=40) googfc2 <- rwf(goog200, h=40) googfc3 <- rwf(goog200, drift=TRUE, h=40) googtest <- window(goog, start=201, end=240) accuracy(googfc1, googtest) accuracy(googfc2, googtest) accuracy(googfc3, googtest) ``` --- # 本讲总结 1. 我们可以预测什么? 2. 什么是时间序列预测? 3. 预测的步骤 4. 可视化 5. 一些简单的预测方法