时间序列分析与可视化(python)

文摘   2024-09-29 20:47   辽宁  
点击上方“进修编程”,选择“星标公众号

超级无敌干货,第一时间送达!!!

每个数据集都有独特的品质,这些品质是数据分析领域的重要方面,可提供有关基础数据的深刻信息。时间序列数据是一种特别重要的数据集。本文深入探讨了时间序列数据集的复杂性,研究了它们的独特功能以及如何利用它们来获得重要见解。

什么是时间序列可视化和分析?

时间序列可视化和分析使用户能够以图形方式表示基于时间的数据,从而识别趋势并跟踪不同时期的变化。这些数据可以通过各种格式呈现,例如折线图、仪表、表格等。

利用时间序列可视化和分析有助于从数据中提取见解,从而生成预测并全面了解手头的信息。组织发现时间序列数据具有巨大价值,因为它允许他们分析实时和历史指标。

什么是时间序列数据?

时间序列数据是按连续时间顺序排列的数据点。时间序列分析包括分析时间序列数据以提取有意义的见解和其他有价值的数据特征的方法。

时间序列分析的重要性

时间序列数据分析在金融行业、制药业、社交媒体公司、网络服务提供商、研究等许多行业中都变得非常重要。要理解时间序列数据,数据可视化至关重要。事实上,如果没有可视化,任何类型的数据分析都是不完整的,因为一个好的可视化可以为数据提供有意义且有趣的见解。

基本时间序列概念

  • 趋势:趋势表示时间序列在一段较长时间内变化的总体方向。它表明值是增加、减少还是保持相对稳定。

  • 季节性:季节性是指在时间序列内定期出现的重复模式或周期,通常对应于特定的时间单位,如天、周、月或季节。

  • 移动平均数:移动平均数法是时间序列分析中常用的一种技术,用于平滑短期波动并突出数据的长期趋势或模式。它涉及计算一组连续数据点的平均值,这些数据点称为“窗口”或“滚动窗口”,因为它们在时间序列中移动

  • 噪声:噪声或随机波动表示时间序列中不遵循可辨别模式的不规则且不可预测的成分。它引入了与潜在趋势或季节性无关的变异性。

  • 差分:差分用于计算指定间隔内的值的差分。默认情况下,它是 1,我们可以为图指定不同的值。这是消除数据趋势的最常用方法。

  • 平稳性:平稳时间序列是指其统计特性(例如均值、方差和自相关)随时间保持不变的时间序列。

  • 阶数:差分阶数是指时间序列数据为了达到平稳性需要差分的次数。

  • 自相关:自相关是时间序列分析中使用的统计方法,用于量化时间序列与其滞后版本之间的相似程度。

  • 重采样:重采样是时间序列分析中的一种技术,涉及改变数据观察的频率。它通常用于将数据转换为不同的频率(例如,从每日到每月),以更清楚地揭示模式或趋势。

时间序列数据的类型

时间序列数据大致可以分为两部分:

1. 连续时间序列数据:连续时间序列数据涉及定期记录的测量或观察,形成无缝且不间断的序列。这种类型的数据的特点是可能值的连续范围,通常在各个领域遇到,包括:

  • 温度数据:以一致的间隔连续记录温度(例如每小时或每天测量)。

  • 股票市场数据:在交易时间内持续跟踪股票价格或价值。

  • 传感器数据:通过传感器连续测量,捕捉压力、湿度或空气质量等变量。

2.离散时间序列数据:另一方面,离散时间序列数据由仅限于特定值或类别的测量或观察组成。与连续数据不同,离散数据没有连续的可能值范围,而是由不同且独立的数据点组成。常见示例包括:

  • 计数数据:跟踪特定时间段内发生的事件的次数。

  • 分类数据:将数据分为不同的类别或等级(例如客户群、产品类型)。

  • 二进制数据:记录仅有两种可能结果或状态的数据。

不同数据类型的可视化方法:

  • 绘制连续时间序列中的数据可以使用线、面积或平滑图以图形方式有效地表示,从而提供对所研究趋势的动态行为的洞察。

  • 为了显示离散时间序列数据中的模式和分布,经常使用条形图、直方图和堆叠条形图。这些方法可以洞察特定事件或类别在一段时间内的分布和频率。

使用 Python 进行时间序列数据可视化

我们将使用 Python 库来可视化数据。数据集的链接可以在这里找到。我们将逐步进行可视化,就像在任何时间序列数据项目中所做的那样。

导入库

我们将在一个地方导入本文中使用的所有库,这样每次使用时就不必导入,这将节省我们的时间和精力。

Numpy – 一个用于数值数学计算和处理多维 ndarray 的 Python 库,它还拥有大量的数学函数集合来操作该数组。

Pandas –一个建立在 NumPy 之上的Python库,用于有效的矩阵乘法和数据框操作,它还用于数据清理、数据合并、数据重塑和数据聚合。

Matplotlib –用于绘制二维和三维可视化图,还支持多种输出格式,包括数据图形。 

import pandas as pdimport numpy as npimport seaborn as snsimport matplotlib.pyplot as pltfrom statsmodels.graphics.tsaplots import plot_acffrom statsmodels.tsa.stattools import adfuller

加载数据集

要将数据集加载到数据框中,我们将使用 pandas read_csv()函数。我们将使用head()函数打印数据集的前五行。在这里,我们将使用 read_csv 函数中的“ parse_dates ”参数将“Date”列转换为 DatetimeIndex 格式。默认情况下,日期以字符串格式存储,这不是时间序列数据分析的正确格式。

# reading the dataset using read_csvdf = pd.read_csv("stock_data.csv",         parse_dates=True,         index_col="Date")
# displaying the first five rows of datasetdf.head()

输出

          Unnamed: 0   Open   High    Low  Close    Volume  NameDate                                                              2006-01-03         NaN  39.69  41.22  38.79  40.91  24232729  AABA2006-01-04         NaN  41.22  41.90  40.77  40.97  20553479  AABA2006-01-05         NaN  40.93  41.73  40.85  41.53  12829610  AABA2006-01-06         NaN  42.88  43.57  42.80  43.21  29422828  AABA2006-01-09         NaN  43.10  43.66  42.82  43.42  16268338  AABA

删除不需要的列  

我们将从数据集中删除对我们的可视化不重要的列。

# deleting columndf.drop(columns='Unnamed: 0', inplace =True)df.head()

输出

  Open   High    Low  Close    Volume  NameDate                                                  2006-01-03  39.69  41.22  38.79  40.91  24232729  AABA2006-01-04  41.22  41.90  40.77  40.97  20553479  AABA2006-01-05  40.93  41.73  40.85  41.53  12829610  AABA2006-01-06  42.88  43.57  42.80  43.21  29422828  AABA2006-01-09  43.10  43.66  42.82  43.42  16268338  AABA

绘制时间序列数据的线图:

由于体积列属于连续数据类型,我们将使用折线图来将其可视化。

# Assuming df is your DataFramesns.set(style="whitegrid") # Setting the style to whitegrid for a clean background
plt.figure(figsize=(12, 6)) # Setting the figure sizesns.lineplot(data=df, x='Date', y='High', label='High Price', color='blue')
# Adding labels and titleplt.xlabel('Date')plt.ylabel('High')plt.title('Share Highest Price Over Time')
plt.show()

输出:

重采样

为了更好地了解数据的趋势,我们将使用重采样方法,按月对数据进行重采样可以提供更清晰的趋势和模式视图,尤其是在处理每日数据时。

# Assuming df is your DataFrame with a datetime indexdf_resampled = df.resample('M').mean() # Resampling to monthly frequency, using mean as an aggregation function
sns.set(style="whitegrid") # Setting the style to whitegrid for a clean background
# Plotting the 'high' column with seaborn, setting x as the resampled 'Date'plt.figure(figsize=(12, 6)) # Setting the figure sizesns.lineplot(data=df_resampled, x=df_resampled.index, y='High', label='Month Wise Average High Price', color='blue')
# Adding labels and titleplt.xlabel('Date (Monthly)')plt.ylabel('High')plt.title('Monthly Resampling Highest Price Over Time')
plt.show()

输出:

我们观察到重新采样的月度交易量数据呈上升趋势。上升趋势表明,在月度间隔内,“高”列趋于随时间增加。

使用自相关检测季节性

我们将使用自相关函数 (ACF) 图检测季节性。ACF 图中规则间隔的峰值表明存在季节性。

# If 'Date' is a column, but not the index, you can set it as the indexdf.set_index('Date', inplace=True)
# Plot the ACFplt.figure(figsize=(12, 6))plot_acf(df['Volume'], lags=40) # You can adjust the number of lags as neededplt.xlabel('Lag')plt.ylabel('Autocorrelation')plt.title('Autocorrelation Function (ACF) Plot')plt.show()

输出:

ACF 图

季节性的存在通常通过定期的峰值或尖峰来表示,因为我们的数据中没有季节性。

检测平稳性

我们将执行ADF 检验来正式测试平稳性。

该测试基于;

  • 零假设是时间序列中存在单位根,表明该序列是非平稳的。

  • 备择假设是该序列在差分之后是平稳的(即,它没有单位根)。

ADF 检验采用包括序列滞后差异的增强回归模型来确定是否存在单位根。

from statsmodels.tsa.stattools import adfuller
# Assuming df is your DataFrameresult = adfuller(df['High'])print('ADF Statistic:', result[0])print('p-value:', result[1])print('Critical Values:', result[4])

输出

ADF Statistic: 0.7671404880535936p-value: 0.9910868050318213Critical Values: {'1%': -3.4325316347197403, '5%': -2.862503905260741, '10%': -2.5672831121111113}
  • 根据 ADF 统计量 > 所有临界值,因此,我们接受原假设,并得出结论,根据增强迪基-福勒检验,数据似乎不是平稳的。

  • 这表明在应用某些时间序列模型之前可能需要差分或其他转换来实现平稳性。

使用差分和移动平均来平滑数据

差分涉及从当前观察值中减去先前的观察值以消除趋势或季节性。

# Differencingdf['high_diff'] = df['High'].diff()
# Plottingplt.figure(figsize=(12, 6))plt.plot(df['High'], label='Original High', color='blue')plt.plot(df['high_diff'], label='Differenced High', linestyle='--', color='green')plt.legend()plt.title('Original vs Differenced High')plt.show()

输出:

该df['High'].diff()部分计算“高”列中连续值之间的差异。此差分运算通常用于将时间序列转换为表示连续观察值之间变化的新序列。

# Moving Averagewindow_size = 120df['high_smoothed'] = df['High'].rolling(window=window_size).mean()
# Plottingplt.figure(figsize=(12, 6))
plt.plot(df['High'], label='Original High', color='blue')plt.plot(df['high_smoothed'], label=f'Moving Average (Window={window_size})', linestyle='--', color='orange')
plt.xlabel('Date')plt.ylabel('High')plt.title('Original vs Moving Average')plt.legend()plt.show()

输出:

这将计算窗口大小为 120(四分之一)的“High”列的移动平均值,从而在“high_smoothed”系列中创建更平滑的曲线。该图将原始“High”值与平滑版本进行比较。现在让我们使用子图绘制所有其他列。

原始数据与差异数据

将原始数据和差异数据并排打印,我们得到;
# Create a DataFrame with 'high' and 'high_diff' columns side by sidedf_combined = pd.concat([df['High'], df['high_diff']], axis=1)
# Display the combined DataFrameprint(df_combined.head())

输出

 High  high_diffDate                        2006-01-03  41.22        NaN2006-01-04  41.90       0.682006-01-05  41.73      -0.172006-01-06  43.57       1.842006-01-09  43.66       0.09

因此,“high_diff”列表示连续高值之间的差异。“high_diff”的第一个值是 NaN,因为没有先前的值来计算差异。

因为,有一个 NaN 值,我们将删除它以继续我们的测试,

# Remove rows with missing valuesdf.dropna(subset=['high_diff'], inplace=True)df['high_diff'].head()

输出:

Date2006-01-04    0.682006-01-05   -0.172006-01-06    1.842006-01-09    0.092006-01-10   -0.32Name: high_diff, dtype: float64

之后如果我们进行ADF测试;

from statsmodels.tsa.stattools import adfuller
# Assuming df is your DataFrameresult = adfuller(df['high_diff'])print('ADF Statistic:', result[0])print('p-value:', result[1])print('Critical Values:', result[4])

输出;

ADF Statistic: -12.148367478343204p-value: 1.5912766134152125e-22Critical Values: {'1%': -3.4325316347197403, '5%': -2.862503905260741, '10%': -2.5672831121111113}
  • 根据 ADF 统计量,即小于所有临界值,因此,我们拒绝原假设,并得出结论:我们有足够的证据拒绝原假设。根据增强 Dickey-Fuller 检验,数据似乎是平稳的。

  • 这表明在应用某些时间序列模型之前可能需要差分或其他转换来实现平稳性。

    国庆节要到了买个国旗贴纸贴在车上

python、matlab程序设计找我

—  —


进修编程
提升编程技能,学习编程技巧