使用 Numpy 和 TensorFlow 计算协方差矩阵

文章目录

  • 协方差矩阵
  • Numpy计算协方差矩阵
  • Tensorflow计算协方差矩阵

协方差矩阵

我们都知道,方差是用来描述数据离散程度的,但那是在一维的情况下,当遇到多维数据的时候,我们可以为每一维度计算各自的方差。然而, 每一维度的数据并不会是独立的,比如身高和体重就存在一定的关联,如果我们只考虑各个维度的方差,难免会丢失一些信息,因此,便引入了协方差矩阵
我们先来看看协方差矩阵的数学公式定义:
cov ⁡ ( X , Y ) = ∑ i = 1 n ( X i − X ‾ ) ( Y i − Y ‾ ) n − 1 \operatorname{cov}(\mathrm{X}, \mathrm{Y})=\frac{\sum_{\mathrm{i}=1}^{\mathrm{n}}\left(\mathrm{X}_{\mathrm{i}}-\overline{\mathrm{X}}\right)\left(\mathrm{Y}_{\mathrm{i}}-\overline{\mathrm{Y}}\right)}{\mathrm{n}-1} cov(X,Y)=n1i=1n(XiX)(YiY)
在这里我们假设有 N N N个样本,每个样本是 M M M维向量,那么这 N N N个样本的协方差矩阵应该是一个 M ∗ M M * M MM的矩阵,矩阵中的每一个元素 ( i , j ) (i,j) (i,j)代表第 i i i维和第 j j j维之间的协方差,因此,矩阵主对角线的值应该是每一维数据的方差。
当遇到实际要计算协方差矩阵的时候,你可能会觉得十分复杂,没事,python早已有人帮你写好了!

Numpy计算协方差矩阵

在Numpy中,已经写好了计算协方差矩阵的函数:np.cov,下面我们来调用试试吧
首先假设我们有5个样本,每个样本是3维的数据,样本数据如下:

import numpy as np

data = np.array([[1, 4, 2], [5, 6, 24], [15, 1, 5], [7,3,8], [9,4,7]])

print(data)打印出来如下:

[[ 1  4  2]
 [ 5  6 24]
 [15  1  5]
 [ 7  3  8]
 [ 9  4  7]]

计算协方差矩阵:

np_cov = np.cov(data.T, bias=False)

print(np_cov)打印出来如下:

[[26.8  -6.8  -6.1 ]
[-6.8   3.3  10.85]
[-6.1  10.85 73.7 ]]

这里要注意的是np.cov()函数,在你传入的数据时候需要进行矩阵转置,因为它默认每一列是一个样本,每一行才是样本的维度,同时bias的值默认归一化False N − 1 N-1 N1,如果bias为True,则归一化为 N N N。其中 N N N为给定的观测次数,也就是样本的数量。


Tensorflow计算协方差矩阵

我们知道Tensorflow中每个变量都是一个Tensor,因此无法使用numpy包进行处理(或者处理比较麻烦),于是,干脆自己写一个计算协方差矩阵的函数。按照协方差矩阵的定义:

import tensorflow as tf

def tf_cov(x):
    mean_x = tf.reduce_mean(x, axis=0, keepdims=True)
    cov_xx = tf.matmul(tf.transpose(x-mean_x), x-mean_x)/tf.cast(tf.shape(x)[0]-1, tf.float64)
    return cov_xx

我们试着调用一下这个函数tf_cov()

data = np.array([[1, 4, 2], [5, 6, 24], [15, 1, 5], [7,3,8], [9,4,7]])

with tf.Session() as sess:
    print(sess.run(tf_cov(tf.constant(data, dtype=tf.float64))))

结果显示:

[[26.8  -6.8  -6.1 ]
 [-6.8   3.3  10.85]
 [-6.1  10.85 73.7 ]]

和上面一样的结果!
记住这里,bias如果为True则代码中

cov_xx = tf.matmul(tf.transpose(x-mean_x), x-mean_x)/tf.cast(tf.shape(x)[0]-1, tf.float64)

应该改为:

cov_xx = tf.matmul(tf.transpose(x-mean_x), x-mean_x)/tf.cast(tf.shape(x)[0], tf.float64)

即去掉-1.


至此,我们完成了对协方差矩阵的计算,协方差矩阵在机器学习中有着很大的左右,例如计算马氏距离等等。这些就留着过后进行探索了。

你可能感兴趣的:(Tensorflow)