哈喽,我是小白~
今儿咱们一起来看看时间序列分析算法。
时间序列分析方法很重要,主要由于:
- 趋势识别:帮助我们识别数据中的长期趋势和季节性变化,为预测未来趋势提供依据。
- 异常检测:能够检测数据中的异常值和异常模式,及时发现潜在问题。
- 决策支持:为政策制定和战略规划提供数据驱动的洞察,帮助优化决策过程。
所以,基于它的重要性,我们一起来看今天分享的有:
一起来看看~
1. 自回归 (AR, Autoregressive Model)
自回归模型假设当前值 是过去若干时刻值的线性组合。
原理
模型利用前 p 个时间点的数据预测当前时间点的数据。
核心公式
其中:
自回归模型的推导可以通过对时间序列数据进行线性回归得到,即:
使用最小二乘法求解系数 。
核心案例
案例中,使用了股票价格数据,展示如何拟合AR模型并进行预测,并生成两个以上的数据分析图形。
使用一个股票价格的时间序列数据,首先对数据进行预处理,然后拟合一个自回归模型,最后生成几个图形,包括时间序列图、ACF图、PACF图和预测图。
使用 yfinance
库来获取股票价格数据。
import yfinance as yf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.tsa.ar_model import AutoReg
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
# 下载数据
ticker = 'AAPL' # 以苹果公司股票为例
start_date = '2020-01-01'
end_date = '2023-01-01'
data = yf.download(ticker, start=start_date, end=end_date)
close_prices = data['Close']
# 绘制时间序列图
plt.figure(figsize=(14, 7))
plt.plot(close_prices, label='Close Price')
plt.title('Apple Stock Close Prices')
plt.xlabel('Date')
plt.ylabel('Close Price')
plt.legend()
plt.show()
# ACF和PACF图
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 10))
plot_acf(close_prices, ax=ax1, lags=50)
plot_pacf(close_prices, ax=ax2, lags=50)
plt.show()
# 拟合自回归模型
lags = 30
model = AutoReg(close_prices, lags=lags)
model_fit = model.fit()
# 模型预测
pred_start = len(close_prices)
pred_end = pred_start 50
predictions = model_fit.predict(start=pred_start, end=pred_end)
# 绘制预测结果
plt.figure(figsize=(14, 7))
plt.plot(close_prices, label='Observed')
plt.plot(predictions, label='Forecast', linestyle='--')
plt.title('Apple Stock Close Price Forecast')
plt.xlabel('Date')
plt.ylabel('Close Price')
plt.legend()
plt.show()
- ACF和PACF图:用于检查时间序列的自相关性和部分自相关性,帮助确定AR模型的阶数。
- 预测图:展示了拟合AR模型后的未来50天的股票价格预测。

2. 移动平均 (MA, Moving Average Model)
移动平均模型假设当前值 是过去若干时刻误差的线性组合。
原理
模型利用前 q 个时间点的误差预测当前时间点的数据。
核心公式
其中:
通过假设误差项 是独立同分布的白噪声,可以用最小二乘法或极大似然估计法求解系数 。
核心案例
假设我们有一个月度的销售数据,该数据包含一些季节性和随机波动。我们将使用移动平均模型来平滑数据,并比较平滑后的数据与原始数据。此外,我们还将计算并绘制残差。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
# 生成模拟的时间序列数据
np.random.seed(42)
n_periods = 120
date_range = pd.date_range(start='2010-01', periods=n_periods, freq='M')
seasonal_pattern = np.sin(2 * np.pi * date_range.month / 12)
random_noise = np.random.normal(scale=0.5, size=n_periods)
sales = 10 seasonal_pattern random_noise
# 创建数据框
data = pd.DataFrame({'Date': date_range, 'Sales': sales})
data.set_index('Date', inplace=True)
# 绘制原始数据
plt.figure(figsize=(14, 6))
plt.plot(data.index, data['Sales'], label='Original Sales Data')
plt.title('Monthly Sales Data')
plt.xlabel('Date')
plt.ylabel('Sales')
plt.legend()
plt.show()
# 使用移动平均模型进行平滑
window_size = 12
data['Sales_MA'] = data['Sales'].rolling(window=window_size).mean()
# 绘制平滑后的数据
plt.figure(figsize=(14, 6))
plt.plot(data.index, data['Sales'], label='Original Sales Data')
plt.plot(data.index, data['Sales_MA'], label=f'{window_size}-month Moving Average', color='red')
plt.title('Monthly Sales Data with Moving Average')
plt.xlabel('Date')
plt.ylabel('Sales')
plt.legend()
plt.show()
# 计算残差
data['Residual'] = data['Sales'] - data['Sales_MA']
# 绘制残差
plt.figure(figsize=(14, 6))
plt.plot(data.index, data['Residual'], label='Residuals', color='green')
plt.title('Residuals from Moving Average Model')
plt.xlabel('Date')
plt.ylabel('Residual')
plt.legend()
plt.show()
# 绘制自相关图和偏自相关图
fig, axes = plt.subplots(1, 2, figsize=(16, 6))
plot_acf(data['Residual'].dropna(), ax=axes[0], lags=40)
plot_pacf(data['Residual'].dropna(), ax=axes[1], lags=40)
axes[0].set_title('ACF of Residuals')
axes[1].set_title('PACF of Residuals')
plt.show()
- 生成时间序列数据:使用正弦函数生成季节性模式,并添加随机噪声。
- 绘制自相关图和偏自相关图:分析残差的自相关性和偏自相关性。

3. 自回归滑动平均 (ARMA, Autoregressive Moving Average Model)
ARMA模型结合了自回归和移动平均模型。
原理
模型利用前 p 个时间点的数据和前 q 个时间点的误差预测当前时间点的数据。
核心公式
ARMA模型是将自回归模型和移动平均模型结合,利用两者的推导方法,对两个模型的参数进行联合估计。
核心案例
代码中,我们使用Python中的 statsmodels
库来进行ARMA建模和分析,并使用 matplotlib
来绘制图形。
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
# 生成示例时间序列数据
np.random.seed(42)
n = 200
ar_params = np.array([0.75, -0.25])
ma_params = np.array([0.65, 0.35])
ar = np.r_[1, -ar_params] # add zero-lag and negate
ma = np.r_[1, ma_params] # add zero-lag
y = np.random.normal(size=n)
x = np.convolve(y, ma)[:n] np.random.normal(size=n)
time_series = pd.Series(x)
# 绘制原始时间序列数据
plt.figure(figsize=(12, 6))
plt.plot(time_series, label='Original Time Series')
plt.title('Original Time Series')
plt.xlabel('Time')
plt.ylabel('Value')
plt.legend()
plt.show()
# 绘制自相关图 (ACF) 和偏自相关图 (PACF)
fig, axes = plt.subplots(1, 2, figsize=(16, 6))
plot_acf(time_series, ax=axes[0], title='Autocorrelation Function (ACF)')
plot_pacf(time_series, ax=axes[1], title='Partial Autocorrelation Function (PACF)')
plt.show()
# 建立并拟合ARMA模型
model = ARIMA(time_series, order=(2, 0, 2))
arma_result = model.fit()
# 打印模型摘要
print(arma_result.summary())
# 绘制拟合后的时间序列和残差图
plt.figure(figsize=(12, 6))
plt.plot(time_series, label='Original Time Series')
plt.plot(arma_result.fittedvalues, color='red', label='Fitted Values')
plt.title('Original and Fitted Time Series')
plt.xlabel('Time')
plt.ylabel('Value')
plt.legend()
plt.show()
# 绘制残差图
residuals = arma_result.resid
plt.figure(figsize=(12, 6))
plt.plot(residuals, label='Residuals')
plt.title('Residuals of ARMA Model')
plt.xlabel('Time')
plt.ylabel('Residual')
plt.legend()
plt.show()
- 生成示例时间序列数据:我们生成一个包含200个数据点的时间序列,使用自回归参数
ar_params
和移动平均参数 ma_params
。 - 绘制原始时间序列数据:使用
matplotlib
绘制原始时间序列数据。 - 绘制ACF和PACF图:使用
statsmodels
库的 plot_acf
和 plot_pacf
函数绘制自相关函数 (ACF) 和偏自相关函数 (PACF) 图。 - 建立并拟合ARMA模型:使用
statsmodels
库中的 ARIMA
函数建立ARMA模型并进行拟合。 - 打印模型摘要:打印拟合结果的摘要,包含模型参数和统计信息。
- 绘制拟合后的时间序列和残差图:绘制原始时间序列与模型拟合值的对比图,以及模型残差图。

4. 自回归积分滑动平均 (ARIMA, Autoregressive Integrated Moving Average Model)
ARIMA模型扩展了ARMA模型,适用于非平稳时间序列。
原理
模型通过对数据进行差分处理,使其平稳,然后再应用ARMA模型。
核心公式
其中:
通过对原始序列 进行 d 次差分,使其变为平稳序列 ,然后对平稳序列应用ARMA模型进行参数估计。
核心案例
当然可以!下面是一个关于时间序列分析的案例,使用 ARIMA 模型来分析和预测数据。我们将使用 Python 的 pandas
、numpy
、matplotlib
和 statsmodels
库来完成这项任务。具体案例为模拟一个经济数据的时间序列,例如股票价格或经济指标。
案例概述
创建一个模拟的时间序列数据,应用 ARIMA 模型进行建模和预测,并画出原始数据、ACF (自相关函数) 图和预测结果图。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import statsmodels.api as sm
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
# 1. 创建模拟时间序列数据
np.random.seed(42)
n = 200
time = np.arange(n)
data = np.sin(0.1 * time) 0.5 * np.random.randn(n)
# 转换为 Pandas DataFrame
df = pd.DataFrame(data, columns=['Value'])
df.index = pd.date_range(start='2020-01-01', periods=n, freq='D')
# 2. 绘制原始时间序列图
plt.figure(figsize=(14, 7))
plt.subplot(3, 1, 1)
plt.plot(df.index, df['Value'], label='Original Data')
plt.title('Original Time Series')
plt.xlabel('Date')
plt.ylabel('Value')
plt.legend()
# 3. 绘制自相关函数 (ACF) 和偏自相关函数 (PACF) 图
plt.subplot(3, 1, 2)
plot_acf(df['Value'], ax=plt.gca(), lags=30)
plt.title('ACF of Time Series')
plt.subplot(3, 1, 3)
plot_pacf(df['Value'], ax=plt.gca(), lags=30)
plt.title('PACF of Time Series')
plt.tight_layout()
plt.show()
# 4. 应用 ARIMA 模型
from statsmodels.tsa.arima.model import ARIMA
# 拟合 ARIMA 模型
model = ARIMA(df['Value'], order=(5, 0, 0)) # (p, d, q) 这里 d=0 是因为数据没有差分
model_fit = model.fit()
# 打印模型摘要
print(model_fit.summary())
# 5. 预测未来 20 个时间点
forecast = model_fit.forecast(steps=20)
# 创建预测数据的时间序列
forecast_index = pd.date_range(start=df.index[-1] pd.Timedelta(days=1), periods=20, freq='D')
forecast_df = pd.DataFrame(forecast, index=forecast_index, columns=['Forecast'])
# 6. 绘制预测结果图
plt.figure(figsize=(14, 7))
plt.plot(df.index, df['Value'], label='Original Data')
plt.plot(forecast_df.index, forecast_df['Forecast'], color='red', linestyle='--', label='Forecast')
plt.title('Forecast using ARIMA Model')
plt.xlabel('Date')
plt.ylabel('Value')
plt.legend()
plt.show()
- 数据生成: 使用正弦函数加上随机噪声生成模拟时间序列数据。
- 自相关函数 (ACF) 图和偏自相关函数 (PACF) 图:用于确定 ARIMA 模型的参数。
- 预测结果图: 展示 ARIMA 模型的预测结果与原始数据。

5. 季节性自回归积分滑动平均 (SARIMA, Seasonal ARIMA)
SARIMA模型扩展了ARIMA模型,适用于季节性时间序列。
原理
模型结合了季节性自回归、季节性差分和季节性移动平均成分。
核心公式
其中:
将季节性成分加入到ARIMA模型中,结合季节性自回归、季节性差分和季节性移动平均,对模型进行参数估计。
核心案例
以下是一个关于月度航空乘客数量数据的案例分析,该数据集包含1949年1月到1960年12月之间的月度航空乘客数量。我们使用SARIMA模型对该数据进行建模,并绘制相关的图形进行数据分析。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.tsa.statespace.sarimax import SARIMAX
from statsmodels.tsa.stattools import adfuller, acf, pacf
# 加载航空乘客数据集
file = 'airline-passengers.csv'
data = pd.read_csv(file, index_col='Month', parse_dates=True)
data.index.freq = 'MS'
# 绘制原始数据
plt.figure(figsize=(10, 6))
plt.plot(data, label='Monthly Airline Passengers')
plt.title('Monthly Airline Passengers from 1949 to 1960')
plt.xlabel('Date')
plt.ylabel('Number of Passengers')
plt.legend()
plt.show()
# 进行ADF检验
adf_result = adfuller(data['Passengers'])
print(f'ADF Statistic: {adf_result[0]}')
print(f'p-value: {adf_result[1]}')
# 绘制ACF和PACF图
lag_acf = acf(data['Passengers'], nlags=40)
lag_pacf = pacf(data['Passengers'], nlags=40, method='ols')
plt.figure(figsize=(12, 6))
plt.subplot(121)
plt.stem(range(len(lag_acf)), lag_acf, linefmt='b-', markerfmt='bo', basefmt='r-')
plt.axhline(y=0, linestyle='--', color='gray')
plt.axhline(y=-1.96/np.sqrt(len(data)), linestyle='--', color='gray')
plt.axhline(y=1.96/np.sqrt(len(data)), linestyle='--', color='gray')
plt.title('Autocorrelation Function')
plt.subplot(122)
plt.stem(range(len(lag_pacf)), lag_pacf, linefmt='b-', markerfmt='bo', basefmt='r-')
plt.axhline(y=0, linestyle='--', color='gray')
plt.axhline(y=-1.96/np.sqrt(len(data)), linestyle='--', color='gray')
plt.axhline(y=1.96/np.sqrt(len(data)), linestyle='--', color='gray')
plt.title('Partial Autocorrelation Function')
plt.tight_layout()
plt.show()
# 拟合SARIMA模型
model = SARIMAX(data['Passengers'], order=(1, 1, 1), seasonal_order=(1, 1, 1, 12))
results = model.fit()
# 打印模型总结
print(results.summary())
# 绘制预测结果
data['forecast'] = results.predict(start=120, end=144, dynamic=True)
plt.figure(figsize=(10, 6))
plt.plot(data['Passengers'], label='Actual Passengers')
plt.plot(data['forecast'], label='Forecasted Passengers', color='red')
plt.title('Actual vs Forecasted Passengers')
plt.xlabel('Date')
plt.ylabel('Number of Passengers')
plt.legend()
plt.show()
- 绘制自相关函数(ACF)和偏自相关函数(PACF)图,以帮助确定模型的阶数。

6. 向量自回归 (VAR, Vector Autoregression)
VAR模型是自回归模型的多变量扩展,适用于多变量时间序列。
原理
模型利用多个时间序列的历史数据进行联合预测。
核心公式
其中:
对多变量时间序列进行线性回归,使用最小二乘法求解系数矩阵 。
核心案例
使用美国经济时间序列数据集,该数据集包括了消费、收入和投资的月度数据。这个数据集可以在 statsmodels
库中找到。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.tsa.api import VAR
# 加载数据集
from statsmodels.datasets.macrodata import load_pandas
data = load_pandas().data
# 选择感兴趣的变量
df = data[['realgdp', 'realcons', 'realinv']]
# 设置时间索引
dates = pd.date_range(start='1959Q1', periods=len(df), freq='Q')
df.index = dates
# 绘制原始数据的时间序列图
fig, axes = plt.subplots(nrows=3, ncols=1, figsize=(10, 8))
df.plot(subplots=True, ax=axes)
plt.tight_layout()
plt.show()
# 计算一阶差分
df_diff = df.diff().dropna()
# 绘制差分后的数据
fig, axes = plt.subplots(nrows=3, ncols=1, figsize=(10, 8))
df_diff.plot(subplots=True, ax=axes)
plt.tight_layout()
plt.show()
# 构建并训练VAR模型
model = VAR(df_diff)
results = model.fit(maxlags=15, ic='aic')
# 打印模型摘要
print(results.summary())
# 绘制模型残差的时间序列图
fig, axes = plt.subplots(nrows=3, ncols=1, figsize=(10, 8))
for i, column in enumerate(df_diff.columns):
axes[i].plot(results.resid[:, i])
axes[i].set_title(f'Residuals of {column}')
plt.tight_layout()
plt.show()
# 预测未来的时间序列
lag_order = results.k_ar
forecast = results.forecast(df_diff.values[-lag_order:], steps=10)
forecast_index = pd.date_range(start=df.index[-1], periods=10, freq='Q')
forecast_df = pd.DataFrame(forecast, index=forecast_index, columns=df.columns)
# 绘制预测结果
fig, axes = plt.subplots(nrows=3, ncols=1, figsize=(10, 8))
for i, column in enumerate(df.columns):
axes[i].plot(df.index, df[column], label='Original')
axes[i].plot(forecast_df.index, forecast_df[column], label='Forecast')
axes[i].set_title(f'{column} - Original vs Forecast')
axes[i].legend()
plt.tight_layout()
plt.show()
- 选择了实际GDP、实际消费和实际投资作为分析变量。
- 预测了未来10个季度的时间序列,并绘制了预测结果与原始数据的对比图。

7. 向量自回归滑动平均 (VARMA, Vector Autoregressive Moving Average)
VARMA模型结合了向量自回归和移动平均模型。
原理
模型利用多个时间序列的历史数据和误差进行联合预测。
核心公式
其中:
结合VAR模型和MA模型的推导方法,对两个模型的参数进行联合估计。
核心案例
时间序列分析中的向量自回归滑动平均(VARMA)模型通常用于分析多个相关联的时间序列变量之间的动态关系。
假设我们有两个变量,分别是销售量和广告支出,我们想分析它们之间的动态关系。我们将构建一个VARMA(1,1)模型来说明。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.statespace.varmax import VARMAX
from statsmodels.tsa.vector_ar.var_model import VAR
# 生成模拟数据
np.random.seed(42)
n_obs = 100
sales = np.random.normal(loc=100, scale=15, size=n_obs)
advertising = np.random.normal(loc=50, scale=10, size=n_obs)
# 创建DataFrame
data = pd.DataFrame({'Sales': sales, 'Advertising': advertising})
# 拆分数据为训练集和测试集
train = data.iloc[:80]
test = data.iloc[80:]
# 拟合VARMA模型
model = VARMAX(train, order=(1, 1))
results = model.fit(maxiter=1000, disp=False)
print(results.summary())
# 预测未来值
forecast = results.forecast(steps=len(test))
# 绘制销售量和广告支出的时间序列及预测结果
plt.figure(figsize=(14, 7))
plt.subplot(2, 1, 1)
plt.plot(train['Sales'], label='Actual Sales (Train)')
plt.plot(test.index, forecast['Sales'], label='Forecasted Sales')
plt.title('Sales Forecast using VARMA(1,1)')
plt.legend()
plt.subplot(2, 1, 2)
plt.plot(train['Advertising'], label='Actual Advertising (Train)')
plt.plot(test.index, forecast['Advertising'], label='Forecasted Advertising')
plt.title('Advertising Forecast using VARMA(1,1)')
plt.legend()
plt.tight_layout()
plt.show()
- 我们首先生成了模拟数据,模拟了销售量和广告支出的时间序列。
- 使用VARMAX模型拟合了VARMA(1,1)模型。
- 对测试集进行预测,并绘制了销售量和广告支出的实际数据以及预测结果的时间序列图。

8. 长短期记忆网络 (LSTM, Long Short-Term Memory)
LSTM是一种特殊的递归神经网络(RNN),适用于捕捉长时间依赖关系。
原理
LSTM通过引入记忆单元和门控机制,有效解决了RNN的梯度消失问题。
核心公式
LSTM通过记忆单元 和三个门控单元(遗忘门 ,输入门 和输出门 )进行信息控制。推导过程可以通过反向传播算法进行参数优化。
核心案例
使用Keras来构建和训练LSTM模型,并使用Matplotlib来绘制数据分析图形。我们使用一个简单的模拟时间序列数据来演示LSTM模型的应用。该数据代表某种时间序列,例如每日温度变化。
import numpy as np
import matplotlib.pyplot as plt
# 生成模拟时间序列数据
np.random.seed(0)
time_steps = 100
data = np.sin(np.linspace(0, 10 * np.pi, time_steps)) np.random.normal(0, 0.5, time_steps)
# 绘制原始数据
plt.figure(figsize=(14, 6))
plt.plot(data, label='Original Data')
plt.title('Simulated Time Series Data')
plt.xlabel('Time Step')
plt.ylabel('Value')
plt.legend()
plt.show()
# 构建LSTM模型
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense
# 准备训练数据
def create_dataset(data, look_back=1):
X, y = [], []
for i in range(len(data) - look_back):
X.append(data[i:(i look_back)])
y.append(data[i look_back])
return np.array(X), np.array(y)
look_back = 3
X, y = create_dataset(data, look_back)
X = X.reshape(X.shape[0], X.shape[1], 1) # LSTM 需要 3D 输入
# 构建 LSTM 模型
model = Sequential()
model.add(LSTM(50, input_shape=(look_back, 1)))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
# 训练模型
model.fit(X, y, epochs=100, batch_size=1, verbose=2)
# 预测并绘制结果
train_predict = model.predict(X)
train_predict_plot = np.empty_like(data)
train_predict_plot[:] = np.nan
train_predict_plot[look_back:len(train_predict) look_back] = train_predict.flatten()
# 绘制原始数据与预测数据对比图
plt.figure(figsize=(14, 6))
plt.plot(data, label='Original Data')
plt.plot(train_predict_plot, label='LSTM Prediction')
plt.title('LSTM Prediction vs Original Data')
plt.xlabel('Time Step')
plt.ylabel('Value')
plt.legend()
plt.show()
# 绘制损失函数变化图
history = model.history
loss = history.history['loss']
plt.figure(figsize=(14, 6))
plt.plot(loss, label='Training Loss')
plt.title('Model Training Loss Over Epochs')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.show()
两个数据分析图形:一个是原始数据与LSTM预测数据的对比图,另一个是训练过程中损失函数的变化图。

9. Prophet
Prophet是由Facebook开发的时间序列预测工具,适用于包含节假日效应、趋势变化和周期性变化的数据。
原理
模型将时间序列分解为趋势、季节性和节假日效应部分。
核心公式
其中:
通过对各部分进行独立建模和参数估计,最终结合各部分得到预测结果。
核心案例
下面是一个使用 Facebook 的 Prophet 库进行时间序列分析的案例。在这个案例中,我们将使用 Prophet 对一个时间序列进行建模和预测,并绘制多个图形来展示数据分析的结果。
我们将使用一个示例数据集,该数据集包含了某网站每日的访问量。我们将进行以下步骤:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from prophet import Prophet
# 生成示例数据
dates = pd.date_range(start='2020-01-01', periods=730, freq='D')
data = np.random.poisson(lam=200, size=730) np.linspace(0, 100, 730)
df = pd.DataFrame({'ds': dates, 'y': data})
# 初始化并训练Prophet模型
model = Prophet(yearly_seasonality=True, daily_seasonality=False)
model.fit(df)
# 创建未来的数据框架并进行预测
future = model.make_future_dataframe(periods=365)
forecast = model.predict(future)
# 绘制原始数据及预测结果
fig1 = model.plot(forecast)
plt.title('Original Data and Forecast')
plt.xlabel('Date')
plt.ylabel('Website Traffic')
# 绘制趋势和季节性成分
fig2 = model.plot_components(forecast)
plt.show()
# 绘制实际数据与预测值的对比
plt.figure(figsize=(10, 6))
plt.plot(df['ds'], df['y'], label='Actual')
plt.plot(forecast['ds'], forecast['yhat'], label='Forecast', linestyle='--')
plt.fill_between(forecast['ds'], forecast['yhat_lower'], forecast['yhat_upper'], color='gray', alpha=0.2)
plt.title('Actual vs Forecast')
plt.xlabel('Date')
plt.ylabel('Website Traffic')
plt.legend()
plt.show()
# 绘制残差图
residuals = df['y'] - forecast['yhat'][:len(df)]
plt.figure(figsize=(10, 6))
plt.plot(df['ds'], residuals)
plt.axhline(0, linestyle='--', color='red')
plt.title('Residuals')
plt.xlabel('Date')
plt.ylabel('Residual')
plt.show()
数据生成和预处理:使用 pandas
生成了从 2020 年 1 月 1 日开始的 730 天的日期范围。生成了一个示例数据集,模拟了网站的每日访问量。
模型训练:初始化 Prophet 模型,并设置年度季节性为真,每日季节性为假。使用示例数据集训练模型。
预测:创建一个包含未来 365 天的日期的数据框架,并使用训练好的模型进行预测。绘制原始数据及预测结果图,展示了实际数据与预测值的对比。
趋势和季节性成分:绘制趋势和季节性成分图,展示了预测中的长期趋势和季节性波动。
实际数据与预测值的对比:将实际数据与预测值进行对比,展示了预测模型的拟合效果。
残差图:计算残差(实际值减去预测值),并绘制残差图,展示了模型的预测误差。


10. 变分自编码器 (VAE, Variational Autoencoders)
VAE是一种生成模型,适用于捕捉复杂时间序列数据的潜在结构。
原理
VAE通过变分推断,将复杂的时间序列数据映射到潜在空间,然后再从潜在空间重构数据。
核心公式
VAE使用变分推断的方法,最大化对数似然函数:
其中:
VAE通过神经网络来参数化 和 ,使用反向传播算法进行优化。
这些方法各自有其适用的场景和优缺点,选择合适的方法取决于具体的数据特征和分析需求。
核心案例
这里,是一个使用变分自编码器(VAE)进行时间序列分析的案例:
import numpy as np
import matplotlib.pyplot as plt
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, Dataset
# 生成正弦波时间序列数据
def generate_sine_wave(seq_length, num_samples):
x = np.linspace(0, np.pi * 2 * num_samples, seq_length * num_samples)
y = np.sin(x)
data = y.reshape(num_samples, seq_length, 1)
return data
seq_length = 50
num_samples = 1000
data = generate_sine_wave(seq_length, num_samples)
# 数据集类
class TimeSeriesDataset(Dataset):
def __init__(self, data):
self.data = torch.tensor(data, dtype=torch.float32)
def __len__(self):
return len(self.data)
def __getitem__(self, idx):
return self.data[idx]
dataset = TimeSeriesDataset(data)
dataloader = DataLoader(dataset, batch_size=32, shuffle=True)
# 定义VAE模型:
class VAE(nn.Module):
def __init__(self, input_dim, hidden_dim, latent_dim):
super(VAE, self).__init__()
# 编码器
self.encoder = nn.Sequential(
nn.Linear(input_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, latent_dim * 2) # 输出mean和logvar
)
# 解码器
self.decoder = nn.Sequential(
nn.Linear(latent_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, input_dim),
nn.Sigmoid()
)
def reparameterize(self, mean, logvar):
std = torch.exp(0.5 * logvar)
eps = torch.randn_like(std)
return mean eps * std
def forward(self, x):
x = x.view(x.size(0), -1)
mean_logvar = self.encoder(x)
mean, logvar = mean_logvar[:, :latent_dim], mean_logvar[:, latent_dim:]
z = self.reparameterize(mean, logvar)
x_recon = self.decoder(z)
return x_recon, mean, logvar
# 训练VAE模型:
input_dim = seq_length
hidden_dim = 128
latent_dim = 16
num_epochs = 50
learning_rate = 0.001
vae = VAE(input_dim, hidden_dim, latent_dim)
optimizer = optim.Adam(vae.parameters(), lr=learning_rate)
criterion = nn.MSELoss()
def loss_function(recon_x, x, mean, logvar):
recon_loss = criterion(recon_x, x)
kld_loss = -0.5 * torch.sum(1 logvar - mean.pow(2) - logvar.exp())
return recon_loss kld_loss
for epoch in range(num_epochs):
vae.train()
train_loss = 0
for batch in dataloader:
optimizer.zero_grad()
recon_batch, mean, logvar = vae(batch)
loss = loss_function(recon_batch, batch.view(-1, input_dim), mean, logvar)
loss.backward()
train_loss = loss.item()
optimizer.step()
print(f'Epoch {epoch 1}, Loss: {train_loss / len(dataloader.dataset)}')
# 绘制原始时间序列与重构时间序列的对比图
vae.eval()
with torch.no_grad():
for batch in dataloader:
recon_batch, mean, logvar = vae(batch)
break
recon_batch = recon_batch.view(-1, seq_length).numpy()
original_batch = batch.numpy()
plt.figure(figsize=(12, 6))
plt.plot(original_batch[0], label='Original')
plt.plot(recon_batch[0], label='Reconstructed')
plt.legend()
plt.title('Original vs Reconstructed Time Series')
plt.show()
# 绘制VAE潜在空间的可视化图
latent_vectors = []
vae.eval()
with torch.no_grad():
for batch in dataloader:
_, mean, _ = vae(batch)
latent_vectors.append(mean.numpy())
latent_vectors = np.concatenate(latent_vectors, axis=0)
plt.figure(figsize=(10, 8))
plt.scatter(latent_vectors[:, 0], latent_vectors[:, 1], alpha=0.5)
plt.title('Latent Space Visualization')
plt.xlabel('Latent Dimension 1')
plt.ylabel('Latent Dimension 2')
plt.show()
