1. 皮尔逊相关系数
1.1 定义
皮尔逊相关系数(Pearson Correlation Coefficient),也称作线性相关系数,是用来衡量两个变量之间线性相关性强弱的统计量。它的值范围是 [−1,1],其中:
- r=1:完全正线性相关,即 Y 随 X 增加严格增加;
- r=−1:完全负线性相关,即 Y 随 X增加严格减少;
- r=0:无线性相关性。
皮尔逊相关系数主要用于描述两个变量之间的线性关系强弱,而非广义的关系。
1.2 数学公式
假设有两个变量 X=[X1,X2,…,Xn]和 Y=[Y1,Y2,…,Yn],皮尔逊相关系数的计算公式为:
其中:
-
Cov(X,Y)是 X 和 Y 的协方差,定义为:
其中
和
分别是 X和 Y 的均值。
-
σX 和 σY 分别是 X 和 Y 的标准差,定义为:
-
结合协方差和标准差进行替换,皮尔逊相关系数可以写作:
1.3 推导与理解
-
协方差的作用:
- 协方差衡量了两个变量的联合波动性。如果 Xi>Xˉ 时 Yi>Yˉ(即 X和 Y 同时偏离均值较多),则协方差为正,反之则为负。
- 但是协方差的具体数值范围受变量尺度影响,无法直接用于比较。
-
标准化协方差:
- 为了消除变量尺度的影响,引入标准差 σX 和 σY 对协方差进行归一化,保证结果的范围为 [−1,1]。
-
几何解释:
- 皮尔逊相关系数可以看作 XX 和 YY 的标准化向量之间的余弦相似度。设这两个向量分别为:
X=(X1−Xˉ,X2−Xˉ,…,Xn−Xˉ)
Y=(Y1−Yˉ,Y2−Yˉ,…,Yn−Yˉ)
则皮尔逊相关系数可以写为:
其中 θ 是两向量间的夹角。
- 皮尔逊相关系数可以看作 XX 和 YY 的标准化向量之间的余弦相似度。设这两个向量分别为:
1.4 适用场景与局限性
-
适用场景:
- 数据服从正态分布;
- 数据之间是线性关系。
-
局限性:
- 不能处理非线性关系:如
的关系,其皮尔逊相关系数可能接近 0,但显然两者相关性很强。
- 对异常值敏感:因为均值和标准差受异常值影响,皮尔逊相关系数的结果也会显著变化。
- 不能处理非线性关系:如
2. 斯皮尔曼相关系数
2.1 定义
斯皮尔曼相关系数(Spearman's Rank Correlation Coefficient)是一种基于秩次(Rank)的非参数统计量,用于衡量两个变量之间的单调关系。它对数据的分布和异常值不敏感,适合检测非线性但单调的关系。
2.2 数学公式
假设有两个变量 X=[X1,X2,…,Xn]和 Y=[Y1,Y2,…,Yn],其对应的秩次为 Rank(X) 和 Rank(Y),斯皮尔曼相关系数的公式为:
其中:
是对应样本的秩次差;
- n是样本数量。
当没有秩次重复(没有数据平分)时,上述公式可以进一步简化为皮尔逊相关系数公式的形式:
2.3 秩次计算
- 对于变量 X,将数据从小到大排序,赋予其对应的秩次 Rank(X)。如果有重复值,取这些重复值秩次的平均值。
- 示例:数据 X=[3,1,4,3],对应的秩次为 [2.5,1,4,2.5](3 的秩次取平均值)。
- 同理计算 Y的秩次。
2.4 推导与理解
-
核心思路:
- 将原始数据转换为秩次后,计算秩次之间的皮尔逊相关系数。
- 因为秩次只关注数据的相对大小顺序,所以斯皮尔曼相关系数消除了尺度和异常值的影响。
-
单调关系:
- 斯皮尔曼相关系数可以捕捉单调的非线性关系。例如,对于
的关系,斯皮尔曼相关系数可以接近 1。
- 斯皮尔曼相关系数可以捕捉单调的非线性关系。例如,对于
-
秩次差的平方:
- 在公式 ρ 中:
- 如果 di=0(即秩次完全一致),则 ρ=1。
- 如果 di 越大(秩次差异越显著),则 ρ 越小。
- 在公式 ρ 中:
2.5 适用场景与局限性
-
适用场景:
- 数据不满足正态分布;
- 数据之间存在单调关系,但不一定是线性关系;
- 数据中存在异常值。
-
局限性:
- 无法捕捉非单调关系(如周期关系)。
3. 对比与可视化
特性 | 皮尔逊相关系数 | 斯皮尔曼相关系数 |
---|---|---|
衡量的关系类型 | 线性关系 | 单调关系(线性或非线性) |
公式依赖 | 均值、标准差、协方差 | 秩次 |
对异常值的敏感性 | 敏感 | 不敏感 |
适用分布假设 | 数据服从正态分布或接近正态分布 | 不要求分布假设 |
适用关系类型 | 线性 | 单调关系(包括非线性) |
计算复杂度 | 较低 | 略高(需排序计算秩次) |
完整代码:
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import pearsonr, spearmanr
# 设置随机种子保证结果可复现
np.random.seed(42)
plt.rcParams['font.sans-serif'] = ['SimHei'] # 使用中文字体
plt.rcParams['axes.unicode_minus'] = False # 解决负号无法正常显示的问题
# 可视化函数
def visualize_correlation(x, y, title):
"""
可视化两个变量的散点图,并计算和对比皮尔逊相关系数与斯皮尔曼相关系数
"""
# 计算皮尔逊相关系数和斯皮尔曼相关系数
pearson_corr, _ = pearsonr(x, y)
spearman_corr, _ = spearmanr(x, y)
# 绘制散点图
plt.scatter(x, y, alpha=0.7, edgecolor='k')
plt.title(f"{title}\nPearson: {pearson_corr:.2f}, Spearman: {spearman_corr:.2f}")
# plt.xlabel("X")
plt.ylabel("Y")
plt.axhline(0, color='gray', linestyle='--', linewidth=0.5)
plt.axvline(0, color='gray', linestyle='--', linewidth=0.5)
plt.grid(alpha=0.3)
# 生成数据和可视化
plt.figure(figsize=(12, 12))
# 1. 正线性关系
x1 = np.linspace(-10, 10, 100)
y1 = 2 * x1 + np.random.normal(0, 5, size=x1.shape)
plt.subplot(3, 2, 1)
visualize_correlation(x1, y1, "正线性关系")
# 2. 负线性关系
x2 = np.linspace(-10, 10, 100)
y2 = -2 * x2 + np.random.normal(0, 5, size=x2.shape)
plt.subplot(3, 2, 2)
visualize_correlation(x2, y2, "负线性关系")
# 3. 非线性关系(如二次函数)
x3 = np.linspace(-10, 10, 100)
y3 = x3**2 + np.random.normal(0, 10, size=x3.shape)
plt.subplot(3, 2, 3)
visualize_correlation(x3, y3, "非线性关系(抛物线)")
# 4. 单调递增非线性关系
x4 = np.linspace(1, 10, 100)
y4 = np.log(x4) + np.random.normal(0, 0.2, size=x4.shape)
plt.subplot(3, 2, 4)
visualize_correlation(x4, y4, "单调递增非线性关系")
# 5. 非单调关系(周期函数)
x5 = np.linspace(0, 2 * np.pi, 100)
y5 = np.sin(x5) + np.random.normal(0, 0.1, size=x5.shape)
plt.subplot(3, 2, 5)
visualize_correlation(x5, y5, "非单调关系(正弦波)")
# 6. 噪声主导的关系(随机数据)
x6 = np.random.uniform(-10, 10, 100)
y6 = np.random.uniform(-10, 10, 100)
plt.subplot(3, 2, 6)
visualize_correlation(x6, y6, "噪声主导的关系(随机数据)")
plt.tight_layout()
plt.show()
4. 总结
- 皮尔逊相关系数适用于研究数据之间的线性关系,常用于正态分布的数值型数据分析场景。
- 斯皮尔曼相关系数适用于研究数据之间的单调关系(包括非线性),对异常值不敏感,适合非正态分布数据。