时间序列之间的相关性检测

article/2025/9/28 1:11:53

为了检测时间序列的相关性,我们经常使用自相关,互相关或归一化互相关。

互相关(Cross-Correlation)

互相关是两个不同时间序列的比较,以检测具有相同最大值和最小值的指标之间是否存在相关性。例如:“两个音频信号同相吗?”

为了检测两个信号之间的相关程度,我们使用互相关。 只需将两个时间序列相乘和相加即可计算得出。

在以下示例中,序列A和B是互相关的,但序列C都不与此相关。

cross-correlation

a = [1, 2, -2, 4, 2, 3, 1, 0]
b = [2, 3, -2, 3, 2, 4, 1, -1]
c = [-2, 0, 4, 0, 1, 1, 0, -2]pyplot.figure()
pyplot.title("Series")
pyplot.plot(range(len(a)), a, color="#f44e2e", label="a")
pyplot.plot(range(len(b)), b, color="#27ccc0", label="b")
pyplot.plot(range(len(c)), c, color="#273ecc", label="c")
pyplot.ylabel("value")
pyplot.xlabel("index")
pyplot.show()

c r o s s _ c o r r ( x , y ) = ∑ i = 0 n − 1 x i ∗ y i cross\_corr(x, y) = \sum_{i=0}^{n-1} x_i*y_i cross_corr(x,y)=i=0n1xiyi

使用上面的互相关公式,我们可以计算序列之间的相关度。

import numpy as np
def cross_corr(set1, set2):return np.sum(set1 * set2)a = np.array([1, 2, -2, 4, 2, 3, 1, 0])
b = np.array([2, 3, -2, 3, 2, 4, 1, -1])
c = np.array([-2, 0, 4, 0, 1, 1, 0, -2])print(f"Cross Correlation a,b: {cross_corr(a, b)}")
print(f"Cross Correlation a,c: {cross_corr(a, c)}")
print(f"Cross Correlation b,c: {cross_corr(b, c)}")OUTPUT:
Cross Correlation a,b: 41
Cross Correlation a,c: -5
Cross Correlation b,c: -4

序列a和b互相关性较大,值为41。序列a和c,a和b相关性较小,值分别为:-5,-4.

标准化的互相关(Normalized Cross-Correlation)

标准化的互相关也是用于两个时间序列的比较,但是使用了不同的评分结果。除了简单的互相关,它还可以比较具有不同值范围的指标。例如:“商店中的顾客数量与每天的销售数量之间是否存在相关性?”

使用互相关值评价相关性存在三个问题:

  1. 互相关的评分值难以理解。
  2. 两个序列必须具有相同的幅度。如如果一个序列值缩小了一半,那么他的相关性会减少。 c r o s s _ c o r r ( a , a / 2 ) = 19.5 cross\_corr(a,a/2)=19.5 cross_corr(a,a/2)=19.5
  3. 无法解决序列值为0的问题,根据互相关公式,由于 0 ∗ 0 = 0 0*0=0 00=0 0 ∗ 200 = 0 0*200=0 0200=0,因此无法解决0值。

为了解决这些问题,使用标准化的互相关

n o r m _ c o r r ( x , y ) = ∑ n = 0 n − 1 x i ∗ y i ∑ n = 0 n − 1 x i 2 ∗ ∑ n = 0 n − 1 y i 2 norm\_corr(x,y)=\dfrac{\sum_{n=0}^{n-1} x_i*y_i}{\sqrt{\sum_{n=0}^{n-1} x_i^2 * \sum_{n=0}^{n-1} y_i^2}} norm_corr(x,y)=n=0n1xi2n=0n1yi2 n=0n1xiyi

计算上边a,b,c序列的标准化的相关性如下:

import numpy as np
def norm_cross_corr(set1, set2):# python中求Normalized Cross Correlation的函数是: statsmodels.tsa.stattools.ccfreturn np.sum(set1 * set2) / (np.linalg.norm(set1) * np.linalg.norm(set2))a = np.array([1, 2, -2, 4, 2, 3, 1, 0])
b = np.array([2, 3, -2, 3, 2, 4, 1, -1])
c = np.array([-2, 0, 4, 0, 1, 1, 0, -2])print(f"Normalized Cross Correlation a,b: {norm_cross_corr(a, b)}")
print(f"Normalized Cross Correlation a,c: {norm_cross_corr(a, c)}")
print(f"Normalized Cross Correlation b,c: {norm_cross_corr(b, c)}")OUTPUT:
Normalized Cross Correlation a,b: 0.9476128352180998
Normalized Cross Correlation a,c: -0.15701857325533194
Normalized Cross Correlation b,c: -0.11322770341445959

标准化的互相关值很容易理解:

  1. 值越高,相关性越高。
  2. 当两个信号完全相同时,最大值为1: n o r m _ c r o s s _ c o r r ( a , a ) = 1 norm\_cross\_corr(a,a)=1 norm_cross_corr(a,a)=1
  3. 当两个信号完全相反时,最小值为-1: n o r m _ c r o s s _ c o r r ( a , − a ) = − 1 norm\_cross\_corr(a,-a)=-1 norm_cross_corr(a,a)=1

标准化的互相关可以检测两个幅度不同的信号的相关性,如: n o r m _ c r o s s _ c o r r ( a , a / 2 ) = 1 norm\_cross\_corr(a,a/2)=1 norm_cross_corr(a,a/2)=1。信号A和具有一半振幅的同一信号之间具有最高的相关性!

自相关(Auto-Correlation)

自相关是时间序列在不同时间与其自身的比较。例如,其目的是检测重复模式或季节性。例如:“服务器网站上是否有每周的季节性?”“本周的数据与前一周的数据高度相关吗?”

自相关的用途非常广泛,其中之一就是检测由于季节性导致的可重复的模式。

下图展示了具有季节性为8的序列:

image

import numpy as np
np.random.seed(10)
a = np.tile(np.array(range(8)), 8) + np.random.normal(loc=0.0, scale=0.5, size=64)
pyplot.figure(figsize=(12, 4))
pyplot.title("Series")
pyplot.plot(range(len(a)), a, color="#f44e2e", label="a")
pyplot.ylabel("value")
pyplot.xlabel("index")
pyplot.legend(loc="upper right")
pyplot.show()

图像由如上代码生成,他是1~8的可重复序列,并且夹杂了一些随机噪声。

接下来计算时间偏移为4和时间偏移为8时信号与自身之间的自相关。
image

import numpy as np
np.random.seed(10)
a = np.tile(np.array(range(8)), 8) + np.random.normal(loc=0.0, scale=0.5, size=64)ar4 = a[:len(a) - 4]
ar4_shift = a[4:]
print(f"Auto Correlation with shift 4: {cross_correlation(ar4, ar4_shift)}")pyplot.figure(figsize=(12, 4))
pyplot.title("Series")
pyplot.plot(range(len(ar4)), ar4, color="blue", label="ar4")
pyplot.plot(range(len(ar4_shift)), ar4_shift, color="green", label="ar4_shift")
pyplot.ylabel("value")
pyplot.xlabel("index")
pyplot.legend(loc="upper right")
pyplot.show()OUTPUT:
Auto Correlation with shift 4: 623.797612892277

image

import numpy as np
np.random.seed(10)
a = np.tile(np.array(range(8)), 8) + np.random.normal(loc=0.0, scale=0.5, size=64)ar8 = a[:len(a) - 8]
ar8_shift = a[8:]
print(f"Auto Correlation with shift 4: {cross_correlation(ar8, ar8_shift)}")pyplot.figure(figsize=(12, 4))
pyplot.title("Series")
pyplot.plot(range(len(ar4)), ar4, color="blue", label="ar4")
pyplot.plot(range(len(ar4_shift)), ar4_shift, color="green", label="ar4_shift")
pyplot.ylabel("value")
pyplot.xlabel("index")
pyplot.legend(loc="upper right")
pyplot.show()OUTPUT:
Auto Correlation with shift 8: 996.8417240253186

上图清楚地显示了时间偏移8处的高自相关,而时间偏移4处没有。计算出的自相关值可以看到shift为8时的自相关值大于shift为4时的值。所以相比于4,我们觉得季节性更可能为8。

标准化的自相关(Normalized Auto-Correlation)

如前所述,用标准化的互相关可以更好地表达两个序列的相关性

print(f"Auto Correlation with shift 4: {norm_cross_correlation(ar4, ar4_shift)}")
print(f"Auto Correlation with shift 8: {norm_cross_correlation(ar8, ar8_shift)}")OUTPUT:
Auto Correlation with shift 4: 0.5779124931215941
Auto Correlation with shift 8: 0.9874907451139486

相关性与时移(Correlation with Time Shift)

标准化的互相关与时移(Normalized Cross-Correlation with Time Shift)

时移可以应用于所有上述算法。想法是将指标与具有不同“时间偏移”的另一个指标进行比较。将时间偏移应用于归一化互相关函数将导致“具有X的时间偏移的归一化互相关”。这可以用来回答以下问题:“当许多顾客进我的商店时,我的销售额在20分钟后会增加吗?”

为了处理时移,我们将原始信号与由x元素向右或向左移动的另一个信号关联。就像我们为自相关所做的一样。

为了检测两个指标是否与时移相关,我们需要计算所有可能的时移。

image

image

from statsmodels.tsa.stattools import ccf
a = np.array([0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4])
b = np.array([1, 2, 3, 3, 0, 1, 2, 3, 4, 0, 1, 1, 4, 4, 0, 1, 2, 3, 4, 0])
res_ary = ccf(a, b, unbiased=False)  # 计算各种time shift下的互相关值print(res_ary)pyplot.bar(range(len(res_ary)), res_ary, fc="blue")
pyplot.show()OUTPUT:
[-3.29180823e-17  8.67261700e-01  1.27247799e-01 -4.65751654e-01-3.92862138e-01 -1.09726941e-17  6.20178595e-01  1.27247799e-01-2.92793480e-01 -2.94028896e-01 -2.47083106e-02  3.48387179e-011.02539489e-01 -1.19835306e-01 -1.70487343e-01 -2.47083106e-021.01304073e-01  5.31228677e-02 -2.10020640e-02 -4.69457901e-02]

从上图以及数据可以看出,当time shift为1时,序列a和b高度相关。

标准化的自相关与时移(Normalized Auto-Correlation with Time Shift)

image

image

from statsmodels.tsa.stattools import acfnp.random.seed(5)
a = np.tile(np.array(range(8)), 8) + np.random.normal(loc=0.0, scale=0.5, size=64)
res_ary = acf(a, nlags=30, fft=False)
print(res_ary)
pyplot.bar(range(len(res_ary)), res_ary, fc="blue")
pyplot.show()OUTPUT:
[ 1.          0.33436187 -0.06325233 -0.39112367 -0.46168766 -0.43537856-0.15175395  0.24403119  0.86075234  0.31051923 -0.03270547 -0.32083613-0.40031665 -0.38383002 -0.14645852  0.20649692  0.72864895  0.2693097-0.01707009 -0.2658133  -0.3339456  -0.32771517 -0.1214095   0.170080130.60740024  0.22492556 -0.01633838 -0.21157885 -0.27896827 -0.27765971-0.10762048]

原始序列是有8的季节性,自相关检测也看到了在8的整数倍的偏移处得到了较高的自相关值。

将相关指标聚类(Cluster Correlated Metrics Together)

我们可以用Normalized Cross Correlation,根据相似度将相关性较大的metric聚类。

使用数据集:graphs45.csv

import numpy as np
import pandas as pddef get_correlation_table(metric_df):metric_cnt = metric_df.shape[1]correlation_table = np.zeros((metric_cnt, metric_cnt))for i in range(metric_cnt):metric_1 = metric_df.iloc[:, i]for j in range(metric_cnt):if i == j:continueelse:metric_2 = metric_df.iloc[:, j]cc_ary = ccf(metric_1, metric_2, unbiased=False)correlation_table[i, j] = cc_ary[0]return correlation_tabledef find_related_metric(correlation_table, orig, high_corr):metric_corr_table = correlation_table[orig]corr_metric_lst = []for i in range(len(metric_corr_table)):if metric_corr_table[i] > high_corr:corr_metric_lst.append(i)return corr_metric_lstif __mian__:metric_df = pd.read_csv("./graphs45.csv")correlation_table_ary = get_correlation_table(metric_df)orig = 3high_corr = 0.9corr_metric_lst = find_related_metric(correlation_table_ary, orig, high_corr)corr_metric_lst.append(orig)print(corr_metric_lst)pyplot.figure()pyplot.title("Series")for idx in corr_metric_lst:metric = metric_df.iloc[:, idx]pyplot.plot(range(len(metric)), metric, label=f"graph_{idx + 1}")pyplot.ylabel("value")pyplot.xlabel("index")pyplot.legend(loc="upper right")pyplot.show()

get_correlation_table()计算了所有metric之间的标准化的互相关值,结果存在correlation_table中,correlation_table[i,j]代表第i个metric和第j个metric之间的相关值。

然后find_related_metric()根据相关值表找出和graph_4相关值大于0.9的序列,最后找出的相关序列画图如下:

image

参考

  1. Understanding Cross-Correlation, Auto-Correlation, Normalization and Time Shift
  2. Detecting Correlation Among Multiple Time Series

http://chatgpt.dhexx.cn/article/n6JojMLe.shtml

相关文章

python实现pearson相关性检验

python实现pearson相关性检验 两个变量之间的相关性可以采用Pearson或Spearman相关分析方法进行分析。Pearson相关分析主要用来分析正态分布、非等间距测度的连续变量,而Spearman可用来分析不服从双变量正态分布或总体分布型未知以及原始数据是等级资料的数据。 测试两个样本是…

数据特征分析技能—— 相关性检验

数据特征分析技能—— 相关性检验 相关性分析是指对两个或多个具备相关性的变量元素进行分析,从而衡量两个变量因素的相关密切程度 一般常用四种方法: - 画图判断 - pearson(皮尔逊)相关系数 - sperman(斯皮尔曼&a…

【相关性检验】

两个变量之间的相关性检验 1、皮尔森相关系数:它们之间的协方差cov(X,Y)除以它们各自标准差的乘积(σX, σY)。 要判断两个变量之间是否存在相关性:可以采用画散点图的方式,进行直观性的分析。使用python进行person检验 import pandas as p…

数学建模竞赛知识点汇总(四)——相关性检验

数学建模竞赛知识点汇总(四)——相关性检验 文章目录 数学建模竞赛知识点汇总(四)——相关性检验简介皮尔逊相关系数总体person相关系数样本person相关系数皮尔逊相关系数假设检验前提步骤流程 斯皮尔曼相关系数皮尔逊相关系数与斯…

scanf函数使用方法详解

scanf函数使用方法详解 一.scanf函数是什么?二.scanf函数的作用三.注意事项1.输入数据2.%c 四.字段宽度五.scanf函数的返回值 一.scanf函数是什么? 1.首先我们需要知道,scanf函数是一种格式化输入函数(按照格式字符串的格式&…

scanf与scanf_s函数的使用 详解

1.scanf_s(是vs提供的函数) a.代码1 int main() {char a 0;//scanf_s("%c", &a, 1);scanf_s("%c", &a, sizeof(a));return 0; } scanf_s有三个参数,最后一个是变量a所占据空间的大小(单位为字节)&…

【opencv4】opencv视频教程 C++(opencv教程)1、opencv介绍和环境搭建

下一讲:【opencv4】opencv视频教程 C(opencv教程)2、加载,修改,保存图像 [opencv_C] 入门强推!!!【B站最全】 文章目录 opencv介绍和环境搭建opencv组成架构核心模块环境搭建&#…

Opencv的使用教程,opencv比较全的基础教程

*免责声明: 1\此方法仅提供参考 2\搬了其他博主的操作方法,以贴上路径. 3* 场景一:Opencv对图像视频的基本使用 场景二:Opencv对图像视频进一步处理 场景三:Opencv对图像视频高级处理 . . . 课程视频 课程视频2 ubuntu18下采用源码编译的方式安裝opencv / 简单方式安装 …

VC2015搭建OpenCV环境(超详细教程)

1、首先下载OpenCV源码库 ① https://sourceforge.net/projects/opencvlibrary/?sourcetyp_redirect ②双击运行.exe文件,导出源代码 2、windows环境变量设置(测试环境是win7 64位) ①找到系统高级设置path 右键计算机--》属性--》高级系…

OpenMV IDE安装使用教程

一、什么是OpenMV OpenMV是一个开源,低成本,功能强大的机器视觉模块。以STM32F427CPU为核心,集成了OV7725摄像头芯片,在小巧的硬件模块上,用C语言高效地实现了核心机器视觉算法,提供Python编程接口。使用者…

OpenMV使用技巧

目录 一、光照影响1. 光照过强2. 光照过弱 二、杂框影响1. threshold参数2. 长宽比 三、画图 一、光照影响 OpenMV在使用过程中可能会遇到光照太强或者光照太弱等影响图像识别的情况,尤其在跑神经网络模型时,光照太强或太弱对识别结果的影响是致命的。 …

VC++6.0配置opencv1.0教程(全网最详细)附加图文

VC6.0配置opencv1.0教程&#xff08;全网最详细&#xff09;附加图文 &#xff08;&#xff08;很多评论我没时间看&#xff0c;tiquma写出来了&#xff0c;有兴趣的同学自己找一找8&#xff09; 配置前 第一次写博客&#xff0c;激动٩(๑>◡<๑)۶&#xff0c;坐标武…

C/C++ vs2017 OpenCV简单入门

离职之际&#xff0c;自学一下图像相关的知识点&#xff0c;只是简单学了一点皮毛&#xff01; 目录 一、 OpenCV环境搭建 二、使用opencv 常用接口说明 使用案例 1. 图像色彩空间转换 2. Mat对象的创建与赋值 3. 图像像素的读写操作 4. 图像像素的算术操作 5. 滚动条…

VS2017搭建OpenCV环境(新手详细教程)

整体流程如下&#xff1a; 下载Visual Studio2017版本下载OpenCV3.4.1版本配置环境变量在Visual Studio2017中引入头文件、库文件、链接库环境测试 说明&#xff1a;没有必要根据博主的博客下载与博客相应的版本&#xff0c;不同版本之间只需要改一点点东西即可 1、下载安装V…

《OpenCV联合C++》第一课:OpenCV下载及环境配置

1.下载OpenCV软件 官网下载Releases - OpenCV 下载对应文件即可 下载后导出到本地 导出中。。。 2.环境变量配置 导入对应文件夹下面路径..\opencv\build\x64\vc15\bin 3.文件夹内文件拷贝指定路径 打开文件夹下面路径.\opencv\build\x64\vc15\bin 将bin目录下面的opencv_wor…

OpenCV入门教程,超详细OpenCV入门教程!10小时让你轻松掌握opencv的使用

OpenCV是一个基于BSD许可&#xff08;开源&#xff09;发行的跨平台计算机视觉和机器学习软件库&#xff0c;可以运行在Linux、Windows、Android和mac OS 操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C 类构成&#xff0c;同时提供了Python、Ruby、MATLAB等语言的接…

VS+OpenCV+VC超详细的配置教程

写在前面的话 版权声明&#xff1a;转载请注明出处&#xff01;博主是一个小菜鸟&#xff0c;并且非常玻璃心&#xff01;如果文中有什么问题&#xff0c;请友好地指出来&#xff0c;博主查证后会进行更正。每篇文章都是博主现阶段的理解&#xff0c;如果理解的更深入的话&…

OpenMV入门介绍

目录 一、OpenMV是什么二、OpenART mini与OpenMV对比三、图像处理背景知识1.像素和分辨率2. 帧率3.RGB三原色4.LAB颜色空间 四、OpenMV图像处理方法1.感光元件自动增益/白平衡/曝光窗口ROI 2.画图画线画框画圆画十字写字示例 3. 寻找色块&#xff08;颜色识别&#xff09;find_…

最新opencv-c++安装及配置教程(VS2019 C++ opencv4.4.0)

以前写过opencv python的安装教程&#xff0c;后来有一些同学开始私信我如何安装及配置opencv c。 本文是以最新的版本入手&#xff0c;一步步详解opencv c 的安装及配置过程。&#xff1a; 第一步&#xff0c;下载解压opencv 算法库 进入到以下链接&#xff1a;https://opencv…

超详细:VS配置OpenCV教程,需要收藏

目录 安装环境说明 下载OpenCV 配置OpenCV开发环境 属性表 测试 可能存在的问题 安装环境说明 操作系统&#xff1a;Windows10 OpenCV版本&#xff1a;OpenCV2和OpenCV3 VS版本&#xff1a;VS2015或者VS2017 下载OpenCV OpenCV下载地址&#xff1a;Home - OpenCV或者直…