3. 相关性度量基础:从相关系数到关联网络

各位同学,今天我们来聊聊构建市场关联性网络最基础、也最关键的一环——相关性度量。说白了,就是怎么量化两个资产之间「同涨同跌」的程度。

我刚开始做量化那会儿,总觉得相关性嘛,不就是算个皮尔逊系数?后来在实盘里吃过亏,才发现事情没那么简单。不同的数据分布、不同的异常值处理方式,算出来的结果可能天差地别。今天我就把常用的三种相关系数掰开揉碎了讲清楚。

3.1 皮尔逊相关系数:最经典,但别乱用

皮尔逊相关系数,大家应该都不陌生。它衡量的是两个变量之间的线性相关程度。公式长这样:

ρ(X,Y) = Cov(X,Y) / (σX * σY)

取值范围在[-1, 1]之间。1代表完全正相关,-1代表完全负相关,0代表没有线性关系。

核心假设:数据要服从正态分布,且变量间是线性关系。

我在项目中遇到过一个问题:用皮尔逊系数算两只股票的日收益率相关性,结果发现某段时间系数突然从0.6跳到了0.9。后来一查,原来是其中一只股票发生了分红除权,导致收益率数据出现了异常值。嗯,这里要注意——皮尔逊系数对异常值极其敏感

避坑指南:我曾经因为没做数据清洗,直接用皮尔逊系数构建相关性矩阵,结果网络里出现了大量虚假的强连接。后来花了整整两天排查,才发现是几个异常值在捣鬼。所以,用皮尔逊之前,务必做好异常值处理和数据标准化。

3.2 斯皮尔曼秩相关系数:不挑数据的「老好人」

斯皮尔曼秩相关系数,说白了就是把原始数据换成排名,再算皮尔逊。它不关心数据的具体数值,只关心相对大小。

公式也很简单:

ρs = 1 - (6 * Σdi²) / (n * (n² - 1))

其中di是每个观测值的排名差,n是样本量。

为什么说它是「老好人」?因为它不要求正态分布,也不要求线性关系。只要两个变量的单调关系一致,它就能捕捉到。

我记得有一次做行业轮动策略,用皮尔逊系数算出来的相关性矩阵一团糟,换成斯皮尔曼之后,结构清晰了很多。原因是什么?因为行业指数的收益率分布往往有厚尾特征,皮尔逊对这种分布很敏感,而斯皮尔曼不受影响。

我的习惯:在做初步探索性分析时,我通常会同时算皮尔逊和斯皮尔曼。如果两者差异很大,说明数据里可能有非线性关系或者异常值,这时候就要小心了。

3.3 肯德尔秩相关系数:更稳健的选择

肯德尔秩相关系数,比斯皮尔曼还要「稳健」。它衡量的是两个变量排序的一致性程度。

计算逻辑是这样的:

  • 对于任意两个观测值,看它们在两个变量上的排序是否一致
  • 一致的对数减去不一致的对数,再除以总对数

公式:

τ = (C - D) / (C + D)

其中C是一致对的数量,D是不一致对的数量。

你想想看,肯德尔系数只关心「谁比谁大」,完全不关心具体数值。所以它对异常值几乎免疫。但代价是什么?计算复杂度高,数据量大时会比较慢。

我个人习惯是:样本量小于1000时用肯德尔,大于1000时用斯皮尔曼。当然,如果你有GPU或者并行计算资源,那另当别论。

3.4 三种相关系数的对比

指标 皮尔逊 斯皮尔曼 肯德尔
数据类型 连续变量 连续/有序 连续/有序
分布假设 正态分布
关系类型 线性 单调 单调
异常值敏感度
计算效率
适用场景 金融收益率 行业轮动 小样本分析

3.5 相关性矩阵的计算与可视化

有了相关系数,下一步就是构建相关性矩阵。说白了,就是把N个资产两两之间的相关系数算出来,排成一个N×N的矩阵。

代码实现其实很简单:

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# 假设我们有一个DataFrame,每列是一只股票的收益率
returns = pd.read_csv('stock_returns.csv', index_col=0)

# 计算皮尔逊相关性矩阵
pearson_corr = returns.corr(method='pearson')

# 计算斯皮尔曼相关性矩阵
spearman_corr = returns.corr(method='spearman')

# 计算肯德尔相关性矩阵
kendall_corr = returns.corr(method='kendall')

# 可视化
fig, axes = plt.subplots(1, 3, figsize=(18, 6))

sns.heatmap(pearson_corr, ax=axes[0], cmap='RdBu_r', 
            vmin=-1, vmax=1, annot=False)
axes[0].set_title('Pearson Correlation')

sns.heatmap(spearman_corr, ax=axes[1], cmap='RdBu_r', 
            vmin=-1, vmax=1, annot=False)
axes[1].set_title('Spearman Correlation')

sns.heatmap(kendall_corr, ax=axes[2], cmap='RdBu_r', 
            vmin=-1, vmax=1, annot=False)
axes[2].set_title('Kendall Correlation')

plt.tight_layout()
plt.show()

可视化小技巧:我习惯用'RdBu_r'色系,红色代表正相关,蓝色代表负相关。颜色越深,相关性越强。另外,记得把vmin和vmax设为-1和1,这样不同矩阵之间才能公平比较。

3.6 本章知识体系

下面这张图展示了三种相关系数的核心逻辑和适用场景:

相关性度量方法体系 相关性度量 皮尔逊相关系数 斯皮尔曼秩相关系数 肯德尔秩相关系数 特性 • 线性关系 • 正态分布假设 • 对异常值敏感 特性 • 单调关系 • 无分布假设 • 基于排名计算 特性 • 排序一致性 • 最稳健 • 计算复杂度高 应用:构建相关性矩阵 → 市场关联性网络 选择建议:数据正态 → 皮尔逊;数据非正态 → 斯皮尔曼;小样本/高稳健性 → 肯德尔

3.7 实战中的选择建议

说了这么多,到底该用哪个?我给大家一个简单的决策流程:

  1. 先看数据分布——如果收益率近似正态,用皮尔逊没问题
  2. 如果有异常值——直接上斯皮尔曼或肯德尔
  3. 如果样本量小(比如少于30个交易日)——肯德尔更可靠
  4. 如果要做大规模网络(比如全A股4000多只股票)——皮尔逊计算最快,但记得先做异常值处理

重要提醒:相关性不等于因果性。两个资产相关性高,不代表一个涨另一个就一定涨。我在构建网络时,通常会把相关性矩阵作为输入,再结合偏相关、条件相关等方法做进一步分析。这个我们后面章节会详细讲。

好了,这一章的内容就到这里。三种相关系数各有优劣,关键是根据你的数据特点和应用场景来选择。下一章我们会聊如何用这些相关系数构建真正的市场关联性网络,包括阈值设定、网络稀疏化等实战技巧。


公众号:蓝海资料掘金营,微信deep3321