计量经济学(一)——时间序列平稳化的Holt-Winters方法
在计量经济学和时间序列分析中,Ping稳性是建模和预测的重要前提条件。Ping稳时间序列能够帮助分析师和研究人员更好地理解和预测数据的行为。研究时间序列是依据已知的历史数据,来预测未来的趋势、季节性和变化情况。时间序列数据与一般数据的最大区别在于数据点之间存在时间的依赖关系,时间是数据的重要自变量。时间序列预测的目标是利用这种依赖关系,识别数据中潜在的模式并进行未来趋势的预测。
时间为自变量:时间序列数据以时间为自变量,表示不同时间点上的数据变化情况。时间可以是连续的,例如每秒、每分钟、每小时,也可以是离散的,如每天、每月、每年。每个时间点上对应的值(也称为依变量或响应变量)可以是单一的,也可以是多个变量的组合。
数据的顺序性:时间序列数据与传统回归分析中独立同分布的数据不同,它是按时间顺序排列的,前一个数据点与后一个数据点之间存在依赖关系。因此,数据顺序是时间序列分析和预测中不可忽视的因素。
连续或离散:时间序列可以是连续型的,如温度、气压等随时间变化的物理量;也可以是离散型的,例如每日商品销售量、每月的失业率等。这种形式的区别决定了时间序列数据的处理方式和建模技术的不同选择。
一、Ping稳时间序列
Ping稳时间序列是指其统计特性(如均值、方差和自相关性)不随时间变化的时间序列。
均值恒定: Ping稳时间序列的均值不随时间变化。这意味着如果我们对序列在不同时间段进行观察,计算得到的均值应相同。举例来说,若一组月度温度数据在每年相同月份的均值稳定,那么这个序列可能是Ping稳的。
方差恒定: Ping稳时间序列的方差也应保持不变。无论在序列的哪个时间段,数据的波动幅度应相似。例如,股票价格的波动幅度若在不同时间段保持一致,则该序列可能为Ping稳序列。
自相关性不变: 自相关性指的是序列中某一时刻的数据与其他时刻数据之间的相关程度。在Ping稳时间序列中,自相关性只与时间滞后有关,而不与具体的时间点有关。这意味着,如果我们计算序列中任意时刻的自相关性,结果只取决于两个数据点之间的时间间隔,而与它们的具体位置无关。
1.1 宽Ping稳时间序列
Ping稳时间序列可以分为两大类:严格Ping稳是指无论如何对时间序列进行Ping移、缩放或变换,其分布特性保持不变。在这种情况下,对于任意时间点\(t_1, t_2, \ldots, t_n\),其联合分布与时间无关。严格Ping稳的序列在理论上是理想化的,实际中较少遇到,要求记为苛刻。宽Ping稳(弱Ping稳)只要求序列的均值和方差不随时间变化,且自协方差只与滞后时间有关。宽Ping稳是实际分析中更常见的形式,因此通常只关注均值和方差的恒定性。
宽Ping稳(弱Ping稳)时间序列是一种满足以下三个条件的时间序列。
- 均值恒定:宽Ping稳时间序列的均值不随时间变化,即对于任意时刻 $ t $,时间序列的期望 $ E(Y_t) $ 是一个常数,不依赖于时间 $ t $:\[E(Y_t) = \mu, \quad \forall t \]
这意味着序列的中心位置在整个时间范围内保持稳定。若时间序列的均值随时间发生变化,则它表现出趋势,这样的序列就不能被视为宽Ping稳序列。
- 方差恒定:宽Ping稳时间序列的方差也必须保持不变,且不依赖于时间。这意味着时间序列中的波动幅度在所有时间点上是相同的,具体表现为:\[\text{Var}(Y_t) = E((Y_t - \mu)^2) = \sigma^2, \quad \forall t \]
如果时间序列的方差随时间变化,数据的波动性会变得不稳定,这样的序列也不符合宽Ping稳的定义。
- 自协方差仅与滞后时间有关:宽Ping稳时间序列的自协方差只与时间的滞后间隔 $ h $ 有关,而不依赖于具体的时间点。自协方差描述的是序列中不同时刻数据的相关性,具体形式为:\[\text{Cov}(Y_t, Y_{t+h}) = \gamma(h), \quad \forall t \]
这里的 $ \gamma(h) $ 只与滞后时间 \(h\) 相关,而与时间点 \(t\) 无关。这意味着时间序列中相隔一定时间的两个数据点之间的关系是固定的,不会随着时间的推移而变化。
1.2 宽Ping稳的检验方法
为了判断一个时间序列是否宽Ping稳,常用的方法包括统计检验和图形分析。
- 时间序列图:绘制时间序列图,观察数据的波动范围、趋势和季节性。如果序列的波动性保持稳定,没有明显的趋势性变化,则该序列可能是宽Ping稳的。
- 自相关函数(ACF)分析:通过计算序列的自相关函数,可以判断序列是否存在滞后相关性。若自相关函数随着滞后时间的增加迅速衰减,则说明序列可能是宽Ping稳的。如果自相关函数呈现非Ping稳性特征(如逐渐衰减到零),则可能需要进行差分等操作以使序列Ping稳。
- 单位根检验:常见的单位根检验方法包括Dickey-Fuller检验、增强Dickey-Fuller(ADF)检验和Phillips-Perron检验等。通过这些检验,可以判断时间序列中是否存在单位根,进而判断其是否Ping稳。若检验结果表明存在单位根,则该序列非Ping稳,需要进行转化处理。
- KPSS检验:KPSS检验的原假设是时间序列是Ping稳的,与单位根检验不同。若KPSS检验的结果拒绝Ping稳假设,则说明序列可能存在非Ping稳性。
在实际的时间序列分析中,宽Ping稳是一种更加实用的Ping稳性定义,因为它只关注序列的均值、方差和自协方差这三个关键的统计量。相比之下,严格Ping稳要求序列的联合分布在任意时间段都保持不变,这在实际应用中较为苛刻,且难以验证。而宽Ping稳的条件相对宽松,主要集中在序列的低阶矩(均值、方差和协方差)上,因而更容易满足。经济、金融、气象和其他领域中的许多时间序列都可以被视为宽Ping稳序列。例如,股票的日收益率、商品价格波动、温度变化等,虽然这些序列可能不具备严格Ping稳的性质,但它们的均值和波动性在较长时间内相对稳定,自协方差也随着滞后时间呈现出一定的规律性,因此可以被认为是宽Ping稳序列。
二、非Ping稳序列的成分和转化
鉴于时间序列的复杂多样性,人们通常通过识别其内在特征来更好地理解和建模时间序列数据。这些特征包括趋势、季节性、周期性和随机波动等,这些成分有助于分析时间序列的行为和变化规律。然而,许多时间序列在其原始状态下是非Ping稳的,无法直接应用于大多数传统的统计模型和计量经济学模型。为了能够对非Ping稳时间序列进行分析,人们通常需要将其转化为Ping稳序列。
2.1 时间序列的成分特征
在时间序列预测中,理解其基本的特征是进行有效建模的关键。时间序列通常由四个基本成分组成。
趋势(Trend):
趋势指时间序列随着时间推移呈现出的长期上升或下降的变化趋势。这种变化可能是线性的,也可能是非线性的。例如,随着经济发展,国家GDP可能呈现出长期的上升趋势。趋势通常反映了时间序列中的长期走向,并可能受外部因素影响,如技术进步、政策变化或市场扩展。
在建模时,去除趋势或将趋势部分单独建模有助于更好地分析其他成分,例如周期性和随机波动。线性趋势可以通过线性回归去除,而对于非线性趋势,通常使用更复杂的回归或Ping滑方法。
季节性(Seasonality):
季节性是指时间序列中在固定周期内出现的重复模式。例如,每年冬季的供暖需求增加、夏季冷饮销售上升等都是季节性特征。季节性通常是由自然、社会或经济规律引起的,且周期性较为规律。
季节性通常可以用周期性函数(如正弦或余弦函数)建模,或者通过季节性差分等方法进行处理。理解季节性特征有助于对未来相似时间点的趋势做出预测。
周期性(Cyclicality):
周期性与季节性相似,都是周期性的波动,但不同的是,周期性变化不一定是固定的时间间隔,可能持续数年或数月,且频率不稳定。经济中的商业周期便是周期性的一个典型例子。周期性特征反映了时间序列中较长时间的波动规律。
周期性成分的建模难度较大,特别是在周期性不规则、变化频率不固定的情况下。通常会结合频谱分析、傅里叶变换等工具识别周期的存在和频率。
随机波动(Noise):
随机波动或“噪声”成分是指时间序列中无法解释的随机性部分,它是序列中没有规律性的变化。随机波动可能由外部不可预测的因素引起,例如市场突然的突发性事件、自然灾害等。
随机波动在时间序列建模中通常被看作是误差项。许多时间序列模型(如ARMA模型)都会假设随机波动成分是白噪声,即具有零均值、恒定方差、且自相关为零的随机变量。白噪声部分通常不含有预测性,但它的处理非常关键,准确处理噪声有助于提升模型的预测精度。
不同的时间序列特征会对模型选择产生直接影响。例如,如果时间序列中存在趋势和季节性成分,通常需要选择可以处理这些特征的模型,如Holt-Winters季节性模型、ARIMA模型等。为了能够有效进行预测,分析并提取时间序列的成分是必不可少的步骤。
去趋势和去季节性:在处理时间序列时,通常首先去除趋势和季节性,这样可以简化模型,并提高预测精度。去趋势方法包括差分、回归去趋势等,而去季节性可以通过季节性调整或季节性差分来实现。
残差分析:在去除趋势和季节性后,通常会对残差(也称为去趋势后的序列)进行分析,以确保残差接近Ping稳序列。模型的残差若呈现为白噪声,说明模型的拟合较好。
通过对时间序列的趋势、季节性、周期性、随机波动和偏移的深入分析和理解,可以为建立准确的预测模型提供可靠的基础,从而提高预测的效果和精度。
2.2 非Ping稳序列的转化
当时间序列被判定为非Ping稳时,需要通过一定的转化方法将其转化为Ping稳序列,以便能够应用如ARMA等模型进行分析。非Ping稳序列通常表现为均值、方差、或者自相关结构随时间变化,因此必须采取适当的措施消除这些趋势、季节性或不稳定因素。以下是一些常见的转化方法:
-
差分法:
差分是处理非Ping稳时间序列的常用方法之一。通过计算相邻观测值的差值,可以去除趋势成分,转化为Ping稳序列。例如,一阶差分公式如下:\[Y_t' = Y_t - Y_{t-1} \]若经过一阶差分处理后序列仍然非Ping稳,则可以继续进行二阶差分:
\[Y_t'' = Y_t' - Y_{t-1}' \]差分法对于处理具有趋势性增长或下降的序列非常有效。差分处理后的序列常被用于建立自回归模型(AR)或移动Ping均模型(MA)。
-
对数变换:
对数变换是另一种常见的处理方法,特别适用于具有指数增长特征的非Ping稳序列。通过取序列的对数,可以减小数据的波动性,使其更接近于Ping稳序列。例如,对于原序列 $ Y_t $,其对数变换为:\[Y_t' = \log(Y_t) \]这种变换能够有效处理较大范围的数值,降低波动幅度,并减少非Ping稳因素。
-
季节性差分:
对于具有季节性波动的序列,季节性差分可以帮助消除周期性影响。其形式与普通差分类似,但差分的滞后期取决于季节周期 $ s $,即:\[Y_t' = Y_t - Y_{t-s} \]季节性差分能够处理那些在不同季节表现出相似模式但总体趋势仍然非Ping稳的序列。
-
去趋势法:
如果时间序列存在明显的线性或非线性趋势,去趋势法可以用来将趋势部分剥离出来。常用方法是对序列进行线性回归分析,将时间作为解释变量,拟合趋势线,然后将原始数据减去拟合后的趋势成分,得到的残差序列通常可以被视为Ping稳序列。去趋势法在分析长期经济数据或其他具有显著趋势的序列中应用广泛。 -
Holt-Winters法:
Holt-Winters方法是一种针对非Ping稳时间序列的Ping滑方法,特别适用于处理具有趋势和季节性的时间序列。该方法通过加权Ping均的方式来Ping滑数据,并且结合了季节性调整和趋势Ping滑两部分。它有两种常用形式:加法模型和乘法模型。- 加法模型假设趋势和季节性对时间序列的影响是线性相加的,适用于序列波动较小且变化较Ping稳的情况。
- 乘法模型则适用于波动较大、随时间变化而扩大的序列,假设季节性和趋势是成比例关系的。乘法模型尤其在经济和财务数据分析中被广泛应用。
Holt-Winters模型的核心思想是通过递归地调整三项:Ping滑趋势、季节性和随机波动,逐步去除序列中的非Ping稳部分,使得序列接近Ping稳。它能够同时处理趋势和季节性非Ping稳的问题,特别适合具有明确季节性规律的时间序列。
-
Box-Cox变换:
Box-Cox变换是一种常用的时间序列变换方法,通过调整参数 $ \lambda $ 来对非Ping稳序列进行变换,使得序列方差更为稳定。其形式为:\[ Y_t' = \begin{cases} \frac{Y_t^\lambda - 1}{\lambda} & \text{若 } \lambda \neq 0 \\ \log(Y_t) & \text{若 } \lambda = 0 \end{cases} \]通过适当选择参数 $ \lambda $,可以大幅减少序列的波动性,并在一定程度上消除非Ping稳因素。Box-Cox变换对于处理方差随时间变化的序列特别有效。
例如,在金融数据中,经常出现非Ping稳的股价序列。通过对股价进行一阶差分,可以得到股价的变化率(收益率),这一序列通常更接近Ping稳,适合进一步的分析或建模。同样,经济数据如GDP也常表现为非Ping稳特征,通过对数变换或季节性调整可以将其转化为Ping稳序列。通过以上方法的合理运用,非Ping稳序列可以被有效转化为Ping稳序列,从而更好地进行建模与预测。
三、Holt-Winters 模型
Holt-Winters 模型是处理含有趋势和季节性时间序列的一种常用方法。根据季节性成分的不同,Holt-Winters 模型可分为 乘法模型 和 加法模型。这两种模型在结构上有所不同,具体选择取决于时间序列的特性。下面我们分别介绍这两种模型,并讨论它们的应用场景以及哪个模型更为常用。Holt-Winters 模型是在 Holt 线性趋势模型的基础上引入了季节性成分,用于对具有趋势和季节性成分的时间序列进行预测。Holt-Winters 模型的核心思想是通过三个Ping滑方程来分别估计序列的水Ping、趋势和季节性因素:水Ping(Level):反映时间序列的整体水Ping位置;趋势(Trend):反映时间序列的增长或下降趋势;季节性(Seasonality):反映时间序列中季节性周期的波动。根据季节性项的不同处理方式,Holt-Winters 模型分为加法模型和乘法模型。
3.1 Holt-Winters 加法模型
加法模型假定季节性成分的大小是固定的,与序列水Ping无关。即季节性成分的影响是相对不变的,序列的周期波动幅度在整个数据集的水Ping上没有明显的变化。加法模型的数学表达式为:
其中:
- $ y_t$:第 $ t$ 期的观测值。
- $ L_t$:第 $ t$ 期的水Ping成分。
- $ T_t$:第 $ t$ 期的趋势成分。
- $ S_t$:第 $ t$ 期的季节性成分。
- $ s$:季节周期的长度(如12个月或4个季度)。
- $ \epsilon_t$:误差项。
加法模型的三个更新方程为:
- 水Ping项更新:\[L_t = \alpha(y_t - S_{t-s}) + (1 - \alpha)(L_{t-1} + T_{t-1}) \]
- 趋势项更新:\[T_t = \beta(L_t - L_{t-1}) + (1 - \beta)T_{t-1} \]
- 季节项更新:\[S_t = \gamma(y_t - L_t) + (1 - \gamma)S_{t-s} \]
其中,\(\alpha\)、\(\beta\) 和 \(\gamma\) 分别是Ping滑参数,取值范围在0到1之间。
3.2 Holt-Winters 乘法模型
乘法模型假定季节性成分的大小与序列水Ping成正比。也就是说,季节性波动幅度会随序列水Ping的变化而变化,季节性影响在较高的水Ping下更加显著,而在较低的水Ping下较小。乘法模型的数学表达式为:
其中符号与加法模型相同,但季节性项 $ S_t$ 通过乘法方式影响观测值。
乘法模型的三个更新方程为:
- 水Ping项更新:\[L_t = \alpha \left( \frac{y_t}{S_{t-s}} \right) + (1 - \alpha)(L_{t-1} + T_{t-1}) \]
- 趋势项更新:\[T_t = \beta(L_t - L_{t-1}) + (1 - \beta)T_{t-1} \]
- 季节项更新:\[S_t = \gamma \left( \frac{y_t}{L_t} \right) + (1 - \gamma)S_{t-s} \]
在实践中,Holt-Winters 乘法模型通常比加法模型更为常用。
- 比例季节性更常见:在许多实际应用中,数据的季节性波动幅度往往会随着水Ping的变化而变化。例如,在零售、旅游、消费品等行业中,销售额较高时,季节性波动的绝对幅度也往往较大,这时乘法模型能够更好地捕捉这种变化。
- 适应广泛的数据特性:乘法模型能够处理既有趋势又有随水Ping变化的季节性波动的数据,而加法模型在面对这些情况时会显得不足。因此,乘法模型的适用范围更广。
- 非负值数据的自然适应:乘法模型适用于所有观测值为非负的数据(如销售量、收入等),因为乘法模型不会产生负的预测值,而加法模型可能在预测较低水Ping的数据时产生负值,特别是当季节性成分较大时。
- 零售业销售预测:在零售行业中,Holt-Winters 乘法模型经常被用来预测带有明显季节性特征的销售数据。例如,假期销售额通常会明显高于其他月份,而且销售水Ping越高,波动幅度越大,乘法模型能够更好地捕捉这种特性。
- 电力需求预测:电力需求通常具有强烈的季节性和趋势性,且随着整体需求的增加,季节性波动也会加剧。在这种情况下,乘法模型的比例变化特性使其成为分析电力需求波动的理想选择。
四、案例分析
在佛罗里达州迈尔斯堡附近的卡普蒂瓦岛上的Vintage饭店,由Karen Payne拥有并经营。饭店刚刚经营了3年。作为一家专门从事海鲜的高档餐饮企业,自从Karen的饭店开业以来,她一直在为Vintage树立声誉。经过Karen及其员工的努力,她的饭店已经成为岛上最好的且营业额增长最快的饭店之一。为了更好地规划饭店未来的发展,Karen需要建立一个系统以提前一年预测食品和饮料的每个月的销售额。
Month | Sales | Month | Sales | Month | Sales |
---|---|---|---|---|---|
1 | 242 | 13 | 263 | 25 | 282 |
2 | 235 | 14 | 238 | 26 | 255 |
3 | 232 | 15 | 247 | 27 | 265 |
4 | 178 | 16 | 193 | 28 | 205 |
5 | 184 | 17 | 193 | 29 | 210 |
6 | 140 | 18 | 149 | 30 | 160 |
7 | 145 | 19 | 157 | 31 | 166 |
8 | 152 | 20 | 161 | 32 | 174 |
9 | 110 | 21 | 122 | 33 | 126 |
10 | 130 | 22 | 130 | 34 | 148 |
11 | 152 | 23 | 167 | 35 | 173 |
12 | 206 | 24 | 230 | 36 | 235 |
4.1 数据整理与图示
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pandas import date_range
import matplotlib.dates as mdates
# 手动输入销售数据
sales_data = [
242, 235, 232, 178, 184, 140, 145, 152, 110, 130, 152, 206, # 2014
263, 238, 247, 193, 193, 149, 157, 161, 122, 130, 167, 230, # 2015
282, 255, 265, 205, 210, 160, 166, 174, 126, 148, 173, 235 # 2016
]
# 创建日期范围,从2014年1月到2016年12月,每月一个数据点
dates = date_range(start='2014-01', periods=len(sales_data), freq='M')
# 创建一个 pandas DataFrame
df = pd.DataFrame({'Date': dates, 'Sales': sales_data})
df.set_index('Date', inplace=True)
# 绘制时间序列图
plt.figure(figsize=(10, 6))
plt.plot(df.index, df['Sales'], marker='o', linestyle='-', color='b')
plt.title('Sales Time Series (2014-2016)')
plt.xlabel('Date')
plt.ylabel('Sales')
plt.xticks(rotation=45)
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m')) # 格式化日期显示
plt.grid(True)
plt.tight_layout()
# 显示图像
plt.show()
4.2 Holt-Winters成分分解
# 导入所需库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.tsa.holtwinters import ExponentialSmoothing
# 输入销售数据
sales_data = [
242, 235, 232, 178, 184, 140, 145, 152, 110, 130, 152, 206, # 2014
263, 238, 247, 193, 193, 149, 157, 161, 122, 130, 167, 230, # 2015
282, 255, 265, 205, 210, 160, 166, 174, 126, 148, 173, 235 # 2016
]
# 创建日期范围
dates = pd.date_range(start='2014-01', periods=len(sales_data), freq='M')
# 创建 DataFrame
df = pd.DataFrame({'Date': dates, 'Sales': sales_data})
df.set_index('Date', inplace=True)
# 使用 Holt-Winters 乘法模型进行分解
hw_model = ExponentialSmoothing(df['Sales'], seasonal='multiplicative', seasonal_periods=12, trend='add').fit()
# 拟合值
df['Fitted'] = hw_model.fittedvalues
# 提取趋势和季节性
df['Trend'] = hw_model.level
df['Seasonal'] = hw_model.season
# 计算残差 (原始数据减去趋势和季节性)
df['Residual'] = df['Sales'] / (df['Trend'] * df['Seasonal'])
# 绘制分解后的成分图
plt.figure(figsize=(10, 8))
# 绘制观察值 observed
plt.subplot(411)
plt.plot(df['Sales'], label='Observed', color='blue')
plt.title('Observed')
plt.ylabel('Sales')
# 绘制趋势 trend
plt.subplot(412)
plt.plot(df['Trend'], label='Trend', color='green')
plt.title('Trend')
plt.ylabel('Sales')
# 绘制季节性 seasonal
plt.subplot(413)
plt.plot(df['Seasonal'], label='Seasonal', color='red')
plt.title('Seasonal')
plt.ylabel('Seasonal Effect')
# 绘制残差 residual
plt.subplot(414)
plt.plot(df['Residual'], label='Residual', color='purple')
plt.title('Residual')
plt.ylabel('Residual Effect')
# 调整布局并展示
plt.tight_layout()
plt.show()
4.3 Holt-Winters预测
#加法模型
# 导入必要的库
import pandas as pd
import matplotlib.pyplot as plt
from pandas import date_range
from statsmodels.tsa.holtwinters import ExponentialSmoothing
# 手动输入销售数据
sales_data = [
242, 235, 232, 178, 184, 140, 145, 152, 110, 130, 152, 206, # 2014
263, 238, 247, 193, 193, 149, 157, 161, 122, 130, 167, 230, # 2015
282, 255, 265, 205, 210, 160, 166, 174, 126, 148, 173, 235 # 2016
]
# 创建日期范围,从2014年1月到2016年12月
dates = date_range(start='2014-01', periods=len(sales_data), freq='M')
# 创建一个 pandas DataFrame
df = pd.DataFrame({'Date': dates, 'Sales': sales_data})
df.set_index('Date', inplace=True)
# 应用 Holt-Winters 指数Ping滑模型 (包含趋势和季节性成分)
# seasonal_periods=12 表示数据是按年周期性的
model = ExponentialSmoothing(df['Sales'], trend='add', seasonal='add', seasonal_periods=12)
fit = model.fit()
# 进行预测:我们预测未来12个月的数据
forecast = fit.forecast(steps=12)
# 绘制原始数据和预测数据
plt.figure(figsize=(10, 6))
plt.plot(df.index, df['Sales'], marker='o', label='Original Sales', linestyle='-', color='b')
plt.plot(forecast.index, forecast, marker='o', label='Forecasted Sales', linestyle='--', color='r')
plt.title('Sales Time Series with Holt-Winters Forecast')
plt.xlabel('Date')
plt.ylabel('Sales')
plt.xticks(rotation=45)
plt.legend()
plt.grid(True)
plt.tight_layout()
# 显示图像
plt.show()
#乘法模型
# 导入必要的库
import pandas as pd
import matplotlib.pyplot as plt
from pandas import date_range
from statsmodels.tsa.holtwinters import ExponentialSmoothing
# 手动输入销售数据
sales_data = [
242, 235, 232, 178, 184, 140, 145, 152, 110, 130, 152, 206, # 2014
263, 238, 247, 193, 193, 149, 157, 161, 122, 130, 167, 230, # 2015
282, 255, 265, 205, 210, 160, 166, 174, 126, 148, 173, 235 # 2016
]
# 创建日期范围,从2014年1月到2016年12月
dates = date_range(start='2014-01', periods=len(sales_data), freq='M')
# 创建一个 pandas DataFrame
df = pd.DataFrame({'Date': dates, 'Sales': sales_data})
df.set_index('Date', inplace=True)
# 应用 Holt-Winters 乘法模型 (包含趋势和季节性成分)
# seasonal_periods=12 表示数据是按年周期性的
model = ExponentialSmoothing(df['Sales'], trend='add', seasonal='mul', seasonal_periods=12)
fit = model.fit()
# 进行预测:我们预测未来12个月的数据
forecast = fit.forecast(steps=12)
# 绘制原始数据和预测数据
plt.figure(figsize=(10, 6))
plt.plot(df.index, df['Sales'], marker='o', label='Original Sales', linestyle='-', color='b')
plt.plot(forecast.index, forecast, marker='o', label='Forecasted Sales', linestyle='--', color='r')
plt.title('Sales Time Series with Holt-Winters Multiplicative Model')
plt.xlabel('Date')
plt.ylabel('Sales')
plt.xticks(rotation=45)
plt.legend()
plt.grid(True)
plt.tight_layout()
# 显示图像
plt.show()
总结
Holt-Winters 乘法模型通常更为常用,特别是在具有比例季节性波动的场景中,其灵活性和广泛的适用性使其成为很多行业进行时间序列预测的首选。加法模型则适合于季节性波动幅度相对稳定的情形。选择哪种模型最终取决于数据的特性,在实际应用中应通过对数据的初步分析来判断季节性波动的性质,并选择适当的模型。