本文所总结的13种时间序列模型,涵盖了从传统的线性模型到现代的深度学习模型,每一种模型都有其独特的优势和适用场景。我们将从模型的原理、特点、应用场景以及Python实现等方面进行详细介绍,力求让读者对每一种模型都有一个全面而深入的了解。
我相信通过本文的学习,你将能够掌握Python中最经典的时间序列模型,并能够根据具体的数据特性和预测需求选择合适的模型进行应用。无论是初学者还是有一定经验的数据科学家,都能从本文中获得宝贵的启示和收获。
1、自回归模型(AR)
AR 自回归模型的核心思想是当前的观测值可以用其过去的观测值的线性组合来表示。具体来说,AR 模型假设时间序列的当前值与其前几个值(滞后值)之间存在线性关系。
如果想了解具体原理的,可以查看作者先前写的文章《时间序列预测模型之一文讲透 AR 模型》
下面是一个简单的自回归(AR)模型的例子,假设我们有一组时间序列数据,表示某个公司的月销售额。我们将使用 AR(1) 模型(即使用前一个月的销售额来预测当前月的销售额)来进行预测。
1. 数据准备
首先,我们需要一些模拟数据。这里我们生成一个简单的时间序列数据。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 设置随机种子以确保结果可重复
np.random.seed(42)
# 生成模拟数据:100个月的销售额
n = 100
time = np.arange(n)
# 模拟销售额:前一个月的销售额加上一个随机噪声
sales = 10 + 0.5 * np.arange(n) + np.random.normal(size=n)
# 创建 DataFrame
data = pd.DataFrame({'Month': time, 'Sales': sales})
# 绘制数据
plt.figure(figsize=(10, 5))
plt.plot(data['Month'], data['Sales'], marker='o')
plt.title('Monthly Sales Data')
plt.xlabel('Month')
plt.ylabel('Sales')
plt.grid()
plt.show()
2. 拟合 AR 模型
使用 statsmodels
库来拟合 AR 模型。
import statsmodels.api as sm
from statsmodels.tsa.ar_model import AutoReg
# 拟合 AR(1) 模型
model = AutoReg(data['Sales'], lags=1)
model_fit = model.fit()
# 输出模型参数
print("Model Parameters:")
print(model_fit.params)
# 进行预测
predictions = model_fit.predict(start=len(data), end=len(data)+5)
print("\nPredictions for next 5 months:")
print(predictions)
# -----输出结果------
# Model Parameters:
# const 0.613318
# Sales.L1 0.996491
# dtype: float64
# Predictions for next 5 months:
# 100 59.670762
# 101 60.074688
# 102 60.477197
# 103 60.878293
# 104 61.277982
# 105 61.676268
# dtype: float64
2、移动平均模型 (MA )
移动平均模型(Moving Average Model),通常简称为 MA 模型,是时间序列分析中的一种重要模型。它假设当前的观测值是过去若干个随机误差项的线性组合,一个 MA 模型通常表示为 MA(q),其中 q 是模型的阶数,表示模型中使用的随机误差项的数量。MA(q) 模型可以表示为
如果想了解具体原理的,可以查看作者先前写的文章《时间序列预测模型之一文讲透 MA 模型》
以下是一个简单的示例,演示如何使用 Python 中的 statsmodels
库构建和拟合 MA 模型。
1. 数据准备
我们将生成一些模拟数据,并添加随机噪声。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 设置随机种子以确保结果可重复
np.random.seed(42)
# 生成模拟时间序列数据
n = 100
time = np.arange(n)
# 真实信号
signal = np.sin(0.1 * time)
# 添加随机噪声
noise = np.random.normal(loc=0, scale=0.5, size=n)
data = signal + noise
# 创建 DataFrame
df = pd.DataFrame({'Time': time, 'Value': data})
# 绘制数据
plt.figure(figsize=(10, 5))
plt.plot(df['Time'], df['Value'], label='Observed Data', color='blue')
plt.title('Simulated Time Series Data with Noise')
plt.xlabel('Time')
plt.ylabel('Value')
plt.legend()
plt.grid()
plt.show()
2. 拟合 MA 模型
使用 statsmodels
中的 ARIMA
类来拟合 MA 模型。
import statsmodels.api as sm
# 拟合 MA(1) 模型
model = sm.tsa.ARIMA(df['Value'], order=(0, 0, 1)) # MA(1) 模型
model_fit = model.fit()
# 输出模型参数
print("Model Parameters:")
print(model_fit.params)
# 进行预测
predictions = model_fit.predict(start=len(df), end=len(df)+5, typ='levels')
print("\nPredictions for next 5 time points:")
print(predictions)
# ------输出------
# Model Parameters:
# const 0.132711
# ma.L1 0.469680
# sigma2 0.462671
# dtype: float64
# Predictions for next 5 time points:
# 100 -0.128440
# 101 0.132711
# 102 0.132711
# 103 0.132711
# 104 0.132711
# 105 0.132711
# Name: predicted_mean, dtype: float64
3、自回归移动平均模型 (ARMA)
ARMA(Autoregressive Moving Average)模型是由两个部分组成的:
- 自回归(AR)部分:表示当前值与其过去值的线性关系。
- 移动平均(MA)部分:表示当前值与过去误差项的线性关系。
以下是一个简单的示例,演示如何使用 Python 中的 statsmodels
库构建和拟合 ARMA 模型。
1. 数据准备
我们将生成一些模拟的平稳时间序列数据。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 设置随机种子以确保结果可重复
np.random.seed(42)
# 生成模拟时间序列数据
n = 100
time = np.arange(n)
# 真实信号
signal = np.sin(0.1 * time) + np.random.normal(0, 0.1, n) # 添加一些噪声
df = pd.DataFrame({'Time': time, 'Value': signal})
# 绘制数据
plt.figure(figsize=(10, 5))
plt.plot(df['Time'], df['Value'], label='Simulated Time Series Data', color='blue')
plt.title('Simulated Time Series Data')
plt.xlabel('Time')
plt.ylabel('Value')
plt.legend()
plt.grid()
plt.show()
2. 拟合 ARMA 模型
使用 statsmodels
中的 ARIMA
类来拟合 ARMA 模型。
import statsmodels.api as sm
# 拟合 ARMA(2, 2) 模型
model = sm.tsa.ARIMA(df['Value'], order=(2, 0, 2)) # ARMA(2, 2) 模型
model_fit = model.fit()
# 输出模型参数
print("Model Parameters:")
print(model_fit.params)
# 进行预测
predictions = model_fit.predict(start=len(df), end=len(df)+5, typ='levels')
print("\nPredictions for next 5 time points:")
print(predictions)
# ------ 输出 ------
# Model Parameters:
# const -0.008708
# ar.L1 1.989793
# ar.L2 -0.999812
# ma.L1 -1.964215
# ma.L2 0.982360
# sigma2 0.009292
# dtype: float64
# Predictions for next 5 time points:
# 100 -0.559253
# 101 -0.640524
# 102 -0.715450
# 103 -0.783282
# 104 -0.843341
# 105 -0.895028
# Name: predicted_mean, dtype: float64
4、自回归综合移动平均模型 (ARIMA)
ARIMA模型通过结合自回归(AR)、差分(I)和移动平均(MA)三种成分,能够处理数据的趋势和季节性变化。
- 自回归(AR):当前值与其过去值的线性关系。
- 差分(I):通过对数据进行差分处理,使其平稳化。差分的目的是消除序列中的趋势成分,使得序列的均值和方差在时间上保持不变。
- 移动平均(MA):当前值与过去误差项的线性关系。
以下是一个简单的示例,演示如何使用 Python 中的 statsmodels
库构建和拟合 ARIMA 模型。
1. 数据准备
我们将生成一些模拟的非平稳时间序列数据,并对其进行差分处理。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 设置随机种子以确保结果可重复
np.random.seed(42)
# 生成模拟时间序列数据(带有趋势)
n = 100
time = np.arange(n)
trend = 0.5 * time # 线性趋势
noise = np.random.normal(0, 1, n) # 随机噪声
data = trend + noise
# 创建 DataFrame
df = pd.DataFrame({'Time': time, 'Value': data})
# 绘制数据
plt.figure(figsize=(10, 5))
plt.plot(df['Time'], df['Value'], label='Simulated Non-Stationary Data', color='blue')
plt.title('Simulated Non-Stationary Time Series Data')
plt.xlabel('Time')
plt.ylabel('Value')
plt.legend()
plt.grid()
plt.show()
2. 差分处理
对数据进行差分以使其平稳。
# 一阶差分
df['Differenced'] = df['Value'].diff().dropna()
# 绘制差分后的数据
plt.figure(figsize=(10, 5))
plt.plot(df['Differenced'].dropna(), label='Differenced Data', color='orange')
plt.title('Differenced Time Series Data')
plt.xlabel('Time')
plt.ylabel('Differenced Value')
plt.legend()
plt.grid()
plt.show()
3. 拟合 ARIMA 模型
使用 statsmodels
中的 ARIMA
类来拟合 ARIMA 模型
import statsmodels.api as sm
# 拟合 ARIMA(1, 1, 1) 模型
model = sm.tsa.ARIMA(df['Value'], order=(1, 1, 1)) # ARIMA(p=1, d=1, q=1)
model_fit = model.fit()
# 输出模型参数
print("Model Parameters:")
print(model_fit.params)
# 进行预测
predictions = model_fit.predict(start=len(df), end=len(df)+5, typ='levels')
print("\nPredictions for next 5 time points:")
print(predictions)
# ------ 输出 ------
# Model Parameters:
# ar.L1 -0.321151
# ma.L1 0.025787
# sigma2 1.749838
# dtype: float64
# Predictions for next 5 time points:
# 100 49.190309
# 101 49.214429
# 102 49.206683
# 103 49.209170
# 104 49.208371
# 105 49.208628
# Name: predicted_mean, dtype: float64
5、季节性自回归整合移动平均模型 (SARIMA)
季节性自回归整合移动平均线(Seasonal Autoregressive Integrated Moving-Average,SARIMA)模型是对ARIMA模型的扩展,专门用于处理具有季节性成分的时间序列数据。SARIMA模型能够捕捉数据中的季节性模式,同时也考虑了趋势和非平稳性。
SARIMA 模型的组成部分
- 季节性自回归(SAR):反映当前值与前一个季节的值之间的关系。例如,在月度数据中,当前值可能与一年前的同月值有关。
- 季节性差分(SI):通过对数据进行季节性差分,使得季节性成分平稳化。
- 季节性移动平均(SMA):当前值与前一个季节的误差项之间的关系。
以下是一个简单的示例,演示如何使用 Python 中的 statsmodels
库构建和拟合 SARIMA 模型。
1. 数据准备
我们将生成一些带有季节性成分的模拟时间序列数据。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 设置随机种子以确保结果可重复
np.random.seed(42)
# 生成模拟时间序列数据(带有季节性和趋势)
n = 120 # 10年,每年12个月
time = np.arange(n)
seasonal_pattern = 10 * np.sin(2 * np.pi * time / 12) # 每年季节性波动
trend = 0.5 * time # 线性趋势
noise = np.random.normal(0, 1, n) # 随机噪声
data = trend + seasonal_pattern + noise
# 创建 DataFrame
df = pd.DataFrame({'Time': time, 'Value': data})
# 绘制数据
plt.figure(figsize=(10, 5))
plt.plot(df['Time'], df['Value'], label='Simulated Seasonal Data', color='blue')
plt.title('Simulated Seasonal Time Series Data')
plt.xlabel('Time')
plt.ylabel('Value')
plt.legend()
plt.grid()
plt.show()
2. 拟合 SARIMA 模型
使用 statsmodels
中的 SARIMAX
类来拟合 SARIMA 模型。
import statsmodels.api as sm
# 拟合 SARIMA(1, 1, 1)(1, 1, 1, 12) 模型
model = sm.tsa.SARIMAX(df['Value'], order=(1, 1, 1), seasonal_order=(1, 1, 1, 12))
model_fit = model.fit()
# 输出模型参数
print("Model Parameters:")
print(model_fit.params)
# 进行预测
predictions = model_fit.predict(start=len(df), end=len(df)+4, typ='levels')
print("\nPredictions for next 12 time points:")
print(predictions)
# 绘制预测结果
plt.figure(figsize=(10, 5))
plt.plot(df['Value'], label='Observed', color='blue')
plt.plot(np.arange(len(df), len(df)+5), predictions, label='Predicted', color='orange')
plt.title('SARIMA Model Predictions')
plt.xlabel('Time')
plt.ylabel('Value')
plt.legend()
plt.grid()
plt.show()
# ----- 输出 -----
# Model Parameters:
# ar.L1 0.001595
# ma.L1 -0.998672
# ar.S.L12 -0.109138
# ma.S.L12 -0.998515
# sigma2 0.790939
# dtype: float64
# Predictions for next 12 time points:
# 120 60.099715
# 121 65.127670
# 122 69.121142
# 123 71.718992
# 124 70.479604
# Name: predicted_mean, dtype: float64
6、具有外生回归量的季节性自回归整合移动平均模型 (SARIMAX)
具有外生回归量的季节性自回归整合移动平均线(SARIMAX,Seasonal Autoregressive Integrated Moving Average with eXogenous variables)模型是SARIMA模型的扩展,除了处理季节性时间序列数据外,还能够纳入外生变量(即模型外部的影响因素)进行建模。这使得SARIMAX模型在时间序列分析中更具灵活性和适用性,尤其是在需要考虑其他变量对目标变量影响的情况下。
SARIMAX 模型的组成部分:
- 季节性自回归(SAR):捕捉当前值与前一个季节的值之间的关系。
- 季节性差分(SI):通过对数据进行季节性差分,使得季节性成分平稳化。
- 季节性移动平均(SMA):当前值与前一个季节的误差项之间的关系。
- 外生变量(X):这些是模型外部的变量,可能会影响目标变量。例如,经济指标、气候数据、市场活动等
以下是一个简单的示例,演示如何使用 Python 中的 statsmodels
库构建和拟合 SARIMAX 模型。
1. 数据准备
我们将生成一些带有季节性成分的模拟时间序列数据,并添加一个外生变量。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 设置随机种子以确保结果可重复
np.random.seed(42)
# 生成模拟时间序列数据(带有季节性和趋势)
n = 120 # 10年,每年12个月
time = np.arange(n)
seasonal_pattern = 10 * np.sin(2 * np.pi * time / 12) # 每年季节性波动
trend = 0.5 * time # 线性趋势
noise = np.random.normal(0, 1, n) # 随机噪声
data = trend + seasonal_pattern + noise
# 生成外生变量(例如,广告支出)
advertising = np.random.normal(5, 2, n)
# 创建 DataFrame
df = pd.DataFrame({'Time': time, 'Value': data, 'Advertising': advertising})
# 绘制数据
plt.figure(figsize=(10, 5))
plt.plot(df['Time'], df['Value'], label='Simulated Seasonal Data', color='blue')
plt.title('Simulated Seasonal Time Series Data with Advertising')
plt.xlabel('Time')
plt.ylabel('Value')
plt.legend()
plt.grid()
plt.show()
2. 拟合 SARIMAX 模型
使用 statsmodels
中的 SARIMAX
类来拟合 SARIMAX 模型。
import statsmodels.api as sm
# 拟合 SARIMAX(1, 1, 1)(1, 1, 1, 12) 模型,包含外生变量
model = sm.tsa.SARIMAX(df['Value'], order=(1, 1, 1), seasonal_order=(1, 1, 1, 12), exog=df['Advertising'])
model_fit = model.fit()
# 输出模型参数
print("Model Parameters:")
print(model_fit.params)
# 进行预测
# 创建未来的外生变量数据(假设未来12个月的广告支出)
future_advertising = np.random.normal(5, 2, 12)
predictions = model_fit.predict(start=len(df), end=len(df)+11, typ='levels', exog=future_advertising)
print("\nPredictions for next 12 time points:")
print(predictions)
# 绘制预测结果
plt.figure(figsize=(10, 5))
plt.plot(df['Value'], label='Observed', color='blue')
plt.plot(np.arange(len(df), len(df)+12), predictions, label='Predicted', color='orange')
plt.title('SARIMAX Model Predictions with Exogenous Variable')
plt.xlabel('Time')
plt.ylabel('Value')
plt.legend()
plt.grid()
plt.show()
# ----- 输出 -----
# Model Parameters:
# Advertising 0.021497
# ar.L1 -0.001191
# ma.L1 -0.999133
# ar.S.L12 -0.101902
# ma.S.L12 -0.999523
# sigma2 0.789218
# dtype: float64
# Predictions for next 12 time points:
# 120 60.083821
# 121 65.088265
# 122 69.197781
# 123 71.652283
# 124 70.454709
# 125 67.805953
# 126 63.247812
# 127 58.693075
# 128 55.294218
# 129 54.387721
# 130 56.851915
# 131 60.478982
# Name: predicted_mean, dtype: float64
7、向量自回归 (VAR)
向量自回归(Vector Autoregression, VAR)是一种多元时间序列模型,用于捕捉多个时间序列变量之间的动态关系。与单变量自回归模型(AR模型)不同,VAR模型能够同时考虑多个变量的相互影响,适用于分析和预测多个相关时间序列数据。
以下是一个简单的示例,演示如何使用Python中的statsmodels
库构建和拟合VAR模型。
1. 数据准备
我们将生成一些模拟的多元时间序列数据。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 设置随机种子以确保结果可重复
np.random.seed(42)
# 生成模拟时间序列数据
n = 100 # 时间点数量
time = np.arange(n)
# 生成两个相关的时间序列
Y1 = np.cumsum(np.random.normal(0, 1, n)) # 随机游走
Y2 = 0.5 * Y1 + np.random.normal(0, 1, n) # Y2受Y1影响
# 创建 DataFrame
df = pd.DataFrame({'Time': time, 'Y1': Y1, 'Y2': Y2}).set_index('Time')
# 绘制数据
plt.figure(figsize=(10, 5))
plt.plot(df['Y1'], label='Y1', color='blue')
plt.plot(df['Y2'], label='Y2', color='orange')
plt.title('Simulated Time Series Data')
plt.xlabel('Time')
plt.ylabel('Values')
plt.legend()
plt.grid()
plt.show()
2. 拟合VAR模型
使用statsmodels
中的VAR
类来拟合VAR模型。
from statsmodels.tsa.api import VAR
# 拟合VAR模型
model = VAR(df)
results = model.fit(maxlags=5, ic='aic')
# 输出模型摘要
print(results.summary())
# 进行预测
forecast = results.forecast(df.values[-results.k_ar:], steps=3)
forecast_df = pd.DataFrame(forecast, index=np.arange(len(df), len(df)+3), columns=['Y1_forecast', 'Y2_forecast'])
# 绘制预测结果
plt.figure(figsize=(10, 5))
plt.plot(df['Y1'], label='Y1', color='blue')
plt.plot(df['Y2'], label='Y2', color='orange')
plt.plot(forecast_df['Y1_forecast'], label='Y1 Forecast', color='green', linestyle='--')
plt.plot(forecast_df['Y2_forecast'], label='Y2 Forecast', color='red', linestyle='--')
plt.title('VAR Model Forecasts')
plt.xlabel('Time')
plt.ylabel('Values')
plt.legend()
plt.grid()
plt.show()
8、向量自回归移动平均 (VARMA)
向量自回归移动平均(Vector Autoregressive Moving Average, VARMA)模型是向量自回归(VAR)模型和向量移动平均(VMA)模型的结合,旨在分析多个时间序列变量之间的动态关系。VARMA模型适用于平稳时间序列数据,能够同时捕捉自回归和移动平均的特性。
以下是一个简单的示例,演示如何使用Python中的statsmodels
库构建和拟合VARMA模型。
1. 数据准备
我们将生成一些模拟的多元时间序列数据。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 设置随机种子以确保结果可重复
np.random.seed(42)
# 生成模拟时间序列数据
n = 100 # 时间点数量
time = np.arange(n)
# 生成两个相关的时间序列
Y1 = np.cumsum(np.random.normal(0, 1, n)) # 随机游走
Y2 = 0.5 * Y1 + np.random.normal(0, 1, n) # Y2受Y1影响
# 创建 DataFrame
df = pd.DataFrame({'Time': time, 'Y1': Y1, 'Y2': Y2}).set_index('Time')
# 绘制数据
plt.figure(figsize=(10, 5))
plt.plot(df['Y1'], label='Y1', color='blue')
plt.plot(df['Y2'], label='Y2', color='orange')
plt.title('Simulated Time Series Data')
plt.xlabel('Time')
plt.ylabel('Values')
plt.legend()
plt.grid()
plt.show()
2. 拟合VARMA模型
使用statsmodels
中的VARMAX
类来拟合VARMA模型(VARMA
是VARMAX
的一种特殊情况)。
from statsmodels.tsa.statespace.varmax import VARMAX
# 拟合VARMA(1, 1)模型
model = VARMAX(df, order=(1, 1))
results = model.fit()
# 输出模型摘要
print(results.summary())
# 进行预测
forecast = results.forecast(steps=10)
forecast_df = pd.DataFrame(forecast, index=np.arange(len(df), len(df)+10), columns=['Y1_forecast', 'Y2_forecast'])
# 绘制预测结果
plt.figure(figsize=(10, 5))
plt.plot(df['Y1'], label='Y1', color='blue')
plt.plot(df['Y2'], label='Y2', color='orange')
plt.plot(forecast_df['Y1_forecast'], label='Y1 Forecast', color='green', linestyle='--')
plt.plot(forecast_df['Y2_forecast'], label='Y2 Forecast', color='red', linestyle='--')
plt.title('VARMA Model Forecasts')
plt.xlabel('Time')
plt.ylabel('Values')
plt.legend()
plt.grid()
plt.show()
9、具有外源回归量的向量自回归移动平均值 (VARMAX)
具有外源回归量的向量自回归移动平均模型(Vector Autoregressive Moving Average with eXogenous inputs, VARMAX)是VARMA模型的扩展,允许将外部变量(外源回归量)纳入模型中,以分析和预测多个时间序列变量之间的关系。VARMAX模型结合了自回归、移动平均和外源变量的特性,适用于多元时间序列分析。
以下是一个简单的示例,演示如何使用Python中的statsmodels
库构建和拟合VARMAX模型。
1. 数据准备
我们将生成一些模拟的多元时间序列数据,并添加一个外部变量。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 设置随机种子以确保结果可重复
np.random.seed(42)
# 生成模拟时间序列数据
n = 100 # 时间点数量
time = np.arange(n)
# 生成两个相关的时间序列
Y1 = np.cumsum(np.random.normal(0, 1, n)) # 随机游走
Y2 = 0.5 * Y1 + np.random.normal(0, 1, n) # Y2受Y1影响
# 生成一个外源回归变量
X = np.random.normal(0, 1, n) # 外部变量
# 创建 DataFrame
df = pd.DataFrame({'Time': time, 'Y1': Y1, 'Y2': Y2, 'X': X}).set_index('Time')
# 绘制数据
plt.figure(figsize=(10, 5))
plt.plot(df['Y1'], label='Y1', color='blue')
plt.plot(df['Y2'], label='Y2', color='orange')
plt.plot(df['X'], label='X (Exogenous)', color='green', linestyle='--')
plt.title('Simulated Time Series Data with Exogenous Variable')
plt.xlabel('Time')
plt.ylabel('Values')
plt.legend()
plt.grid()
plt.show()
2. 拟合VARMAX模型
使用statsmodels
中的VARMAX
类来拟合VARMAX模型。
from statsmodels.tsa.statespace.varmax import VARMAX
# 拟合VARMAX(1, 1)模型,外源变量X
model = VARMAX(df[['Y1', 'Y2']], exog=df[['X']], order=(1, 1))
results = model.fit()
# 输出模型摘要
print(results.summary())
# 进行预测
forecast_steps = 10
exog_forecast = np.random.normal(0, 1, forecast_steps) # 未来外源变量的预测值
forecast = results.forecast(steps=forecast_steps, exog=exog_forecast)
forecast_df = pd.DataFrame(forecast, index=np.arange(len(df), len(df)+forecast_steps), columns=['Y1_forecast', 'Y2_forecast'])
print(forecast_df)
# 绘制预测结果
plt.figure(figsize=(10, 5))
plt.plot(df['Y1'], label='Y1', color='blue')
plt.plot(df['Y2'], label='Y2', color='orange')
plt.plot(forecast_df['Y1_forecast'], label='Y1 Forecast', color='green', linestyle='--')
plt.plot(forecast_df['Y2_forecast'], label='Y2 Forecast', color='red', linestyle='--')
plt.title('VARMAX Model Forecasts with Exogenous Variable')
plt.xlabel('Time')
plt.ylabel('Values')
plt.legend()
plt.grid()
plt.show()
10、简单指数平滑 (SES)
简单指数平滑(Simple Exponential Smoothing, SES)是一种用于时间序列预测的基本方法,特别适用于没有明显趋势或季节性模式的数据。SES通过对过去观察值的加权平均来生成未来的预测,权重随着时间的推移而指数衰减,这意味着最近的数据点对预测的影响更大。
SES使用一个平滑参数(通常用α表示,取值范围在0到1之间)来控制对过去数据的加权。公式如下:
以下是使用Python中的statsmodels
库实现简单指数平滑的示例代码:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.holtwinters import SimpleExpSmoothing
# 生成模拟时间序列数据
np.random.seed(42)
data = np.random.normal(10, 1, 100) # 生成随机数据
data = pd.Series(data).cumsum() # 累加生成平稳的时间序列
# 拟合简单指数平滑模型
model = SimpleExpSmoothing(data)
fit = model.fit(smoothing_level=0.2, optimized=False) # 设置平滑参数α
# 进行预测
forecast = fit.forecast(10) # 预测未来10个时间点
# 绘制结果
plt.figure(figsize=(10, 5))
plt.plot(data, label='Observed', color='blue')
plt.plot(fit.fittedvalues, label='Fitted', color='orange')
plt.plot(forecast, label='Forecast', color='green', linestyle='--')
plt.title('Simple Exponential Smoothing')
plt.xlabel('Time')
plt.ylabel('Values')
plt.legend()
plt.grid()
plt.show()
11、霍尔特·温特的指数平滑 (HWES)
霍尔特·温特斯指数平滑(Holt-Winters Exponential Smoothing, HWES)是一种扩展的指数平滑方法,适用于具有趋势和季节性的时间序列数据。HWES模型通过引入趋势和季节性成分,能够更好地捕捉时间序列中的变化模式,从而提高预测的准确性。
HWES模型包含三个主要成分:
- 水平(Level):当前时间点的基本值。
- 趋势(Trend):时间序列的长期变化方向,即数据的上升或下降趋势。
- 季节性(Seasonality):时间序列中定期出现的波动模式,通常与季节或周期相关。
以下是使用Python中的statsmodels
库实现霍尔特·温特斯指数平滑的示例代码:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.holtwinters import ExponentialSmoothing
# 生成模拟时间序列数据(具有趋势和季节性)
np.random.seed(42)
n = 120
time = np.arange(n)
seasonal_pattern = 10 * np.sin(2 * np.pi * time / 12) # 每12个时间点的季节性波动
trend = time * 0.5 # 线性趋势
data = trend + seasonal_pattern + np.random.normal(0, 2, n) # 加上随机噪声
# 创建 DataFrame
df = pd.DataFrame({'Time': time, 'Value': data}).set_index('Time')
# 拟合霍尔特·温特斯模型
model = ExponentialSmoothing(df['Value'], trend='add', seasonal='add', seasonal_periods=12)
fit = model.fit()
# 进行预测
forecast = fit.forecast(steps=12) # 预测未来12个时间点
# 绘制结果
plt.figure(figsize=(10, 5))
plt.plot(df['Value'], label='Observed', color='blue')
plt.plot(fit.fittedvalues, label='Fitted', color='orange')
plt.plot(forecast, label='Forecast', color='green', linestyle='--')
plt.title('Holt-Winters Exponential Smoothing')
plt.xlabel('Time')
plt.ylabel('Values')
plt.legend()
plt.grid()
plt.show()
12、指数平滑状态空间模型(ETS)
ETS模型(Exponential Smoothing State Space Model)是一种用于时间序列预测的强大工具,基于指数平滑法的思想。ETS模型通过对时间序列的趋势、季节性和误差成分进行建模,能够有效捕捉数据的动态变化,广泛应用于经济、金融、库存管理等领域。
ETS模型的名称中的每个字母代表了模型的不同成分:
- E (Error): 误差成分,表示模型预测值与实际值之间的偏差。可以是加性(A)或乘性(M)。
- T (Trend): 趋势成分,表示时间序列的长期上升或下降趋势。可以是无趋势(N)、加性趋势(A)或乘性趋势(M)。
- S (Seasonal): 季节性成分,表示时间序列中周期性波动的模式。可以是无季节性(N)、加性季节性(A)或乘性季节性(M)。
在Python中,可以使用statsmodels
库中的ExponentialSmoothing
类来构建和拟合ETS模型。以下是一个简单的示例:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.holtwinters import ExponentialSmoothing
# 生成示例数据
np.random.seed(0)
n = 100
time = np.arange(n)
data = pd.Series(10 + 0.5 * time + 10 * np.sin(time / 5) + np.random.normal(size=n)
# 拟合ETS模型
model = ExponentialSmoothing(data, trend='add', seasonal='add', seasonal_periods=12)
model_fit = model.fit()
# 进行预测
forecast = model_fit.forecast(steps=10)
# 绘制结果
plt.figure(figsize=(10, 6))
plt.plot(data, label='Actual Data', color='blue')
plt.plot(model_fit.fittedvalues, label='Fitted Values', color='orange')
plt.plot(forecast, label='Forecast', color='red')
plt.title('ETS Model Forecast')
plt.legend()
plt.show()
13、季节性趋势分解模型(STL)
STLForecast 是一种基于 STL(Seasonal-Trend decomposition using LOESS)分解的时间序列预测方法。STL 分解是一种强大的工具,用于将时间序列分解为趋势、季节性和残差(噪声)成分。STLForecast 利用这种分解来进行更准确的预测,特别是在具有明显季节性和趋势的时间序列数据中。
STL分解的基本组成
- 趋势成分 (Trend): 表示数据的长期变化方向,可以是上升、下降或平稳。
- 季节性成分 (Seasonality): 表示数据中存在的周期性波动,通常与特定的时间周期(如月份、季度等)相关。
- 残差成分 (Residuals): 表示去除趋势和季节性后剩余的部分,通常被视为随机噪声。
在 Python 中,可以使用 statsmodels
库中的 STL
类来进行 STL 分解,并结合其他建模方法进行预测。以下是一个简单的示例:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.tsa.seasonal import STL
# 生成示例时间序列数据
np.random.seed(0)
date_rng = pd.date_range(start='1/1/2020', end='1/31/2020', freq='D')
data = pd.Series(10 + 5 * np.sin(2 * np.pi * date_rng.dayofyear / 365) + np.random.normal(size=len(date_rng)), index=date_rng)
# STL 分解
stl = STL(data, seasonal=7) # 假设季节性周期为7天(对于实际数据,这个值应该根据具体情况调整)
result = stl.fit()
# 绘制 STL 分解结果
result.plot()
plt.show()
# 假设我们要预测接下来的7天
forecast_steps = 7
# 对分解后的趋势成分进行简单的线性预测
trend_data = result.trend
trend_forecast = np.linspace(trend_data.iloc[-1], trend_data.iloc[-1] + (trend_data.iloc[-1] - trend_data.iloc[-2]), forecast_steps)
# 季节性成分通常具有周期性,因此我们可以简单地重复最后一个季节性周期
seasonal_data = result.seasonal
seasonal_forecast = seasonal_data.iloc[-7:].values.reshape(-1, 1).repeat(forecast_steps, axis=0).flatten()[:forecast_steps]
# 残差成分通常被认为是随机的,因此我们可以简单地假设它们为零
# 在这里,我们假设残差为零
resid_forecast = np.zeros(forecast_steps)
# 合并预测结果
forecast_data = trend_forecast + seasonal_forecast + resid_forecast
# 准备预测结果的日期索引
forecast_index = pd.date_range(start=data.index[-1], periods=forecast_steps + 1, freq=data.index.freq)[1:]
# 绘制实际数据和预测数据
plt.figure(figsize=(10, 6))
plt.plot(data, label='Actual')
plt.plot(forecast_index, forecast_data, label='Forecast', linestyle='--')
plt.legend()
plt.show()
如果你喜欢本文,欢迎点赞,并且关注我们的微信公众号:Python技术极客,我们会持续更新分享 Python 开发编程、数据分析、数据挖掘、AI 人工智能、网络爬虫等技术文章!让大家在Python 技术领域持续精进提升,成为更好的自己!
添加作者微信(coder_0101),拉你进入行业技术交流群,进行技术交流