使用递归图 recurrence plot 表征时间序列

简介: 在本文中,我将展示如何使用递归图 Recurrence Plots 来描述不同类型的时间序列。我们将查看具有500个数据点的各种模拟时间序列。我们可以通过可视化时间序列的递归图并将其与其他已知的不同时间序列的递归图进行比较,从而直观地表征时间序列。

递归图

Recurrence Plots(RP)是一种用于可视化和分析时间序列或动态系统的方法。它将时间序列转化为图形化的表示形式,以便分析时间序列中的重复模式和结构。Recurrence Plots 是非常有用的,尤其是在时间序列数据中存在周期性、重复事件或关联结构时。

Recurrence Plots 的基本原理是测量时间序列中各点之间的相似性。如果两个时间点之间的距离小于某个给定的阈值,就会在 Recurrence Plot 中绘制一个点,表示这两个时间点之间存在重复性。这些点在二维平面上组成了一种图像。

 import numpy as np
 import matplotlib.pyplot as plt

 def recurrence_plot(data, threshold=0.1):
     """
     Generate a recurrence plot from a time series.

     :param data: Time series data
     :param threshold: Threshold to determine recurrence
     :return: Recurrence plot
     """
     # Calculate the distance matrix
     N = len(data)
     distance_matrix = np.zeros((N, N))
     for i in range(N):
         for j in range(N):
             distance_matrix[i, j] = np.abs(data[i] - data[j])

     # Create the recurrence plot
     recurrence_plot = np.where(distance_matrix <= threshold, 1, 0)

     return recurrence_plot

上面的代码创建了一个二进制距离矩阵,如果时间序列i和j的值相差在0.1以内(阈值),则它们的值为1,否则为0。得到的矩阵可以看作是一幅图像。

白噪声

接下来我们将可视化白噪声。首先,我们需要创建一系列模拟的白噪声:

 # Set a seed for reproducibility
 np.random.seed(0)

 # Generate 500 data points of white noise
 white_noise = np.random.normal(size=500)

 # Plot the white noise time series
 plt.figure(figsize=(10, 6))
 plt.plot(white_noise, label='White Noise')
 plt.title('White Noise Time Series')
 plt.xlabel('Time')
 plt.ylabel('Value')
 plt.legend()
 plt.grid(True)
 plt.show()

递归图为这种白噪声提供了有趣的可视化效果。对于任何一种白噪声,图看起来都是一样的:

 # Generate and plot the recurrence plot
 recurrence = recurrence_plot(white_noise, threshold=0.1)

 plt.figure(figsize=(8, 8))
 plt.imshow(recurrence, cmap='binary', origin='lower')
 plt.title('Recurrence Plot')
 plt.xlabel('Time')
 plt.ylabel('Time')
 plt.colorbar(label='Recurrence')
 plt.show()

可以直观地看到一个嘈杂的过程。可以看到图中对角线总是黑色的。

随机游走

接下来让我们看看随机游走(Random Walk)是什么样子的:

 # Generate 500 data points of a random walk
 steps = np.random.choice([-1, 1], size=500) # Generate random steps: -1 or 1
 random_walk = np.cumsum(steps) # Cumulative sum to generate the random walk

 # Plot the random walk time series
 plt.figure(figsize=(10, 6))
 plt.plot(random_walk, label='Random Walk')
 plt.title('Random Walk Time Series')
 plt.xlabel('Time')
 plt.ylabel('Value')
 plt.legend()
 plt.grid(True)
 plt.show()

 # Generate and plot the recurrence plot
 recurrence = recurrence_plot(random_walk, threshold=0.1)

 plt.figure(figsize=(8, 8))
 plt.imshow(recurrence, cmap='binary', origin='lower')
 plt.title('Recurrence Plot')
 plt.xlabel('Time')
 plt.ylabel('Time')
 plt.colorbar(label='Recurrence')
 plt.show()

SARIMA

SARIMA(4,1,4)(1,0,0,12)的模拟数据

 from statsmodels.tsa.statespace.sarimax import SARIMAX

 # Define SARIMA parameters
 p, d, q = 4, 1, 4  # Non-seasonal order
 P, D, Q, s = 1, 0, 0, 12  # Seasonal order

 # Simulate data
 model = SARIMAX(np.random.randn(100), order=(p, d, q), seasonal_order=(P, D, Q, s), trend='ct')
 fit = model.fit(disp=False)  # Fit the model to random data to get parameters
 simulated_data = fit.simulate(nsimulations=500)

 # Plot the simulated time series
 plt.figure(figsize=(10, 6))
 plt.plot(simulated_data, label=f'SARIMA({p},{d},{q})({P},{D},{Q},{s})')
 plt.title('Simulated Time Series from SARIMA Model')
 plt.xlabel('Time')
 plt.ylabel('Value')
 plt.legend()
 plt.grid(True)
 plt.show()

 recurrence = recurrence_plot(simulated_data, threshold=0.1)

 plt.figure(figsize=(8, 8))
 plt.imshow(recurrence, cmap='binary', origin='lower')
 plt.title('Recurrence Plot')
 plt.xlabel('Time')
 plt.ylabel('Time')
 plt.colorbar(label='Recurrence')
 plt.show()

混沌的数据

 def logistic_map(x, r):
     """Logistic map function."""
     return r * x * (1 - x)

 # Initialize parameters
 N = 500         # Number of data points
 r = 3.9         # Parameter r, set to a value that causes chaotic behavior
 x0 = np.random.rand()  # Initial value

 # Generate chaotic time series data
 chaotic_data = [x0]
 for _ in range(1, N):
     x_next = logistic_map(chaotic_data[-1], r)
     chaotic_data.append(x_next)

 # Plot the chaotic time series
 plt.figure(figsize=(10, 6))
 plt.plot(chaotic_data, label=f'Logistic Map (r={r})')
 plt.title('Chaotic Time Series')
 plt.xlabel('Time')
 plt.ylabel('Value')
 plt.legend()
 plt.grid(True)
 plt.show()

 recurrence = recurrence_plot(chaotic_data, threshold=0.1)

 plt.figure(figsize=(8, 8))
 plt.imshow(recurrence, cmap='binary', origin='lower')
 plt.title('Recurrence Plot')
 plt.xlabel('Time')
 plt.ylabel('Time')
 plt.colorbar(label='Recurrence')
 plt.show()

标准普尔500指数

作为最后一个例子,让我们看看从2013年10月28日至2023年10月27日的标准普尔500指数真实数据:

 import pandas as pd

 df = pd.read_csv('standard_and_poors_500_idx.csv', parse_dates=True)
 df['Date'] = pd.to_datetime(df['Date'])
 df.set_index('Date', inplace = True)
 df.drop(columns = ['Open', 'High', 'Low'], inplace = True)

 df.plot()
 plt.title('S&P 500 Index - 10/28/2013 to 10/27/2023')
 plt.ylabel('S&P 500 Index')
 plt.xlabel('Date');

 recurrence = recurrence_plot(df['Close/Last'], threshold=10)

 plt.figure(figsize=(8, 8))
 plt.imshow(recurrence, cmap='binary', origin='lower')
 plt.title('Recurrence Plot')
 plt.xlabel('Time')
 plt.ylabel('Time')
 plt.colorbar(label='Recurrence')
 plt.show()

选择合适的相似性阈值是 递归图分析的一个关键步骤。较小的阈值会导致更多的重复模式,而较大的阈值会导致更少的重复模式。阈值的选择通常需要根据数据的特性和分析目标进行调整。

这里我们不得不调整阈值,最终确得到的结果为10,这样可以获得更大的对比度。上面的递归图看起来很像随机游走递归图和无规则的混沌数据的混合体。

总结

在本文中,我们介绍了递归图以及如何使用Python创建递归图。递归图给了我们一种直观表征时间序列图的方法。递归图是一种强大的工具,用于揭示时间序列中的结构和模式,特别适用于那些具有周期性、重复性或复杂结构的数据。通过可视化和特征提取,研究人员可以更好地理解时间序列数据并进行进一步的分析。

从递归图中可以提取各种特征,以用于进一步的分析。这些特征可以包括重复点的分布、Lempel-Ziv复杂度、最长对角线长度等。

递归图在多个领域中得到了广泛应用,包括时间序列分析、振动分析、地震学、生态学、金融分析、生物医学等。它可用于检测周期性、异常事件、相位同步等。

https://avoid.overfit.cn/post/6b385fd6e8d64f2cb62d9caafd05389b

作者:Sam Erickson

目录
相关文章
|
机器学习/深度学习 运维
Moment:又一个开源的时间序列基础模型
MOMENT团队推出Time-series Pile,一个大型公共时间序列数据集,用于预训练首个开源时间序列模型家族。模型基于Transformer,采用遮蔽预训练技术,适用于预测、分类、异常检测和输入任务。研究发现,随机初始化比使用语言模型权重更有效,且直接预训练的模型表现出色。MOMENT改进了Transformer架构,调整了Layer norm并引入关系位置嵌入。模型在长期预测和异常检测中表现优异,但对于数值预测的效果尚不明朗。论文贡献包括开源方法、数据集创建和资源有限情况下的性能评估框架。
1315 0
|
2月前
|
机器学习/深度学习 监控 数据可视化
基于YOLOv8的无人机行人目标检测项目|完整源码数据集+PyQt5界面+完整训练流程+开箱即用!
本项目基于YOLOv8实现高精度、实时行人检测,集成PyQt5图形界面,支持图片/视频/摄像头/文件夹多源输入。含完整训练代码、标注数据集、预训练权重及详细教程,开箱即用,适用于无人机巡检、安防监控与应急救援等场景。
基于YOLOv8的无人机行人目标检测项目|完整源码数据集+PyQt5界面+完整训练流程+开箱即用!
|
4月前
|
机器学习/深度学习 算法 数据挖掘
YOLOv11改进 - C3k2融合 | C3k2融合CBSA 收缩 - 广播自注意力:轻量级设计实现高效特征压缩,优化处理效率 | NeurIPS 2025
本文提出收缩-广播自注意力(CBSA),通过选取代表性token进行收缩计算并广播结果,实现高效、可解释的线性复杂度注意力机制。其逻辑透明,统一多种注意力形式,并集成至YOLOv11的C3k2模块,在视觉任务中展现优越性能与速度优势。
YOLOv11改进 - C3k2融合 | C3k2融合CBSA 收缩 - 广播自注意力:轻量级设计实现高效特征压缩,优化处理效率 | NeurIPS 2025
|
10月前
|
机器学习/深度学习 人工智能 自然语言处理
面向认知智能的AI推理体系:理论基础与工程实践
本文深入探讨了AI推理从“感知智能”迈向“认知智能”的理论框架与技术突破。文章分析了符号推理、神经推理及混合推理的优劣势,指出了多跳推理、因果推理和可解释性等挑战。同时,结合大语言模型、ReAct架构和知识增强推理等前沿技术,展示了AI推理在代码实现中的应用。未来,认知图谱、推理驱动的智能体、边缘推理优化及人机协同将成为重要方向,推动AI向通用人工智能(AGI)迈进。
1158 60
面向认知智能的AI推理体系:理论基础与工程实践
|
11月前
|
机器学习/深度学习 人工智能 算法
Python+YOLO v8 实战:手把手教你打造专属 AI 视觉目标检测模型
本文介绍了如何使用 Python 和 YOLO v8 开发专属的 AI 视觉目标检测模型。首先讲解了 YOLO 的基本概念及其高效精准的特点,接着详细说明了环境搭建步骤,包括安装 Python、PyCharm 和 Ultralytics 库。随后引导读者加载预训练模型进行图片验证,并准备数据集以训练自定义模型。最后,展示了如何验证训练好的模型并提供示例代码。通过本文,你将学会从零开始打造自己的目标检测系统,满足实际场景需求。
11158 1
Python+YOLO v8 实战:手把手教你打造专属 AI 视觉目标检测模型
|
12月前
|
缓存 JavaScript 前端开发
Vue 基础语法介绍
Vue 基础语法介绍
|
计算机视觉
YOLOv11改进策略【卷积层】| 2024最新轻量级自适应提取模块 LAE 即插即用 保留局部信息和全局信息
YOLOv11改进策略【卷积层】| 2024最新轻量级自适应提取模块 LAE 即插即用 保留局部信息和全局信息
562 0
YOLOv11改进策略【卷积层】| 2024最新轻量级自适应提取模块 LAE 即插即用 保留局部信息和全局信息
|
机器学习/深度学习 算法
概率分布深度解析:PMF、PDF和CDF的技术指南
本文将深入探讨概率分布,详细阐述概率质量函数(PMF)、概率密度函数(PDF)和累积分布函数(CDF)这些核心概念,并通过实际示例进行说明。
2211 15
概率分布深度解析:PMF、PDF和CDF的技术指南
|
Kubernetes 网络协议 网络安全
k8s中网络连接问题
【10月更文挑战第3天】
1198 7

热门文章

最新文章