方差是协方差的一种特殊形式。如果计算同一个变量的协方差,实际上就成了方差。
但在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没有关系。在标准化的时候,上下约掉了。