一、介绍
PCA(PrincipalComponents Analysis)即主成分分析,常用于对多变量(变量之间具有相关性时)降维的方法,由于各变量之间存在一定的相关关系,因此可以考虑将关系紧密的变量变成尽可能少的新变量,使这些新变量是两两不相关的,将各个变量综合为少数若干个有代表性的变量。怎样衡量有代表性的变量(特征)?(学术——工业:变量——特征)
- 能代表原始特征的绝大部分信息
- 组合后的特征互不相关
例如:图像识别中,设想如果一幅图像有300个特征点,每个特征点又有一个相应的描述该特征点的128维的向量,那么该幅图像就有300*vector(128维)个,那么整个图像识别模型的训练的复杂度相当高。如果我们对每个向量进行PCA处理,将其降维为64维,整个处理的复杂度便会大大降低。但是,很多人不知道具体的原理,现在结合具体的案例从推导到应用来理解PCA。
二、原理
2.1 统计学的一些性质
期望的性质
- E(kx) = kE(x)
- E(x+y) = E(x) + E(y)
若x和y相互独立:E(xy) = E(x)E(y);若E(xy) = E(x)E(y),不能推出x,y相互独立,只能说x,y不想关。
协方差
- Cov(x,y) = E(xy) - E(x)E(y)
当 cov(X, Y)>0时,表明 X与Y 正相关;
当 cov(X, Y)<0时,表明X与Y负相关;
当 cov(X, Y)=0时,表明X与Y不相关。
向量夹角与协方差
n维向量x和y的夹角记作,根据余弦定理,其余弦值为:
这两个向量的相关系数为: 比较上述两个式子,可知余弦值即将相关系x,y向量各自平移到原点后夹角余弦。
2.2 PCA过程
- 样本矩阵的协方差必然是对称阵,协方差的元素即各个特征间相关性的度量(具体实践中考虑是否去均值化)。
- 对于协方差矩阵,对角线上是方差、非对角线上是协方差。协方差为0时两者独立,协方差绝对值越大两者对彼此的影响越大。
- 将协方差矩阵C的特征向量组成P,可以将C合同为对角矩阵D(),对角矩阵D的对角元素即为A的特征值。
协方差矩阵的特征向量,进行单位化(即向量的模为1),从而P使标准正交的.
将特征间线性加权,使得加权后的特征组合间是不相关的,选前k(k是由用户进行决定的,即降维至k维)个最大的
特征值对应的特征向量来代替原始向量.
2.3 PCA核心推导
矩阵和向量的乘积:
对于n个特征的m个样本,其矩阵为:
取单位矩阵U(U的模为1),计算A*U为:
计算向量的方差:
对于得到的向量AU,求该向量的方差,假定AU是取均值化的,即AU的均值为0。
方差和特征值:
令方差为则得到 ,推出,当A中的列向量取均值化时,即为A的协方差矩阵,由此可知U是的一个特征向量,的值得大小为原始数据的特征值在向量U上的方向上投影值得方差。最终选择若干最大得特征值对应得特征向量来表示原始向量。
2.4 PCA实现
- 协方差公式
- 假设我们的数据集是一个具有3个特征即三个维度,的样本则协方差矩阵如下,协方差矩阵是一个对称的矩阵,而且对角线是各个维度上的方差。
- 计算协方差矩阵的特征向量和特征值。
- 选择成分组成模式矢量,求出协方差矩阵的特征值及特征向量之后,按照特征值由大到小进行排列,这将给出成分的重要性级别,再选择前k个特征值对应的特征向量作为我们的转换矩阵。注:(现在假设我们的原始数据是现在需要降至维,协方差矩阵为)
2.5 两个重要问题
- 为什么求协方差矩阵的特征向量,取前k个就是最理想的?
- 原始数据与转换矩阵*的乘积意义?也就是投影的意义?
对于1,方差大小描述的是一个变量的信息量,类似于混合两种气体的密闭性空间,空间里面的气体分子越不稳定,表明它的熵越大。而一组数据集,不同维度的数据方差越大,表明两种合起来所包含的信息量越大。(个人理解)
对于2,最后所求的k维特征矩阵,是能够代表原始特征的绝大部分信息。将数据从原空间投影到选择的k维特征空间中,实现特征的压缩,当然会损失掉部分信息,但是大大减少了复杂度同时也减少了噪音。
2.6 PCA小结
PCA的全部工作简单点说,就是对原始的空间中顺序地找一组相互正交的坐标轴,第一个轴是使得方差最大的,第二个轴是在与第一个轴正交的平面中使得方差最大的,第三个轴是在与第1、2个轴正交的平面中方差最大的,这样假设在N维空间中,我们可以找到N个这样的坐标轴,我们取前r个去近似这个空间,这样就从一个N维的空间压缩到r维的空间了,但是我们选择的r个坐标轴能够使得空间的压缩使得数据的损失最小。——借鉴于其他
三、乳腺癌案例
1. 导入库
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from sklearn.datasets.samples_generator import make_blobs
2. 加载数据集并可视化
X, y = make_blobs(n_samples=1000, n_features=3, centers=[[3,3, 3], [0,0,0], [1,1,1], [2,2,2]], cluster_std=[0.2, 0.1, 0.2, 0.2],
random_state =9)
fig = plt.figure()
ax = Axes3D(fig, rect=[0, 0, 1, 1], elev=30, azim=20)
plt.scatter(X[:, 0], X[:, 1], X[:, 2],marker='o')
3. 调用np.Cov()函数生成协方差矩阵,再使用np.linalg.eig()返回特征值、特征向量
cov_X = np.cov(X.T)
print(cov_X.shape)
eigVals,eigVects=np.linalg.eig(np.mat(cov_X))
print(eigVals)
print(eigVects)
4.特征值大到小,排序选择前k个特征值对应的特征向量
k = 2
sorted_indices = np.argsort(eigVals)
topk_evecs = eigVects[:,sorted_indices[:-k-1:-1]]
index = np.argsort(-eigVals) #依照featValue进行从大到小排序
selectVec = np.matrix(topk_evecs.T[index[:k]])
print(selectVec)
'''
output:
(2, 3)
([[-0.57654564, -0.58173155, -0.57374518],
[-0.67638533, 0.73373894, -0.0642656 ]])
'''
5. 对原数据进行降维处理,降维之后的原数据图由30维降至2维
X_pca = np.dot(X,selectVec.T)
print(X_pca)
plt.scatter(X_pca[:, 0].tolist(), X_pca[:, 1].tolist(),marker='o')