介绍
时间序列分析属于统计学的一个分支,涉及对有序的、通常是时间的数据的研究。 当相关应用时,时间序列分析可以揭示意想不到的趋势,提取有用的统计数据,甚至预测未来的趋势。 由于这些原因,它被应用于许多领域,包括经济学、天气预报和容量规划等。
在本教程中,我们将介绍一些用于时间序列分析的常用技术,并介绍操作、可视化时间序列数据所需的迭代步骤。
先决条件
本指南将介绍如何在本地桌面或远程服务器上进行时间序列分析。 处理大型数据集可能会占用大量内存,因此无论哪种情况,计算机都需要至少 2GB 内存 来执行本指南中的一些计算。
在本教程中,我们将使用 Jupyter Notebook 来处理数据。 如果您还没有它,您应该按照我们的 教程安装和设置适用于 Python 3 的 Jupyter Notebook。
第 1 步 — 安装软件包
我们将利用 pandas
库和 statsmodels
库,它在处理数据时提供了很大的灵活性,它允许我们在 Python 中执行统计计算。 这两个库一起使用,可以扩展 Python 以提供更强大的功能并显着增加我们的分析工具包。
与其他 Python 包一样,我们可以使用 pip
安装 pandas
和 statsmodels
。 首先,让我们进入我们的本地编程环境或基于服务器的编程环境:
cd environments
. my_env/bin/activate
从这里,让我们为我们的项目创建一个新目录。 我们将它命名为timeseries
,然后进入目录。 如果您给项目起一个不同的名称,请务必在整个指南中用您的名称替换 timeseries
mkdir timeseries cd timeseries
我们现在可以安装 pandas
、statsmodels
和数据绘图包 matplotlib。 它们的依赖项也将被安装:
pip install pandas statsmodels matplotlib
至此,我们现在已设置好开始使用 pandas
和 statsmodels
。
第 2 步 - 加载时间序列数据
要开始处理我们的数据,我们将启动 Jupyter Notebook:
jupyter notebook
要创建新的笔记本文件,请从右上角的下拉菜单中选择 New > Python 3:
这将打开一个笔记本,允许我们加载所需的库(注意用于引用 pandas
、matplotlib
和 statsmodels
的标准简写)。 在我们的笔记本顶部,我们应该写下以下内容:
import pandas as pd import statsmodels.api as sm import matplotlib.pyplot as plt
在本教程中的每个代码块之后,您应该键入 ALT + ENTER
以运行代码并移动到笔记本中的新代码块。
方便的是,statsmodels
带有内置数据集,因此我们可以将时间序列数据集直接加载到内存中。
我们将使用一个名为“来自美国夏威夷莫纳罗亚天文台连续空气样本的大气二氧化碳”的数据集,该数据集收集了 1958 年 3 月至 2001 年 12 月的二氧化碳样本。 我们可以按如下方式引入这些数据:
data = sm.datasets.co2.load_pandas() co2 = data.data
让我们检查一下时间序列数据的前 5 行:
print(co2.head(5))
Output co2 1958-03-29 316.1 1958-04-05 317.3 1958-04-12 317.6 1958-04-19 317.5 1958-04-26 316.4
随着我们的包导入和 CO2 数据集准备就绪,我们可以继续索引我们的数据。
第 3 步 — 使用时间序列数据进行索引
您可能已经注意到日期已设置为我们的 pandas
DataFrame 的索引。 在 Python 中处理时间序列数据时,我们应该确保将日期用作索引,因此请确保始终检查这一点,我们可以通过运行以下命令来做到这一点:
co2.index
OutputDatetimeIndex(['1958-03-29', '1958-04-05', '1958-04-12', '1958-04-19', '1958-04-26', '1958-05-03', '1958-05-10', '1958-05-17', '1958-05-24', '1958-05-31', ... '2001-10-27', '2001-11-03', '2001-11-10', '2001-11-17', '2001-11-24', '2001-12-01', '2001-12-08', '2001-12-15', '2001-12-22', '2001-12-29'], dtype='datetime64[ns]', length=2284, freq='W-SAT')
dtype=datetime[ns]
字段确认我们的索引是由日期戳对象组成的,而 length=2284
和 freq='W-SAT'
告诉我们从星期六开始每周有 2,284 个日期戳。
每周数据可能很难处理,所以让我们使用时间序列的月平均值来代替。 这可以通过使用方便的 resample
函数来获得,它允许我们将时间序列分组为桶(1 个月),在每个组(平均值)上应用 函数,并结合结果(每组一行)。
y = co2['co2'].resample('MS').mean()
在这里,术语 MS
意味着我们将桶中的数据按月分组,并确保我们使用每个月的开始作为时间戳:
y.head(5)
Output1958-03-01 316.100 1958-04-01 317.200 1958-05-01 317.120 1958-06-01 315.800 1958-07-01 315.625 Freq: MS, Name: co2, dtype: float64
pandas
的一个有趣特性是它能够处理日期戳索引,这使我们能够快速对数据进行切片。 例如,我们可以对数据集进行切片以仅检索 1990
年之后的数据点:
y['1990':]
Output1990-01-01 353.650 1990-02-01 354.650 ... 2001-11-01 369.375 2001-12-01 371.020 Freq: MS, Name: co2, dtype: float64
或者,我们可以对数据集进行切片以仅检索 10 月 1995
和 10 月 1996
之间的数据点:
y['1995-10-01':'1996-10-01']
Output1995-10-01 357.850 1995-11-01 359.475 1995-12-01 360.700 1996-01-01 362.025 1996-02-01 363.175 1996-03-01 364.060 1996-04-01 364.700 1996-05-01 365.325 1996-06-01 364.880 1996-07-01 363.475 1996-08-01 361.320 1996-09-01 359.400 1996-10-01 359.625 Freq: MS, Name: co2, dtype: float64
通过正确索引我们的数据以处理时间数据,我们可以继续处理可能丢失的值。
第 4 步 - 处理时间序列数据中的缺失值
现实世界的数据往往是混乱的。 从图中我们可以看出,时间序列数据包含缺失值的情况并不少见。 检查这些的最简单方法是直接绘制数据或使用以下命令显示输出中丢失的数据:
y.isnull().sum()
Output5
此输出告诉我们,我们的时间序列中有 5 个月的缺失值。
一般来说,如果缺失值不是太多,我们应该“填充”缺失值,这样我们就不会在数据中出现空白。 我们可以使用 fillna() 命令 在 pandas
中执行此操作。 为简单起见,我们可以用时间序列中最接近的非空值填充缺失值,尽管重要的是要注意滚动平均值有时更可取。
y = y.fillna(y.bfill())
填写缺失值后,我们可以再次检查是否存在任何空值,以确保我们的操作有效:
y.isnull().sum()
Output0
执行这些操作后,我们看到我们已经成功填充了时间序列中的所有缺失值。
第 5 步 - 可视化时间序列数据
在处理时间序列数据时,可以通过可视化来揭示很多东西。 需要注意的几点是:
- 季节性:数据是否显示出明显的周期性模式?
- 趋势:数据是否遵循一致的向上或向下倾斜?
- noise:是否存在与其余数据不一致的异常点或缺失值?
我们可以使用 matplotlib
API 周围的 pandas
包装器来显示我们数据集的绘图:
y.plot(figsize=(15, 6)) plt.show()
当我们绘制数据时,会出现一些可区分的模式。 时间序列具有明显的季节性规律,整体呈上升趋势。 我们还可以使用一种称为时间序列分解的方法来可视化我们的数据。 顾名思义,时间序列分解允许我们将时间序列分解为三个不同的组成部分:趋势、季节性和噪声。
幸运的是,statsmodels
提供了方便的 seasonal_decompose
函数来执行开箱即用的季节性分解。 如果您有兴趣了解更多信息,可以在以下论文“STL: A Seasonal-Trend Decomposition Procedure Based on Loess”中找到其原始实现的参考。
下面的脚本展示了如何在 Python 中执行时间序列季节性分解。 默认情况下,seasonal_decompose
返回一个相对较小的图形,因此该代码块的前两行确保输出图形足够大,以便我们可视化。
from pylab import rcParams rcParams['figure.figsize'] = 11, 9 decomposition = sm.tsa.seasonal_decompose(y, model='additive') fig = decomposition.plot() plt.show()
使用时间序列分解可以更轻松地快速识别数据中不断变化的均值或变化。 上图清楚地显示了我们数据的上升趋势,以及它的年度季节性。 这些可以用来理解我们时间序列的结构。 时间序列分解背后的直觉很重要,因为许多预测方法都建立在结构化分解的概念之上来产生预测。
结论
如果您已按照本指南进行操作,那么您现在已经具备了在 Python 中可视化和操作时间序列数据的经验。
为了进一步提高您的技能,您可以加载另一个数据集并重复本教程中的所有步骤。 例如,您可能希望使用 pandas
库读取 CSV 文件或使用 statsmodels
库预加载的 sunspots
数据集:[X156X ]。