时间序列数据的自相关

导航到

时间序列,顾名思义,是一系列按时间顺序排列的数据点。通常情况下,时间序列用于追踪某些事物在短期和长期内的变化——股票价格或其他商品的变动是典型的例子。无论如何,你都在密切关注某个事物随时间在固定时间间隔内的变化——这在尝试利用过去预测未来时非常重要。

为什么时间序列分析很重要

例如,如果你能确切地看到某只证券的价格随时间的变化,那么你可以对未来的同一时间段内价格可能发生的变化做出更加明智的猜测。这可以导致更好的、更明智的决策,这也是为什么时间序列分析对许多行业来说如此重要的原因。

为什么时间序列数据是独特的

时间序列是一系列按时间索引的数据点。由于时间序列数据是有序的,这使得它在数据空间中具有独特性,因为它通常显示出序列相关性。序列相关性发生在某个时间点的数据值在统计上依赖于另一个时间点的另一个数据值。然而,时间序列数据的这一属性违反了许多统计分析的基本假设之一——即数据是统计独立的。

时间序列中的自相关是什么?

自相关这个术语指的是A)给定时间序列与B)其滞后版本之间的相似程度,在C)连续的时间间隔内。换句话说,自相关旨在衡量变量的当前值与您可能拥有的任何过去值之间的关系。

因此,时间序列自相关试图衡量变量的当前值与该变量的历史数据之间的关系。它最终在一条序列上绘制另一条序列,并确定两者之间的相似程度。

为了比较,自相关本质上与您自己计算两个不同时间序列值集之间的相关性的过程完全相同。这里的主要区别在于,自相关两次使用同一时间序列:一次是其原始值,然后在几个不同的时间段之后再次使用。

自相关也称为序列相关、时间序列相关和滞后相关。无论其使用方式如何,自相关都是揭示时间序列数据中趋势和模式的理想方法,这些趋势和模式在其他情况下可能无法被发现。

自相关示例

需要注意的是,时间序列数据中的自相关并不是所有领域都以完全相同的方式使用这种技术。它是极具灵活性的——这意味着将数据与其延迟副本进行比较的简单原则在广泛的各种环境中同样有价值。同样,时间序列在不同领域的应用也不尽相同——这意味着它们使用一个简单的过程来达到完全不同的结果。

示例 1:回归分析

自相关通常被广泛使用的突出例子是以时间序列数据进行的回归分析。在这里,专业人士通常会使用标准的自回归模型、移动平均模型,或者称为自回归积分移动平均模型(简称ARIMA)的组合。

示例 2:自相关的科学应用

自相关在荧光相关光谱学中也得到了相当广泛的应用,这是理解某些科学环境中分子级扩散和化学反应的关键部分。

示例 3:全球定位系统

自相关也是智能手机或其他移动设备中嵌入的GPS芯片核心数学技术之一。在这里,自相关用于校正传播延迟——即在载波信号传输和最终被相关GPS设备接收到之前发生的时间偏移。这就是GPS总是知道您所在位置,并在您到达该精确位置之前告诉您何时何地转弯的原因。

示例4:信号处理

自相关也是信号处理中非常重要的技术,信号处理是电气工程的一部分,专注于更深入地了解(甚至修改或合成)声音、图像以及有时是科学测量等信号。在这种情况下,自相关可以帮助人们更好地理解音乐节奏等重复事件——这对确定歌曲的正确节奏非常重要。许多人还用它来估计音乐音调中的非常特定的音高。

示例5:天体物理学

天体物理学是天文学的一个分支,它将物理学和化学的已知原理结合起来,以帮助我们更好地理解外太空物体的性质,而不是仅仅满足于知道它们的相对位置或它们的运动方式。这也是自相关被使用的另一个重要方式,因为它帮助专业人士研究宇宙中天体(如星系)之间的空间分布。在多波长观测低质量X射线双星时,它也可以很有帮助。

为什么自相关很重要

通常,数据分析的第一步之一是进行回归分析。然而,回归分析的一个假设是数据没有自相关。这可能令人沮丧,因为如果您尝试对具有自相关的数据进行回归分析,那么您的分析将是误导性的。

此外,一些时间序列预测方法(特别是回归建模)依赖于残差(拟合模型与数据之间的差异)没有自相关的假设。人们通常使用残差来评估他们的模型是否合适,而忽略了残差没有自相关的假设(或者错误是独立同分布的,或)。这种错误会导致人们相信他们的模型是合适的,而实际上并不是。我强烈建议阅读这篇文章如何(不)使用机器学习进行时间序列预测:避免陷阱,作者在该文章中展示了日益流行的LSTM(长短期记忆)网络如何看似是一个优秀的一元时间序列预测器,而实际上只是对数据进行过度拟合。他进一步解释说,这种误解是由于自相关的存在导致准确度指标失败。

最后,自相关分析最具说服力的方面可能是它如何帮助我们揭示数据中的隐藏模式,并帮助我们选择正确的预测方法。具体来说,我们可以用它来帮助我们识别时间序列数据中的季节性和趋势。此外,分析自相关函数(ACF)和偏自相关函数(PACF)是选择适当的ARIMA模型进行时间序列预测所必需的。

自相关测试

时间序列数据中可能存在的任何自相关都通过自相关图(也称为ACF图)来确定。这有助于你确定你的数字序列是否存在自相关,然后你可以更好地理解序列中值可能预测的规律。

最常用的自相关测试称为Durbin-Watson测试,以James Durbin和Geoffrey Watson的名字命名,并在20世纪50年代初提出。

自相关统计和测试

也常被称为Durbin-Watson统计量,此测试用于检测回归分析中发现的任何预测误差中是否存在滞后为1的自相关。此测试的精确计算方法可以在此处找到

一旦你成功地将数字输入Durbin-Watson测试,它会报告一个0到4的值。如果返回的值是2,那么你的时间序列中就没有自相关。如果值在0到2之间,你看到的是所谓的正自相关 - 这在时间序列数据中非常常见。如果值在2到4之间,这意味着存在负相关——在时间序列数据中较少见,但在某些情况下确实会发生。

如何确定你的时间序列数据是否存在自相关

在这个练习中,我使用InfluxDB和InfluxDB Python客户端。我使用来自美国国家海洋和大气管理局(NOAA)操作海洋产品和服务中心的可用数据。具体来说,我将查看圣莫尼卡一条河流的水位和水温。

数据集

curl https://s3.amazonaws.com/noaa.water-database/NOAA_data.txt -o NOAA_data.txt
influx -import -path=NOAA_data.txt -precision=s -database=NOAA_water_database

此分析和代码包含在此仓库中的jupyter笔记本中。

首先,我导入所有依赖项。

import pandas as pd
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from influxdb import InfluxDBClient
from statsmodels.graphics.tsaplots import plot_pacf
from statsmodels.graphics.tsaplots import plot_acf
from scipy.stats import linregress

接下来,我连接到客户端,查询我的水温数据,并将其绘制出来。

client = InfluxDBClient(host='localhost', port=8086)
h2O = client.query('SELECT mean("degrees") AS "h2O_temp" FROM "NOAA_water_database"."autogen"."h2o_temperature"  GROUP BY time(12h) LIMIT 60')
h2O_points = [p for p in h2O.get_points()]
h2O_df = pd.DataFrame(h2O_points)
h2O_df['time_step'] = range(0,len(h2O_df['time']))
h2O_df.plot(kind='line',x='time_step',y='h2O_temp')
plt.show()

Fig 1. H2O temperature vs. timestep - autocorrelation in time series data

图1. H2O温度与时间步长的关系

从上面的图表来看,我们数据是否存在自相关并不明显。例如,我无法检测到季节性存在,这将导致高自相关。

我可以使用Pandas.Series.autocorr()函数计算自相关,该函数返回皮尔逊相关系数的值。皮尔逊相关系数是衡量两个变量之间线性相关程度的指标。皮尔逊相关系数的值介于-1和1之间,其中0表示没有线性相关,>0表示正相关,<0表示负相关。正相关是指两个变量同时变化,而负相关系数表示变量成反比变化。我将数据与滞后=1(或data(t)与data(t-1))和滞后=2(或data(t)与data(t-2))进行比较。

shift_1 = h2O_df['h2O_temp'].autocorr(lag=1)
print(shift_1)
-0.07205847740103073
0.17849760131784975

这些值非常接近0,这表明几乎没有相关性。然而,计算单个自相关值可能无法说明整个情况。在滞后=1时可能没有相关性,但在滞后=15时可能存在相关性。制作一个自相关图来比较自相关函数(AFC)在不同滞后大小下的值是个好主意。还要注意,随着滞后值的增加,AFC的可靠性会降低。这是因为随着滞后值的增加,你将比较的观测值越来越少。一个一般的指导原则是,总观测数(T)应至少为50,最大的滞后值(k)应小于或等于T/k。由于我总共有60个观测值,我将只考虑AFC的前20个值。

plot_acf(h2O_df['h2O_temp'], lags=20)
plt.show()

Fig 2. Autocorrelation plot for H2O temperatures

图2. H2O温度的自相关图

从这张图中,我们看到ACF的值在滞后>0时位于95%置信区间(用实线灰色线表示)内,这验证了我们的数据没有自相关性。起初,我发现这个结果令人惊讶,因为通常一天中的气温与前一天的温度高度相关。我假设水温也会如此。这个结果让我想起河流和空气没有相同的系统行为。我不是水文地质学家,但我知道 springs 或融雪通常一年四季都是相同的温度。也许它们表现出日复一日的稳定温度轮廓,其中平均值、方差和自相关都是恒定的(其中自相关=0)。

在时间序列数据中用自相关揭示季节性

ACF还可以用来揭示和验证时间序列数据中的季节性。让我们看看同一数据集中的水位。

client = InfluxDBClient(host='localhost', port=8086)
h2O_level = client.query('SELECT "water_level" FROM "NOAA_water_database"."autogen"."h2o_feet" WHERE "location"=\'santa_monica\' AND time >= \'2015-08-22 22:12:00\' AND time <= \'2015-08-28 03:00:00\'')
h2O_level_points = [p for p in h2O_level.get_points()]
h2O_level_df = pd.DataFrame(h2O_level_points)
h2O_level_df['time_step'] = range(0,len(h2O_level_df['time']))
h2O_level_df.plot(kind='line',x='time_step',y='water_level')
plt.show()

Fig 3. H2O level vs. timestep - autocorrelation in time series data

图3. H2O水位与时间步长的关系

仅通过绘图,就可以很明显地看出数据中可能存在季节性,这是由数据中的可预测模式所证明的。让我们通过绘制ACF来验证这个假设。

plot_acf(h2O_level_df['water_level'], lags=400)
plt.show()

Autocorrelation plot for H2O levels

图4:H2O水平的自相关图

从上面的ACF图中,我们可以看到我们的季节性周期大约由246个时间步组成(ACF有第二个最大的正峰值)。虽然从图3中绘制时间序列很容易看出水位数据具有季节性,但这种情况并不总是如此。在《使用Python进行季节性ARIMA》中,作者Sean Abu展示了他是如何必须在他的ARIMA方法中添加季节性成分来解释数据集中的季节性的。我欣赏他的数据集选择,因为我无法在以下图中检测到任何自相关性。这是一个很好的例子,说明了如何使用ACF来揭示数据中的隐藏趋势。

Monthly Ridership vs. Year. Source: Seasonal ARIMA with Python

图5:月乘客量与年份的关系。来源:《使用Python进行季节性ARIMA》

在时间序列数据中用自相关考察趋势

为了查看时间序列数据的趋势,我们首先需要去除季节性。滞后差分是一种简单的转换方法,可以用来去除序列的季节性成分。滞后差分定义为

difference(t) = observation(t) - observation(t-interval)2,

其中interval是周期。为了计算水位数据的滞后差分,我使用了以下函数

def difference(dataset, interval):
    diff = list()
    for i in range(interval, len(dataset)):
        value = dataset[i] - dataset[i - interval]
        diff.append(value)
    return pd.DataFrame(diff, columns = ["water_level_diff"])
h2O_level_diff = difference(h2O_level_df['water_level'], 246)
h2O_level_diff['time_step'] = range(0,len(h2O_level_diff['water_level_diff']))
h2O_level_diff.plot(kind='line',x='time_step',y='water_level_diff')
plt.show()

Lagged difference for H2O levels - autocorrelation in time series data

图6:H2O水平的滞后差分

我们现在可以再次绘制ACF。

plot_acf(h2O_level_diff['water_level_diff'], lags=300)
plt.show()

ACF of lagged difference for H2O levels - autocorrelation in time series data

图7:H2O水平滞后差分的ACF

这似乎表明我们滞后差分中仍然存在季节性。然而,如果我们关注图5的y轴,我们可以看到范围非常小,所有数值都接近0。这告诉我们我们成功地去除了季节性,但存在多项式趋势。我使用了seasonal_decompose来验证这一点。

from statsmodels.tsa.seasonal import seasonal_decompose
from matplotlib import pyplot
result = seasonal_decompose(h2O['water_level'], model='additive', freq=250)
result.plot()
pyplot.show()

Seasonal Decomposition of H2O levels

图8. H2O水平的季节分解

结论

自相关很重要,因为它可以帮助我们揭示数据中的模式,成功选择最佳预测模型,正确评估我们模型的有效性。希望这篇关于自相关的介绍对您有所帮助。如果您有任何问题,请在工作社区网站上发布或给我们发推文@InfluxDB。一如既往,这里有一个小休息时间

参考文献

  1. 《通过实例学习时间序列分析和预测》,Søren Bisgaard和Murat Kulachi
  2. 如何在Python中使用差分变换去除趋势和季节性

资源

  1. 使用Python进行季节性ARIMA时间序列预测
  2. Python中的时间序列(第二部分):处理季节性数据
  3. 如何将时间序列数据分解为趋势和季节性
  4. 如何(或不)使用机器学习进行时间序列预测:避免陷阱
  5. 自相关和偏自相关的温和介绍
  6. 时间序列概念
  7. 平稳性
  8. 使用Python进行波士顿月度抢劫案时间序列预测案例分析
  9. 如何在Python中为时间序列预测创建ARIMA模型
  10. 解释部分自相关函数(PACF)
  11. 线性回归的假设