你的收入和支出相关吗?

你的收入和支出相关吗?这是一个很难回答的问题,表面上看好像是相关的,因为随着收入的增长,有了更多的钱,当然可以有更多的支出。但是,很多公司一年才涨一次工资,在这一年内,物价却可能在不停上涨,是不是收入没涨而每个月的支出都在涨呢?

如何来回答是否相关的问题呢?用统计学的方法,我们可以把收入和支出当做两个变量来对待,然后用数学的方法衡量其相关性。

什么是相关性

两个变量之间存在关联关系即为相关。相关性是具有方向性的:可能为正,意味着两个变量同时表现出增大或减小;也可能为负,意味着当一个变量值增加时,另一个变量的值就会减少;也可能为零,即这些变量是不相关的。

  • 正相关:两个变量同时表现出增大或减小
  • 零相关:变量间的变化不存在相关
  • 负相关:变量当一个变量值增加时,另一个变量的值就会减少

为什么要研究相关性

研究相关性可以加深我们自己对于生活中的现象的理解。除此之外,在做机器学习模型时,如果存在两个或两个以上的变量紧密相关,那么一些算法的性能就会下降,例如线性回归(见多重共线性)。为了提高模型的性能,应该移除其中有干扰的相关变量。所以研究相关性还可以帮助我们更好的做机器学习模型。

如何表示变量相关性

协方差

如果有人对协方差不太熟,但方差应该是大家经常接触到的一个概念。

方差可以衡量一个变量的波动的剧烈程度,它的具体原理是用每一个变量的值去减去变量均值,然后分别求平方加和,即variance(X) = sum((x - mean(X)) ** 2) / len(X)。方差的用途很广泛,比如我们想知道所有中国人的收入(变量X)是否平均,我们就可以计算所有人收入的方差,从而衡量收入的波动程度,如果波动小,那么收入就较平均。

与方差对应的一个概念是标准差。在计算方差时,为了屏蔽掉差异的正负符号影响,我们添加了一个平方项,这就造成了方差不能反映真实的差异,而是反映了差异的一个平方。为了修正这种影响,我们将标注差做开方处理,于是就得到了标准差。其计算公式为:std(X) = variance(X) ** 0.5

协方差可以理解为方差的一种推广,他们都是通过衡量差异的方式来表示变量的性质的。事实上方差只是协方差的一种特殊形式。从上面的解释来看,方差是描述一个变量的,如果想描写两个变量的话,我们就要用协方差了。协方差的计算公式为cov(X) = sum((x - mean(X)) * (y - mean(Y))) / (len(X) - 1)(为什么这里要减一,可以看这里)。虽然名字里面都有方差,但是协方差却是用来衡量两个变量之间的相关性的。

如果两个变量之间具有正相关性(即两个变量同时表现出增大或减小),则从协方差定义可以看出其值为正。如果具有负相关性,则协方差为负。通过numpycov可以计算两个变量直接的协方差。示例如下:

1
2
3
4
5
6
7
8
9
import numpy as np
from numpy import cov

np.random.seed(1)
X = np.random.randn(1000) * 10 + 100
Y = np.random.randn(1000)

print(sum([(X[i] - X.mean()) * (Y[i] - Y.mean()) for i in range(len(X))]) / (len(X) - 1))
print(cov(X, Y)) # 输出协方差矩阵,表示所有变量两两之间的协方差

使用协方差,我们可以看出变量的相关性,但是却不好确定其相关的程度,因为它会受到变量取值范围的影响。如何屏蔽掉这种影响呢?需要用到皮尔森(Pearson)相关系数。

Pearson相关系数

为了抵消变量取值范围的影响,我们可以在计算时,引入一个除数。而标准差作为衡量变量差异的一个量,正好可以用来作为此除数。这就得到了Pearson相关系数。其计算公式为pearson_correlation_coefficient = cov(X, Y) / (std(X) * std(Y))

计算Pearson相关系数得到的数值是可以很好的解释的。该系数的取值在-1到1之间,该取值区间表示相关的范围,即从完全负相关到完全正相关,0表示无相关。一般而言,低于-0.5或高于0.5的值表示显著的相关,其他范围的值则表示不显著相关。

使用SciPy中的函数可以计算两个相同长度的数据样本的Pearson相关系数,示例如下:

1
2
3
4
5
6
7
8
9
10
import numpy as np
from scipy import stats

np.random.seed(1)
X = np.random.randn(1000) * 10 + 100
Y = np.random.randn(1000)
Y1 = X + Y

print(stats.pearsonr(X, Y))
print(stats.pearsonr(X, Y1))

运行这段代码可以得到Pearson相关系数为0.0220.995。它表示XY不相关,而XY1具有很高的相关性。这与我们生成的数据的方式是一致的。

Spearman相关系数

实际上Pearson相关系数有一个缺点,即它只能用于计算正态分布的两个变量且只能用于识别线性相关性(相关原理需要参考统计学知识)。为了应对这两种情况,除了Pearson相关系数,还可以用什么办法呢?其实还有一种类似的相关系数,即Spearman相关系数。

Spearman相关系数不直接用变量的值来进行计算,而是先计算变量的次序。次序即当前值在整个变量取值中的排名,比如变量X=[100,30,5,20,1],则次序为X_=[5,4,2,3,1]。通过引入次序,就屏蔽掉了非正态分布带来的取值差异影响。比如,班级考试得分排名,Spearman只考虑排名位置,即谁是第一名和谁是第二名,而不考虑他们的得分,无论第一名和第二名相差是30分还是3分计算结果都一样。

Spearman相关系数计算公式为spearman_correlation_coefficient = cov(rank(X), rank(Y)) / (std(rank(X)) * std(rank(Y)))

使用SciPy来计算Spearman相关系数,示例如下:

1
2
3
4
5
6
7
8
9
10
import numpy as np
from scipy import stats

np.random.seed(1)
X = np.random.exponential(2, 1000)
Y = np.random.randn(1000)
Y1 = X + Y

print(stats.spearmanr(X, Y))
print(stats.spearmanr(X, Y1))

这里计算得到的Spearman相关系数值为0.0100.993。它表示XY不相关,而XY1具有很高的相关性。这与我们生成的数据的方式是一致的。

总结

有了这里的相关性计算方式,对于题目中的收入和支出的关系问题,我们就可以用数学的方式来回答了。当然,这还需要我们先去搜集一下数据。