使用PyMC进行时间序列分层建模

简介: 在统计建模领域,理解总体趋势的同时解释群体差异的一个强大方法是分层(或多层)建模。这种方法允许参数随组而变化,并捕获组内和组间的变化。在时间序列数据中,这些特定于组的参数可以表示不同组随时间的不同模式。

今天,我们将深入探讨如何使用PyMC(用于概率编程的Python库)构建分层时间序列模型。

让我们从为多个组生成一些人工时间序列数据开始,每个组都有自己的截距和斜率。

 import numpy as np
 import matplotlib.pyplot as plt
 import pymc as pm

 # Simulating some data
 np.random.seed(0)
 n_groups = 3  # number of groups
 n_data_points = 100  # number of data points per group
 x = np.tile(np.linspace(0, 10, n_data_points), n_groups)
 group_indicator = np.repeat(np.arange(n_groups), n_data_points)
 slope_true = np.random.normal(0, 1, size=n_groups)
 intercept_true = np.random.normal(2, 1, size=n_groups)
 y = slope_true[group_indicator]*x + intercept_true[group_indicator] + np.random.normal(0, 1, size=n_groups*n_data_points)

我们生成了三个不同组的时间序列数据。每组都有自己的时间趋势,由唯一的截距和斜率定义。

 colors = ['b', 'g', 'r']  # Define different colors for each group

 plt.figure(figsize=(10, 5))

 # Plot raw data for each group
 for i in range(n_groups):
     plt.plot(x[group_indicator == i], y[group_indicator == i], 'o', color=colors[i], label=f'Group {i+1}')

 plt.title('Raw Data with Groups')
 plt.xlabel('Time')
 plt.ylabel('Value')
 plt.legend()
 plt.show()

下一步是构建层次模型。我们的模型将具有组特定的截距(alpha)和斜率(beta)。截距和斜率是从具有超参数mu_alpha、sigma_alpha、mu_beta和sigma_beta的正态分布中绘制的。这些超参数分别表示截距和斜率的组水平均值和标准差。

 with pm.Model() as hierarchical_model:
     # Hyperpriors
     mu_alpha = pm.Normal('mu_alpha', mu=0, sigma=10)
     sigma_alpha = pm.HalfNormal('sigma_alpha', sigma=10)
     mu_beta = pm.Normal('mu_beta', mu=0, sigma=10)
     sigma_beta = pm.HalfNormal('sigma_beta', sigma=10)

     # Priors
     alpha = pm.Normal('alpha', mu=mu_alpha, sigma=sigma_alpha, shape=n_groups)  # group-specific intercepts
     beta = pm.Normal('beta', mu=mu_beta, sigma=sigma_beta, shape=n_groups)  # group-specific slopes
     sigma = pm.HalfNormal('sigma', sigma=1)

     # Expected value
     mu = alpha[group_indicator] + beta[group_indicator] * x

     # Likelihood
     y_obs = pm.Normal('y_obs', mu=mu, sigma=sigma, observed=y)

     # Sampling
     trace = pm.sample(2000, tune=1000)

现在我们已经定义了模型并对其进行了采样。让我们检查不同参数的模型估计:

 # Checking the trace
 pm.plot_trace(trace,var_names=['alpha','beta'])
 plt.show()

最后一步是将原始数据和模型预测可视化:

 # Posterior samples
 alpha_samples = trace.posterior['alpha'].values
 beta_samples = trace.posterior['beta'].values

 # New x values for predictions
 x_new = np.linspace(0, 10, 200)

 plt.figure(figsize=(10, 5))

 # Plot raw data and predictions for each group
 for i in range(n_groups):
     # Plot raw data

     plt.plot(x[group_indicator == i], y[group_indicator == i], 'o', color=colors[i], label=f'Group {i+1} observed')
     x_new = x[group_indicator == i]
     # Generate and plot predictions
     alpha = trace.posterior.sel(alpha_dim_0=i,beta_dim_0=i)['alpha'].values
     beta = trace.posterior.sel(alpha_dim_0=i,beta_dim_0=i)['beta'].values
     y_hat = alpha[..., None] + beta[..., None] * x_new[None,:]
     y_hat_mean = y_hat.mean(axis=(0, 1))
     y_hat_std = y_hat.std(axis=(0, 1))
     plt.plot(x_new, y_hat_mean, color=colors[i], label=f'Group {i+1} predicted')
     plt.fill_between(x_new, y_hat_mean - 2*y_hat_std, y_hat_mean + 2*y_hat_std, color=colors[i], alpha=0.3)

 plt.title('Raw Data with Posterior Predictions by Group')
 plt.xlabel('Time')
 plt.ylabel('Value')
 plt.legend()
 plt.show()

从图中可以看出,分层时间序列模型很好地捕获了每组中的单个趋势,而阴影区域给出了预测的不确定性。

层次模型为捕获时间序列数据中的组级变化提供了一个强大的框架。它们允许我们在组之间共享统计数据,提供部分信息池和对数据结构的细微理解。使用像PyMC这样的库,实现这些模型变得相当简单,为健壮且可解释的时间序列分析铺平了道路。

https://avoid.overfit.cn/post/56ad545325504850ab2b7b7b9a264a61

作者:Charles Copley

目录
相关文章
|
5月前
|
SQL 存储 关系型数据库
技术心得记录:数仓建模方法之范式建模、ER实体建模、维度建模
技术心得记录:数仓建模方法之范式建模、ER实体建模、维度建模
103 0
|
6月前
|
存储 数据可视化 前端开发
数仓常用分层与维度建模
本文介绍了数据仓库的分层结构和维度建模。数仓通常分为ODS、DIM、DWD、DWS和ADS五层,各层负责不同的数据处理阶段。维度建模是数据组织方法,包括星型和雪花模型。星型模型简单直观,查询性能高,适合简单查询;雪花模型则通过规范化减少冗余,提高数据一致性和结构复杂性,但可能影响查询效率。选择模型需根据业务需求和数据复杂性来定。
513 0
|
6月前
维度建模-2
维度建模-2
83 4
|
6月前
|
存储 数据挖掘
维度建模-3
维度建模-3
124 3
|
6月前
|
存储 数据建模
维度建模-1
维度建模-1
60 1
|
机器学习/深度学习 监控 vr&ar
时间序列预测的20个基本概念总结
时间序列是一组按时间顺序排列的数据点
278 2
|
大数据 数据管理 数据库
数据仓库(3)数仓建模之星型模型与维度建模
维度建模是一种将数据结构化的逻辑设计方法,也是一种广泛应用的数仓建模方式,它将客观世界划分为度量和上下文。度量是常常是以数值形式出现,事实周围有上下文包围着,这种上下文被直观地分成独立的逻辑块,称之为维度。它与实体-关系建模有很大的区别,实体-关系建模是面向应用,遵循第三范式,以消除数据冗余为目标的设计技术。维度建模是面向分析,为了提高查询性能可以增加数据冗余,反规范化的设计技术。
462 1
|
测试技术
分析建模
分析建模
112 0
|
机器学习/深度学习 并行计算 算法
R-建模 randomForest
本分分享了R语言中 `randomForest` 函数的用法,以供参考
133 0
|
算法 异构计算
时序电路建模基础
⭐本专栏针对FPGA进行入门学习,从数电中常见的逻辑代数讲起,结合Verilog HDL语言学习与仿真,主要对组合逻辑电路与时序逻辑电路进行分析与设计,对状态机FSM进行剖析与建模。
113 0
时序电路建模基础