深入理解“协方差矩阵”(python模拟)
协方差矩阵时机器学习中常用的概念,应该是像是牛顿三大定律一样章口就莱。但是真当用到的时候却还是模棱两可,需要重新查资料确认,这次就写一篇文章一次性给自己说清楚,也争取能给大家说清楚。
方差和协方差
先弄清楚方差和协方差才能深入理解协方差矩阵(以下给出的均为统计学中的定义)
方差:是用来度量单个随机变量的变化程度(也称离散程度)
协方差:用于衡量两个随机变量总体变化程度。
有的地方说:“协方差刻画两个随机变量的相似程度”,这种表述是不够准确的,可以说:“刻画两个随机变量偏离各自期望的的程度的程度”。这么说就很绕,下面给出百度百科的解释
如果两个变量的变化趋势一致,也就是说如果其中一个大于自身的期望值,另外一个也大于自身的期望值,那么两个变量之间的协方差就是正值。 如果两个变量的变化趋势相反,即其中一个大于自身的期望值,另外一个却小于自身的期望值,那么两个变量之间的协方差就是负值。(百度百科)
网上还有一种比喻就是说方差就像是在一群人中衡量一个人的身高;而协方差是在一群中衡量一个人的升高和体重(也许对有些人会比较好理解,下面的说明也会用到这个例子)
下面给出方差的方程:
式中 是样本的数量(上例中人群的总人数);是所有随机数的平均值(人群的平均身高),通常是向量表示。
协方差的公式如下:
变量的含意和方差的差不多(两个变量 可以分别表示升高和体重)。
乍一看总感觉方差的方程式和协方差的方程式有点夫妻相。
没错,方差就是协方差的一种特殊形式,当两个变量相同时,协方差就是方差了。
协方差矩阵
知道了方差和协方差的定义之后,我们假设现在有 个随机变量 (比如说身高、体重、年龄… …);依然有 观测样本( 个人),那么 ( ) 表示随机变量 中的第 个样本(第 个人身高)
于是根据协方差的定义我们可以求出两两之间的协方差,所有变量两两之间的协方差按照顺序排列起来,就构成协方差矩阵
为了方便理解和,我们将 个随机变量写成向量的形式
通过向量相乘的法则我们知道,要想让一个向量的每两个元素都一一相乘,只需要让这个向量乘它自己的转置
那么协方差矩阵就可以这么定义:
即
从上式可以看出,协方差矩阵中对角线上元素就是各个随机变量的方差,非对角线上的就是两两随机变量之间的协方差,由于是向量与其本身的转置相乘得到的,因此可以确定:协方差矩阵是大小为 的 对称矩阵.
接下来我们用python+nunpy来模拟一下(为了方便展示,这里只用两个随机变量)
import numpy as np
import matplotlib.pyplot as plt
#使用plt自带样式进行美化
plt.style.use("ggplot")
#设置字体显示中文
plt.rcParams['font.sans-serif']=['SimHei']
#显示负号
plt.rcParams['axes.unicode_minus']=False
#设置图像显示大小
plt.rcParams['figure.figsize']=(8,8)
#各取500个标准正态分布的数据
x1=np.random.normal(0,1,500)
x2=np.random.normal(0,1,500)
#将x1,x2以向量的形式排列起来
X=np.vstack((x1,x2)).T
plt.scatter(X[:,0],X[:,1])
plt.title("x1,x2的点图")
plt.axis('equal')
plt.show
接下来算一下协方差矩阵
#计算协方差
def cov(x1,x2):
x1mean,x2mean=x1.mean(),x2.mean()
Sigma=np.sum((x1-x1mean)*(x2-x2mean))/(len(x1)-1)
return Sigma
#协方差矩阵
def covMatrix(X):
matrix=np.array([[cov(X[0],X[0]),cov(X[0],X[1])],[cov(X[1],X[0]),cov(X[1],X[1])]])
return matrix
covMatrix(X)
#output
'''
array([[0.00437243, 0.0433571 ],
[0.0433571 , 0.42993022]])
'''
由于我们取的方差均为1,期望为0,所以我们得到的协方差矩阵就应该是
而 和 与等于1,这与输出一样
线性变换
对矩阵的线性变换主要是通过矩阵的相乘得到的,通过将矩阵乘一个 Scaling Matrix 可以将矩阵线性化,在通过乘一个 Rotation Matrix 将矩阵旋转。
这里定义Scaling Matrix:
所以经过线性变换后的矩阵为:
这也就意味着我们可以从我们新的协方差方程中提取出我们的scaling matrix 通过:。同时,这种线性的变换其实就是
定义rotation matrix:
其中是绕顺时针旋转的角度
于是,就有了transformation matrix,就是scaling matrix 和 rotation matrix 的乘积,给出变换矩阵 的定义:
综上,协方差矩阵的线性变换就是协方差矩阵乘上变换矩阵,即:
下面用代码演示以下
#线性转换:
def linear_trans(X,sx,sy,theta):
X = X-np.mean(X,0)
S=np.array([[sx,0],[0,sy]])
R=np.array([[np.cos(theta),-np.sin(theta)],[np.sin(theta),np.cos(theta)]])
Y=X.dot(S)
A=S @ R
plt.scatter(Y[:,0],Y[:,1])
plt.scatter(X.dot(A)[:,0],X.dot(A)[:,1])
plt.title("转换之后的矩阵")
plt.axis('equal')
plt.show
return Y,X.dot(A)
Y,SIGMA=linear_trans(X,0.7,3.4,0.25*np.pi)
print(covMatrix(Y))
'''
[[ 0.74757612 -0.39267912]
[-0.39267912 0.20626247]]
'''
print(covMatrix(SIGMA))
'''
[[0.10609819 0.18799412]
[0.18799412 0.33310456]]
'''
参考:https://janakiev.com/blog/covariance-matrix/
来源:CSDN
作者:小小秃头怪
链接:https://blog.csdn.net/weixin_41203075/article/details/104402530