在介绍皮尔逊相关系数前,先来回顾一些统计相关的术语,便于我们更好的理解后面的计算公式。

方差(Variance)

参考百度百科

注意:

方差在统计描述和概率分布中各有不同的定义,并有不同的公式。

下面主要介绍在统计描述中的方差

在统计描述中,方差用来计算每一个变量(观察值)与总体均数之间的差异。为避免出现离均差总和为零,离均差平方和受样本含量的影响,统计学采用平均离均差平方和来描述变量的变异程度。

总体方差计算公式为:

$$ \sigma^2 = \frac{\sum(X-\mu)^2}{N} $$

$\sigma^2$为总体方差,$X$为变量,$\mu$为总体均值,$N$为总体例数。

实际工作中,总体均数难以得到时,应用样本统计量代替总体参数,经校正后,

样本方差计算公式:

$$ S^2 = \frac{\sum(X-\bar{X}) ^2}{(n-1)} $$

$S^2$为样本方差,$X$为变量,$\bar{X}$为样本均值,$n$为样本例数。

例如:

两个人X, Y 5次考试测验的分数分别是:

  • X: 50, 100, 100, 60, 50
  • Y: 73, 70, 75, 72, 70

X, Y的平均值分别为:

$$ \mu_x = \bar{X} = \frac{(50+100+100+60+50)}{5} = 72 $$

$$ \mu_y = \bar{Y} = \frac{(73+70+75+72+70)}{5} = 72 $$

总体方差为:

$$ \sigma^2_x = \frac{(50-72)^2+(100-72)^2+(100-72)^2+(60-72)^2+(50-72)^2}{5}= \frac{2680}{5}=536 $$

$$ \sigma^2_y = \frac{(73-72)^2+(70-72)^2+(75-72)^2+(72-72)^2+(70-72)^2}{5}=\frac{18}{4}=3.6 $$

样本方差为:

$$ S^2_x = \frac{(50-72)^2+(100-72)^2+(100-72)^2+(60-72)^2+(50-72)^2}{5-1} = \frac{2680}{4} = 670 $$

$$ S^2_y = \frac{(73-72)^2+(70-72)^2+(75-72)^2+(72-72)^2+(70-72)^2}{5-1}=\frac{18}{4}=4.5 $$

使用python模块计算

statisticnumpy包含了计算方差的方式

statistics.variance计算样本方差

1
2
3
4
5
6
7
>>> import statistics

>>> statistics.variance([50, 100, 100, 60, 50])
670

>>> statistics.variance([73, 70, 75, 72, 70])
4.5

numpy可以通过设置参数ddof参数来选择计算方式。默认是计算全局方差

计算全局方差(ddof=0)

1
2
3
4
5
>>> np.var([50, 100, 100, 60, 50])
536.0

>>> np.var([73, 70, 75, 72, 70])
3.6

计算样本方差(ddof=1)

1
2
3
4
5
>>> np.var([50, 100, 100, 60, 50], ddof=1)
670.0

>>> np.var([73, 70, 75, 72, 70], ddof=1)
4.5

扩展阅读

标准差(Standard Deviation)

参考百度百科

标准差(Standard Deviation), 中文环境中又常称均方差,用σ表示。标准差是方差的算术平方根。标准差能反映一个数据集的离散程度。平均数相同的两组数据,标准差未必相同。

标准差的计算公式为:

$$ \sigma = \sqrt{方差} = \sqrt{\frac{(X-\mu)^2}{N}} $$

同计算方差类似,计算标准差如下:

样本的标准差

1
2
3
4
5
>>> statistics.stdev([50, 100, 100, 60, 50])
25.88435821108957

>>> statistics.stdev([73, 70, 75, 72, 70])
2.1213203435596424

总体的样本差

1
2
3
4
5
>>> np.std([50, 100, 100, 60, 50])
23.15167380558045

>>> np.std([73, 70, 75, 72, 70])
1.8973665961010275

样本的标准差

1
2
3
4
5
>>> np.std([50, 100, 100, 60, 50], ddof=1)
25.88435821108957

>>> np.std([73, 70, 75, 72, 70], ddof=1)
2.1213203435596424

由标准差可以看出,虽然学生X, Y的平均分数相同(都是72分)

  • X: 50, 100, 100, 60, 50
  • Y: 73, 70, 75, 72, 70

但是,Y的标准差小于X的标准差。Y的考试成绩更稳定。

标准分数(Standard Score)

参考百度百科

标准分数也叫z分数(z-score),是一种具有相等单位的量数。它是将原始分数与团体的平均数之差除以标准差所得的商数,是以标准差为单位度量原始分数离开其平均数的分数之上多少个标准差,或是在平均数之下多少个标准差。它是一个抽象值,不受原始测量单位的影响,并可接受进一步的统计处理

计算公式为:

$$ z = \frac{x - \mu}{\sigma} $$

$x$为某一具体分数,$\mu$为平均数,$\sigma$为标准差。

使用场景

某中学高一班期末考试,已知语文期末考试的全班平均分为73分,标准差为7分,甲得了78分;数学期末考试的全班平均分为80分,标准差为6.5分,甲得了83分。甲哪一门考试成绩比较好?

因为两科期末考试的标准差不同,因此不能用原始分数直接比较。需要将原始分数转换成标准分数,然后进行比较。

Z(语文)=(78-73)/7=0.71
Z(数学)=(83-80)/6.5=0.46

甲的语文成绩在其整体分布中位于平均分之上0.71个标准差的地位,他的数学成绩在其整体分布中位于平均分之上0.46个标准差的地位。

由此可见,甲的语文期末考试成绩优于数学期末考试成绩。 由于标准分数不仅能表明原始分数在分布中的地位,它还是以标准差为单位的等距量表,故经过把原始分数转化为标准分数,可以在不同分布的各原始分数之间进行比较。

使用python模块计算

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
>>> from scipy import stats

>>> stats.zscore([50, 100, 100, 60, 50])
array([-0.95025527,  1.2094158 ,  1.2094158 , -0.51832106, -0.95025527])

>>> stats.zscore([73, 70, 75, 72, 70])
array([ 0.52704628, -1.05409255,  1.58113883,  0.        , -1.05409255])

>>> stats.zscore([50, 100, 100, 60, 50], ddof=1)
array([-0.84993415,  1.08173437,  1.08173437, -0.46360045, -0.84993415])

>>> stats.zscore([73, 70, 75, 72, 70], ddof=1)
array([ 0.47140452, -0.94280904,  1.41421356,  0.        , -0.94280904])

皮尔逊相关系数(Pearson Correlation Coefficient)

参考百度百科

相关系数是最早由统计学家卡尔·皮尔逊设计的统计指标,是研究变量之间线性相关程度的量,一般用字母 r 表示。由于研究对象的不同,相关系数有多种定义方式,较为常用的是皮尔逊相关系数。

需要说明的是,皮尔逊相关系数并不是唯一的相关系数,但是最常见的相关系数

定义1

两个变量之间的皮尔逊相关系数定义为两个变量之间的协方差和标准差的商

计算公式如下:

$$ P_{xy}=\frac{cov(X, Y)}{\sigma_x\sigma_y} $$

定义2

相关系数r亦可由$(X_i,Y_i)$样本点的标准分数均值估计

计算公式如下:

{% math %}

r_{xy} = \frac{1}{n}\sum\limits_{i=1}^n(Z_x)_i(Z_y)_i \\
= \frac{1}{n}\sum\limits_{i=1}^n\cdot\frac{x-\bar{x}}{\sqrt{\frac{1}{n}\sum\limits_{i=1}^n(x-\bar{x})^2}}\cdot\frac{y-\bar{y}}{\sqrt{\frac{1}{n}\sum\limits_{i=1}^n(y-\bar{y})^2}} \\
= \frac{\sum\limits_{i=1}^n(x_i-\bar{x})(y_i-\bar{y})}{\sqrt{\sum\limits_{i=1}^n(x-\bar{x})^2}\sqrt{\sum\limits_{i=1}^n(y-\bar{y})^2}}

{% endmath %}

其中$Z_x$为$x$的标准分数,其中$Z_y$为$y$的标准分数。$\bar{x}$为x的平均数,$\bar{y}$为y的平均数。

举个例子(来自李政轩老师的视频教程皮尔逊相关系数):

有学生A, B, C…G的数学成绩和自然成绩分别如下, 现在需要分析学生的数学成绩和自然成绩之间是否存在关系。比如学生数学成绩好的自然成绩也好?

相关系数

标准化成绩的计算方式如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
>>> from scipy import stats

>>> import numpy as np

# 设置打印3位小数
>>> np.set_printoptions(precision=3)

# 标准化数学成绩
>>> zscore_math = stats.zscore([74, 76, 77, 63, 63, 61, 72], ddof=1)

>>> zscore_math
array([ 0.667,  0.959,  1.105, -0.938, -0.938, -1.23 ,  0.375])

# 标准化自然成绩
>>> zscore_sciense = stats.zscore([84, 83, 85, 74, 75, 81, 73], ddof=1)

>>> zscore_sciense
array([ 0.92 ,  0.725,  1.116, -1.032, -0.837,  0.335, -1.227])

# 两个标准化成绩相乘
>>> dot_math_sciense = zscore_math * zscore_sciense

>>> dot_math_sciense
array([ 0.614,  0.695,  1.233,  0.968,  0.785, -0.412, -0.461])

相关系数

1
2
3
4
5
# 下面除以(n-1)是因为前面一直用样本方差来计算的
>>> r = sum(dot_math_sciense) / (7-1)

>>> r
0.5704948696393594

相关系数为0.570, 说明数学成绩和自然成绩之间没有什么关系 利用现成的库计算

1
2
3
4
5
6
7
# 返回的元组第一个数就是相关系数
>>> scipy.stats.pearsonr([74, 76, 77, 63, 63, 61, 72], [84, 83, 85, 74, 75, 81, 73])
(0.5704948696393595, 0.18107908965203987)

>>> np.corrcoef([74, 76, 77, 63, 63, 61, 72], [84, 83, 85, 74, 75, 81, 73])
array([[1.  , 0.57],
       [0.57, 1.  ]])

相关系数的特性

$$ -1 \leq r_{xy} \leq 1 $$

1表示完全正相关,-1表示完全负相关