计算协方差和相关系数

方差是协方差的一种特殊形式。如果计算同一个变量的协方差,实际上就成了方差。

但在numpy里有一个参数要注意,ddof:delta degree of freedom,也就是计算方差和协方差时候,除数用n还是n-1的问题。

在这里,ddof,直译叫自由度偏差。ddof=0表示用n,ddof=1表示用n-1。

numpy中的函数,对于这个值默认并不统一,有的默认值是0,有的是1(具体要看文档说明)

 

1. 试一下单个变量的方差和协方差:

>>> x1 = np.array([42, 52, 48, 58])

>>> np.var(x1)  // 方差,默认ddof=0
34.0
>>> np.var(x1, ddof=1)
45.333333333333336

>>> sum((x1 - np.mean(x1)) ** 2) / len(x1)
34.0

 

>>> np.cov(x1)  // 协方差,默认ddof=None,效果上看就是1
array(45.33333333333333)
>>> np.cov(x1, ddof=0)
array(34.0)

 

2. 上面计算的协方差只是一个变量的,算出来是一个数字。有多个变量的时候,就可以计算不同变量之间的协方差了。

如果有p个变量,i, j都从0到p-1,协方差矩阵S是一个p x p的方阵。元素S(i, j) 表示第i和变量和第j个变量的协方差。

因为协方差的定义,交换顺序结果一样,所以S(i, j) == S(j, i)。右上三角和左下三角是对称的。

对角线S(i, i)实际上就是第i个变量的方差。

>>> x1 = np.array([42, 52, 48, 58])

>>> x2 = np.array([4, 5, 4, 3])

>>> np.var(x1), np.var(x2)
(34.0, 0.5)

>>> np.mean((x1 - np.mean(x1)) * (x2 - np.mean(x2)))
-1.5

>>> np.cov(x1, x2, ddof=0)
array([[ 34. , -1.5],
          [ -1.5, 0.5]])

 

有的文章会出现以下这种矩阵的形式: 

>>> X = np.array([[42, 52, 48, 58],

                             [ 4,  5,  4,  3]], dtype=np.float64).T

>>> X
array([[42, 4],
          [52, 5],
          [48, 4],
          [58, 3]])

>>> X -= np.mean(X, axis=0)

>>> np.dot(X.T, X) / X.shape[0]
array([[ 34. , -1.5],
          [ -1.5, 0.5]])

仔细对一下矩阵形式,三个步骤:1)减去均值,2)变量转置相乘并求和(矩阵乘法),3)除以n

 

3. 相关系数是标准化的协方差。它等于协方差除以两个变量标准差的乘积。得到的值在[-1, 1]之间,表示两个变量的线性相关程度。

如果等于0,表达两个变量线性无关。>0表示线性正相关,<0表示线性负相关。数值越大,表示相关的程度越明显。

它只是指“线性”相关,

1)有可能存在一些非线性的关系,用这个数值无法来衡量。

2)也可能计算出来相关,但实际上变量没有什么关系,因为相关系数对于异常值很敏感。

>>> np.corrcoef(x1, x2)
array([[ 1. , -0.36380344],
          [-0.36380344, 1. ]])
>>> -1.5 / np.std(x1) / np.std(x2)
-0.3638034375544994

一般用r来表示相关系数,它和ddof没有关系。在标准化的时候,上下约掉了。

posted on 2017-02-20 20:15  hankh  阅读(852)  评论(0编辑  收藏  举报