这是我在阅读论文《Creating emoji lexica from unsupervised sentiment analysis of their descriptions》看到的性能评价中的一部分,不得不说Q1就是Q1。
本文主要是讲解下何为Pearson相关系数,Spearman相关系数,以及相应的代码实现。(代码是我根据公式自己封装的,所以:1. 性能肯定没有Tensorflow那些框架的性能好; 2. 有可能会有问题)
1 Pearson相关系数
1.1 协方差
在讲解Pearson相关系数前,要先提协方差。协方差的公式如下:
c
o
v
(
X
,
Y
)
=
E
[
(
X
−
μ
)
(
Y
−
v
)
]
=
E
(
X
Y
)
−
E
(
X
)
E
(
Y
)
cov(X, Y)=E[(X-\mu)(Y-\mathcal{v})]=E(XY)-E(X)E(Y)
cov(X,Y)=E[(X−μ)(Y−v)]=E(XY)−E(X)E(Y)
μ \mu μ是随机变量 X X X的期望, v \mathcal{v} v是随机变量 Y Y Y的期望。
协方差反映了两个随机变量之间的相关性:
- 协方差为正:当一方增大时,另一方也倾向于增大,反之亦然。或者说一方的取值大于期望值,另一方取值大于期望值的概率将更大,反之亦然;
- 协方差为负:当一方增大时,另一方则倾向于减小,反之亦然。或者说一方的取值大于期望值,另一方取值小于期望值的概率将更大,反之亦然;
- 协方差为0:即使一方增大,另一方也不会因此增大或减小(两个随机变量之间没有线性关系)。
注:
- 这里所谓的倾向增大(减小),是因为我们从后面这一句来分析,因为是随机的,只是说可能大于(小于)均值(期望)的概率;
- 这里说的没有线性关系,但是有可能会有其他的关系,比如 x 2 x^2 x2这种非线性的关系。
我们来简单分析下,为什么协方差反映了两个随机变量之间的相关性。我们就从公式 E [ ( X − μ ) ( Y − v ) ] E[(X-\mu)(Y-\mathcal{v})] E[(X−μ)(Y−v)]中来分析:
首先 ( X − μ ) (X-\mu) (X−μ)反映的是随机变量 X X X与其均值 μ \mu μ的差值, ( Y − v ) (Y-\mathcal{v}) (Y−v)反映的是随机变量 Y Y Y与其均值 v \mathcal{v} v的差值,期望值 E E E我们就当做是均值,并不会改变正负,所以暂且不考虑,就只考虑期望内的内容。那么我们就可以得出,如果 ( X − μ ) (X-\mu) (X−μ)与 ( Y − v ) (Y-\mathcal{v}) (Y−v)同号,那么结果同号,如果异号,那么结果异号,所以就可以反映出两者之间的相关性。
但是这里会有个问题,是否协方差10000的相关性就大于协方差为1的相关性?要如何衡量几组样本相关性?于是我们就有了相关系数(Pearson相关系数)。
1.2 相关系数
最开始我看Pearson相关系数的时候还没反应过来,这就是相关系数……一方面怪我数学功底太差,第二方面这万恶的资本主义非要用人名来命名东西,淦!
好的,我们就先假设我们也不知道什么是相关系数,回到上面的两个问题上来,是否协方差10000的相关性就大于协方差为1相关性?如何衡量几组样本的相关性?
那么我们是不是希望能够把值压缩到某一个可比较的区间上来观测?有了这样的想法后,归一化就顺理成章的出现了。所以Pearson相关系数(下简称相关系数)就出现了。
相关系数就是协方差与标准差乘积的商,或者说就是归一化后的协方差,用于描述两个随机变量
X
X
X和
Y
Y
Y的线性相关性,且不随变量的平移而改变,取值范围为
[
−
1
,
1
]
[-1, 1]
[−1,1]。公式为:
ρ
(
X
,
Y
)
=
c
o
v
(
X
,
Y
)
σ
X
σ
Y
=
E
[
(
X
−
μ
)
(
Y
−
v
)
]
σ
X
σ
Y
\rho(X,Y)=\frac{cov(X,Y)}{\sigma X \sigma Y}=\frac{E[(X-\mu)(Y-\mathcal{v})]}{\sigma X \sigma Y}
ρ(X,Y)=σXσYcov(X,Y)=σXσYE[(X−μ)(Y−v)]
其中 σ \sigma σ为标准差。
标准差反映的是所有值与均值(期望)的平均离散程度(因为方差有平方,离散程度会被放大),这里由协方差与标准差相除就可以将数据归一化,变到 [ − 1 , 1 ] [-1, 1] [−1,1]的范围内,可以进行相应的对比了。
用代码来表示如下:
import numpy as np
def pearson_correlations(x, y):
"""
Pearson相关系数
:param x: 向量x
:param y: 向量y
:return rho: (Pearson)相关系数
"""
cov = np.cov(x, y, bias=True)[0][1] # 有偏估计, 当样本长度确定时
# cov = np.cov(x, y)[0][1] # 无偏估计
std_x = np.std(x)
std_y = np.std(y)
rho = cov / (std_x * std_y)
return rho
我使用的两个向量如下:
vector_x = np.array([-6, 8, -4, 10])
vector_y = np.array([-7, -5, 7, 9])
这里要补充下两个内容:1. 协方差矩阵; 2. 有偏估计与无偏估计。(补充的原因是因为我撸码的时候遇到了)
首先是第一个内容:协方差矩阵。就以我上面的两个向量来说,得到的协方差矩阵如下:
[ [ ρ ( X , X ) , ρ ( X , Y ) ] , [[\rho(X, X), \rho(X,Y)], [[ρ(X,X),ρ(X,Y)],
[ ρ ( X , Y ) , ρ ( X , X ) ] ] [\rho(X,Y), \rho(X, X)]] [ρ(X,Y),ρ(X,X)]]
所以代码中使用的是np.cov(x, y)[0][1]。
接着是有偏估计与无偏估计。首先是两者的定义及使用情况:
- 有偏估计:
1
n
∑
i
=
1
n
(
x
i
−
μ
)
2
\frac{1}{n}\sum_{i=1}^n(x_i-\mu)^2
n1∑i=1n(xi−μ)2,即估计量的数学期望不等于被估计参数的真实值,
E
(
θ
ˉ
)
≠
θ
E(\bar \theta)\neq \theta
E(θˉ)=θ。有偏估计的长度
n
n
n是总体抽样的长度,不随着每次计算而改变。
在这里给我的个人感觉是如下的:如果我们知晓总体样本情况,比如上面两个向量,我们知晓个数,那么我们就可以得知全部的 n n n,也就可以得到真实的情况。但是大部分情况我们是不知晓总体情况的,所以这样的估计方法得到的结果会略小于等于真实情况,详细的推导过程在这篇博客中:https://blog.csdn.net/weixin_37352167/article/details/90338977。(主要是我只是瞟了一眼,没有推导……) - 无偏估计: 1 n − 1 ∑ i = 1 n ( x i − μ ) 2 \frac{1}{n-1}\sum_{i=1}^n(x_i-\mu)^2 n−11∑i=1n(xi−μ)2,即估计量的数学期望等于被估计参数的真实值, E ( θ ˉ ) = θ E(\bar \theta)= \theta E(θˉ)=θ。无偏估计是个局部最优问题,就是说在我们不清楚具体样本的情况下,我们能够保证每次取出来的样本得到的方差是接近真实值的,具体的推导情况也和上面相同。
这里我还有些地方没有理解透彻,关于我参考的所有文章我会在后面一一列出,大家有兴趣可以翻阅下。不过我这里列出这个的概念是想说明代码中cov里面bias的取值,我们先看看cov的源码中bias的注释:
bias : bool, optional
Default normalization (False) is by ``(N - 1)``, where ``N`` is the
number of observations given (unbiased estimate). If `bias` is True,
then normalization is by ``N``. These values can be overridden by using
the keyword ``ddof`` in numpy versions >= 1.5.
这里大体的意思就是说,bias如果是True,那么为有偏估计,分母为 N N N,如果bias为False(默认情况也是False),那么为无偏估计,偏离的自由度由ddof确定,ddof则是分母的 N − k N-k N−k中的 k k k值,默认ddof为1。
再回到代码中,由于我的向量是确定的,所以可以直接采用有偏估计,但是如果向量不确定,那么需要无偏估计。
最终得到的结果为:
样本的Pearson相关系数为: 0.27999999999999997
2 Spearman相关系数
当我第一次看到这个Spearman的时候,把我惊到了,因为它是针对两个随机变量 X X X和 Y Y Y,分别为 X X X和 Y Y Y中的每个值 x i x_i xi和 y i y_i yi打分或者说排序(英文叫rank),将打分后的内容与之前的内容重新组合成一个新的矩阵:
x x x | y y y | r a n k x rank_x rankx | r a n k y rank_y ranky |
---|
通过如下的公式来计算相似度:
ρ
=
1
−
6
∑
i
=
1
n
d
i
2
n
(
n
2
−
1
)
,
(
d
i
=
r
a
n
k
x
i
−
r
a
n
k
y
i
)
\rho = 1-\frac{6\sum_{i=1}^nd_i^2}{n(n^2-1)}, (d_i=rank_{x_i}-rank_{y_i})
ρ=1−n(n2−1)6∑i=1ndi2,(di=rankxi−rankyi)
是不是看了之后发现清新脱俗?我根本不关心 x x x与 y y y之间的大小关系,我只需要排序后就可以简单计算出来相似度,这样就可以直接忽略掉样本 X X X和 Y Y Y的均值(期望值),但是就是得出来的相似性也就不一定很准确了。
用上面的两个向量举例:
vector_x = np.array([-6, 8, -4, 10])
vector_y = np.array([-7, -5, 7, 9])
得到的矩阵如下:
x x x | y y y | r a n k x rank_x rankx | r a n k y rank_y ranky |
---|---|---|---|
-6 | -7 | 1 | 1 |
-4 | 7 | 2 | 3 |
8 | -5 | 3 | 2 |
10 | 9 | 4 | 4 |
用代码表示如下:
import numpy as np
def spearmans_rank_correlation(x, y):
"""
Spearman相关系数
:param x: 向量x
:param y: 向量y
:return rho: spearman相关系数
"""
# 合并向量
# [[-6, 8, -4, 10],
# [-7, -5, 7, 9]]
spearman_matrix = np.vstack((x, y))
# 得到排序后的x和y的rank值(因为x与y同型)
# [1, 2, 3, 4]
rank = np.arange(1, len(x) + 1)
# 将x的rank值向量合并到矩阵上
# [[-6, -4, 8, 10],
# [-7, 7, -5, 9],
# [1, 2, 3, 4]]
spearman_matrix = spearman_matrix[:, spearman_matrix[0].argsort()]
spearman_matrix = np.vstack((spearman_matrix, rank))
# 将y的rank值向量合并到矩阵上
# [[-6, 8, -4, 10],
# [-7, -5, 7, 9],
# [1, 3, 2, 4],
# [1, 2, 3, 4]]
spearman_matrix = spearman_matrix[:, spearman_matrix[1].argsort()]
spearman_matrix = np.vstack((spearman_matrix, rank))
# 重新按照x的rank值排列
# [[-6, -4, 8, 10],
# [-7, 7, -5, 9],
# [1, 2, 3, 4],
# [1, 3, 2, 4]]
spearman_matrix = spearman_matrix[:, spearman_matrix[0].argsort()]
# 求squa(d)
# [0, 1, 1, 0]
d_square = (spearman_matrix[2] - spearman_matrix[3]) ** 2
rho = 1 - (6 * sum(d_square) / (len(x) * (len(x) ** 2 - 1)))
return rho
得到的结果如下:
样本的Spearman相关系数为: 0.8
3 区别
- 连续数据,正态分布,线性关系,用Pearson相关系数是最恰当,当然用Spearman相关系数也可以,就是效率没有Pearson相关系数高。
- 上述任一条件不满足,就用Spearman相关系数,不能用Pearson相关系数。
- 两个定序测量数据之间也用Spearman相关系数,不能用Pearson相关系数。
用Pearson处理的数据,必须满足一下条件:成对数据、连续、整体是正态分布的。
Pearson相关系数是用原来的数值计算积差相关系数, 而Spearman是用原来数值的秩次计算积差相关系数.
4 参考
[1]平冈和幸,堀玄.程序员的数学2概率统计[M].人民邮电出版社:北京,2015:195-220.
[2]mmc2015.几个相关系数:Pearson、Spearman、pointbiserialr、kendalltau[EB/OL].https://blog.csdn.net/mmc2015/article/details/51942066,2016-7.
[3]百度百科.皮尔逊相关系数[EB/OL].https://baike.baidu.com/item/%E7%9A%AE%E5%B0%94%E9%80%8A%E7%9B%B8%E5%85%B3%E7%B3%BB%E6%95%B0/12712835?fr=aladdin&fromtitle=Pearson%20Correlation%20Coefficients&fromid=2903702,2020-4.
[4]百度百科.斯皮尔曼等级相关[EB/OL].https://baike.baidu.com/item/%E6%96%AF%E7%9A%AE%E5%B0%94%E6%9B%BC%E7%AD%89%E7%BA%A7%E7%9B%B8%E5%85%B3?fr=aladdin,2019-8.
[5]wyf.numpy中的方差、协方差、相关系数[EB/OL].https://www.cnblogs.com/weiyinfu/p/10693445.html,2019-4.
[6]–每天都被梦想唤醒–.spark MLlib 概念 1:相关系数( PPMCC or PCC or Pearson’s r皮尔森相关系数) and Spearman’s correlation(史匹曼等级相关系数)[EB/OL].https://www.cnblogs.com/zwCHAN/p/4265729.html,2015-2.
[7]GoWeiXH.有偏估计 and 无偏估计 - 方差分母 n-1(详细证明)[EB/OL].https://blog.csdn.net/weixin_37352167/article/details/90338977,2019-5.
[8]时海涛|Thomas.计量经济与时间序列_关于自协方差函数与自相关函数的有偏估计和无偏估计的解释[EB/OL].https://www.cnblogs.com/noah0532/p/8512160.html,2018-3.
[9]狼族的后裔_西伯利亚狼.有偏估计与无偏估计的区别[EB/OL].https://www.cnblogs.com/lorenshuai724005/p/11576760.html,2019-9.
[10]氕-氦氖氩氪氙氡.有偏估计与无偏估计[EB/OL].https://blog.csdn.net/u013300012/article/details/86443725,2019-1.