一、相关系数
前言
- 相关系数取值范围:[0, 1]
- 负值: 表示两个变量成负相关;
- 正值: 表示两个变量成正相关;
- 0: 表示两个变量无相关关系(一个变量的增大减小对另一个的取值没有影响)
1、斯皮尔曼相关系数
(1)基本概念
- 皮尔逊相关是关于两个随机变量之间的线性关系强度的统计度量,而斯皮尔曼相关考察的是两者单调关系的强度,就是两者在变大或变小的趋势上多大程度上保持步调一致,哪怕没有保持比例关系;
- 计算皮尔逊相关系数时使用的是数据样本值本身,而计算斯皮尔曼相关系数使用的是数据样本排位位次值(有时候数据本身就是位次值,有时候数据本身不是位次值,则在计算斯皮尔曼相关系数之前要先计算位次值)。
“非参数”的两层含义:
(2)适用情况
- 数据展现的是非线性关系,或者不是正态分布的
- 至少有一方数据是序数类型(ordinal)而非数值类型
例如考察两个球队在历年联赛中的战绩之间的关系,得到的数据可能是这样的:A队在2010~2020年间的联赛排名为{1,2,4,5,…,2}, B队在2010~2020年间的联赛排名为{2,1,3,6,…,4}。这两个数据就是序数类型的数据,考察它们的相关性你使用皮尔逊相关系数就不妥当
- 数据中有明显的异常值
与皮尔逊相关不同,斯皮尔曼相关对于异常值不太敏感,因为它基于排序位次进行计算,实际数值之间的差异大小对于计算结果没有直接影响
(3)表达式
ρ = 1 n ∑ i = 1 n ( R ( x i ) − R ( x ) ‾ ) ⋅ ( R ( y i ) − R ( y ) ‾ ) ( 1 n ∑ i = 1 n ( R ( x i ) − R ( x ) ‾ ) 2 ) ⋅ ( 1 n ∑ i = 1 n ( R ( y i ) − R ( y ) ‾ ) 2 ) \rho=\frac{\frac{1}{n}\sum_{i=1}^{n}\left(R(x_{i})-\overline{R(x)})\cdot(R(y_{i})-\overline{R(y)}\right)}{\sqrt{\left(\frac{1}{n}\sum_{i=1}^{n}\left(R(x_{i})-\overline{R(x)}\right)^{2}\right)\cdot\left(\frac{1}{n}\sum_{i=1}^{n}\left(R(y_{i})-\overline{R(y)}\right)^{2}\right)}} ρ=(n1∑i=1n(R(xi)−R(x))2)⋅(n1∑i=1n(R(yi)−R(y))2)n1∑i=1n(R(xi)−R(x))⋅(R(yi)−R(y))
- R ( x ) R(x) R(x)和 R ( y ) R(y) R(y)分别是x和y的位次
(4)代码实现
import numpy as np
from scipy import stats # 基于scipy
stats.spearmanr([3,5,1,6,7,2,8,9,4], [5,3,2,6,8,1,7,9,4]) # 确定顺序的
rng = np.random.default_rng()
x2n = rng.standard_normal((100, 2))
stats.spearmanr(x2n) # 随机数序列的
import pandas as pd # 基于pandas
import numpy as np
X=pd.Series([3,5,1,6,7,2,8,9,4])
Y=pd.Series([5,3,2,6,8,1,7,9,4])
rho = X.corr(Y,method='spearman')
print(rho)
2、皮尔逊相关系数
- 最常用的相关,通常用 r r r表示
- 衡量两个随机变量间的线性关系(线性关联度)
(1)数学表达式
定义为:两个变量之间的协方差和标准差之积的商
r
=
∑
i
=
1
n
(
x
i
−
X
ˉ
)
(
y
i
−
Y
ˉ
)
∑
i
=
1
n
(
x
i
−
X
ˉ
)
2
∑
i
=
1
n
(
y
i
−
Y
ˉ
)
2
r=\frac{\sum_{i=1}^{n}(x_{i}-\bar{X})(y_{i}-\bar{Y})}{\sqrt{\sum_{i=1}^{n}(x_{i}-\bar{X})^{2}}\sqrt{\sum_{i=1}^{n}(y_{i}-\bar{Y})^{2}}}
r=∑i=1n(xi−Xˉ)2∑i=1n(yi−Yˉ)2∑i=1n(xi−Xˉ)(yi−Yˉ)
X
ˉ
\bar{X}
Xˉ与
Y
ˉ
\bar{Y}
Yˉ分别是两个样本的均值
(2)数学性质
1)对称性
因为每个样本的协方差与标准差不变,所以其具有对称性
2)位移不变性
由于在皮尔逊相关计算(不管是总体的、还是样本的)中,分子(两者的协方差)和分母(各自的方差)都通过减去均值(中心化,或者均值归一化)将均值的影响消除掉了,因此X和Y的均值的变化不会影响两者之间的皮尔逊相关系数。
3)尺度不变性
分别将X与Y乘以一个不变的系数,两样本间的皮尔逊系数不变
(3)结果分析
1)左:
r
=
1
r=1
r=1完全正相关;中:为
r
=
0
r=0
r=0线性不相关;右:
r
=
−
1
r=-1
r=−1完全负相关
2)上图为不完全相关
3)注:皮尔逊中,
r
=
0
r=0
r=0仅能说明两个变量间没有线性关系,可能还存在其他相关性:
如上图,可能存在非线性关系
4)
(4)代码实现
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import pearsonr
from scipy.optimize import curve_fit
# 生成随机数
np.random.seed(0)
x = np.random.rand(100)
y = 2 * x + 1 + np.random.randn(100) * 0.2
# 计算皮尔逊相关系数
correlation_coefficient, _ = pearsonr(x, y)
# 定义线性函数
def linear_function(x, a, b):
return a * x + b
# 使用curve_fit拟合数据
params, covariance = curve_fit(linear_function, x, y)
# 绘制散点图和拟合曲线
plt.scatter(x, y, label='Data')
plt.plot(x, linear_function(x, *params), color='red', label='Fit: {:.2f}x + {:.2f}'.format(*params))
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Scatter Plot with Fitted Line\nCorrelation coefficient = {:.2f}'.format(correlation_coefficient))
plt.legend()
plt.grid(True)
plt.show()
3、肯德尔相关系数
(1)基本概念
- 使用 τ \tau τ表示
- 基于样本数据对之间的关系来进行相关系数的强弱的分析,数据对可以分为一致对(Concordant)和分歧对(Discordant)
- 需要首先计算一致对与分歧对
1)一致对与分歧对
一致对:
两个变量的这一对样本值取值的相对关系一致,可以理解为与
有相同的符号,即
分歧对:
这一对样本值取值的相对关系不一致,即
2)前提条件
使用肯德尔系数时,应满足以下两个假设:
- 变量数据是有序的( ordinal) 或者是连续的(continuous)
有序尺度(Ordinal scales)的数据通常用于以数值的方式来衡量非数值的概念,例如满意度,幸福度等等,还有像成绩排名啊、比赛名次啊之类的。而连续尺度的数据就勿需解释了,常见的温度啊、体重啊、收入啊等等都(或严格、或近似)算是连续尺度的数据。
- 两个变量的数据之间应该遵循单调关系( monotonic relationship)
这个单调关系是一个统计意义上的,或者说一种趋势上的,而非严格的单调。如下如所示。左图和中图都呈现一种近似单调的关系,而右图则不是,因为右图的左半部分和右半部分的趋势是相反的。
3)适用情况
当数据样本比较小,而且存在并列排位(tied ranks,比如说小明的历史成绩和英语成绩排名都是第8名)时,肯德尔相关系数是比斯皮尔曼相关系数更合适的一个相关性衡量指标。
例如:
- 学生的考试成绩分级 (A, B, C…) 和他平均每天学习所投入的时间分级 (<2 hours, 2–4 hours, 5–7 hours…)时间的相关性
- 顾客满意度 (比如说:非常满意,比较满意,一般。。。) 以及递送时间 (< 30 Minutes, 30 minutes — 1 Hour, 1–2 Hours etc)
(2)表达式及代码实现
有两个计算公式,一个称为Tau-c,另一个称为Tau-b。两者的区别是Tau-b可以处理有相同值的情况,即并列排位(tied ranks)
1)Tau-a
n表示样本个数。如上所述,肯德尔相关系数是基于数据对来进行分析的,n个样本每两两组队所得到的组队数就是,Tau-a的分母即来自于此。分子中c和d则分别代表一致对和分歧对的个数。
from scipy.stats.stats import kendalltau
dat1 = np.array([3,5,1,9,7,2,8,4,6])
dat2 = np.array([5,3,2,6,8,1,7,9,4])
fig,ax = plt.subplots()
ax.scatter(dat1,dat2)
kendalltau(dat1,dat2)
>>> KendalltauResult(correlation=0.39, pvalue=0.18)
2)Tau-b
当原始数据中存在并列排位时,则用以下公式能够给出更准确的分析结果。
其中c和d则分别代表一致对和分歧对的个数,
t
x
t_x
tx和
t
y
t_y
ty则分别表示数据X中的并列排位个数和数据Y中的并列排位个数。
注:如果是同时发生在X和Y中并列排位,则既不计入
t
x
t_x
tx,也不计入
t
y
t_y
ty。
from scipy.stats.stats import kendalltau
dat1 = np.array([3,5,1,6,7,2,8,8,4])
dat2 = np.array([5,3,2,6,8,1,7,8,4])
print('kendalltau(dat1,dat2) = {0}'.format(kendalltau(dat1,dat2)))
>>>kendalltau(dat1,dat2) = KendalltauResult(correlation=0.6857142857142857, pvalue=0.011424737055271894)