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 实战中的选择建议
说了这么多,到底该用哪个?我给大家一个简单的决策流程:
- 先看数据分布——如果收益率近似正态,用皮尔逊没问题
- 如果有异常值——直接上斯皮尔曼或肯德尔
- 如果样本量小(比如少于30个交易日)——肯德尔更可靠
- 如果要做大规模网络(比如全A股4000多只股票)——皮尔逊计算最快,但记得先做异常值处理
重要提醒:相关性不等于因果性。两个资产相关性高,不代表一个涨另一个就一定涨。我在构建网络时,通常会把相关性矩阵作为输入,再结合偏相关、条件相关等方法做进一步分析。这个我们后面章节会详细讲。
好了,这一章的内容就到这里。三种相关系数各有优劣,关键是根据你的数据特点和应用场景来选择。下一章我们会聊如何用这些相关系数构建真正的市场关联性网络,包括阈值设定、网络稀疏化等实战技巧。
公众号:蓝海资料掘金营,微信deep3321