目录
一、PCA介绍
1.PCA概念
PCA全称Principal Component Analysis,又叫做主成分分析。这是一种多元统计方法,用于从多个变量中提取和识别最重要的信息。PCA的主要目的是通过减少数据的维度来简化数据集,同时尽可能保留数据集中的重要特征。
2.PCA的基本流程
获得数据:这是PCA的第一步,需要收集和整理需要进行主成分分析的数据。
减去平均值:在进行PCA之前,需要将每个数据点减去其相应变量的平均值,以使均值为0。
计算协方差矩阵:这是PCA中一个关键步骤,通过计算数据的协方差矩阵来量化数据之间的相关性。
计算特征值和特征向量:这一步涉及到对协方差矩阵进行特征分解,以找出数据的主成分。特征值和特征向量可以通过多种数学方法计算得出。
选择主成分:根据特征值的大小选择主成分。通常选择前几个最大的特征值对应的特征向量作为主成分。
投影数据:将原始数据投影到选定的主成分上,得到降维后的数据。
可视化结果:将降维后的数据可视化,以便更好地理解和分析数据。
3.PCA原理
从直觉上看,PCA主成分分析类似于依次寻找一群样本点的各个位置差异最大的方向长轴。假定把一个人身上的所有细胞看成一个一个的样本点。这些样本点可以用3个坐标来表示,从左到右为x方向,从前到后为y方向,从下到上为z方向。
第一个主成分对应的长轴是沿着人的脚到头的方向,也就是通常的上下方向,即z方向。这个方向是最主要的长轴。这些样本点的位置差异基本上70%以上来自于这个方向上的差异。
第二个主成分对应的方向是沿着人的左臂到右臂的方向,也就通常的左右方向,即y方向。这个方向和第一个主成分长轴垂直,这些样本点的位置差异大概有20%左右来自这个方向上的差异。
第三个主成分方向是沿着人的前胸到后背的方向,也就是通常的前后方向,即x方向。这个方向和前两个主成分长轴垂直,样本点的位置差异有一般只有不到10%来自这个方向的差异,当然,有些身材比较圆润的同学除外。
现在,如果要将这些样本点的坐标减少到用2个来表示,并尽可能多的保留样本点之间位置差异的信息,那么,显然,应该保留第一个主成分坐标和第二个主成分坐标。假定这个人躺在一个斜的躺椅上,那么现在这些样本点的第一主成分显然不再是从下到上的z方向。我们应该将我们的坐标系作一个旋转,让z轴和斜着的躺椅方向一致,这个新的z方向是这些样本点的第一主成分方向。类似地,也需要旋转x轴和y轴得到新的第二主成分方向和第三主成分方向。
这个旋转旧坐标系以找到主成分方向的过程就是PCA主成分分析。
PCA主成分分析是一种通过正交线性组合方式,最大化保留样本间方差的降维方法。用几何观点来看,PCA主成分分析方法可以看成通过正交变换,对坐标系进行旋转和平移,并保留样本点投影坐标方差最大的前几个新的坐标。
二、PCA算法
1.协方差和散度矩阵
样本均值:
样本方差:
样本X和样本Y的协方差:
由上面的公式,我们可以得到以下结论:
(1) 方差的计算公式是针对一维特征,即针对同一特征不同样本的取值来进行计算得到;而协方差则必须要求至少满足二维特征;方差是协方差的特殊情况。
(2) 方差和协方差的除数是n-1,这是为了得到方差和协方差的无偏估计。
协方差为正时,说明X和Y是正相关关系;协方差为负时,说明X和Y是负相关关系;协方差为0时,说明X和Y是相互独立。Cov(X,X)就是X的方差。当样本是n维数据时,它们的协方差实际上是协方差矩阵(对称方阵)。例如,对于3维数据(x,y,z),计算它的协方差就是:
散度矩阵定义为:
2.基于特征值分解协方差矩阵实现PCA算法
输入:数据集 ,需要降到k维。
1) 去平均值(即去中心化),即每一位特征减去各自的平均值。
2) 计算协方差矩阵 ,注:这里除或不除样本数量n或n-1,其实对求出的特征向量没有影响。
3) 用特征值分解方法求协方差矩阵 的特征值与特征向量。
4) 对特征值从大到小排序,选择其中最大的k个。然后将其对应的k个特征向量分别作为行向量组成特征向量矩阵P。
5) 将数据转换到k个特征向量构建的新空间中,即Y=PX。
关于为什么用特征值分解矩阵,是因为 是方阵,能很轻松的求出特征值与特征向量。当然,用奇异值分解也可以,是求特征值与特征向量的另一种方法。
3.基于SVD分解协方差矩阵实现PCA算法
输入:数据集 ,需要降到k维。
1) 去平均值,即每一位特征减去各自的平均值。
2) 计算协方差矩阵。
3) 通过SVD计算协方差矩阵的特征值与特征向量。
4) 对特征值从大到小排序,选择其中最大的k个。然后将其对应的k个特征向量分别作为列向量组成特征向量矩阵。
5) 将数据转换到k个特征向量构建的新空间中。
在PCA降维中,我们需要找到样本协方差矩阵 的最大k个特征向量,然后用这最大的k个特征向量组成的矩阵来做低维投影降维。可以看出,在这个过程中需要先求出协方差矩阵,当样本数多、样本特征数也多的时候,这个计算还是很大的。当我们用到SVD分解协方差矩阵的时候,SVD有两个好处:
1) 有一些SVD的实现算法可以先不求出协方差矩阵也能求出我们的右奇异矩阵V。也就是说,我们的PCA算法可以不用做特征分解而是通过SVD来完成,这个方法在样本量很大的时候很有效。实际上,scikit-learn的PCA算法的背后真正的实现就是用的SVD,而不是特征值分解。
2)注意到PCA仅仅使用了我们SVD的左奇异矩阵,没有使用到右奇异值矩阵,那么右奇异值矩阵有什么用呢?
假设我们的样本是m*n的矩阵X,如果我们通过SVD找到了矩阵XtX 最大的k个特征向量组成的k*n的矩阵Vt ,则我们可以做如下处理:
可以得到一个m*k的矩阵X',这个矩阵和我们原来m*n的矩阵X相比,列数从n减到了k,可见对列数进行了压缩。也就是说,左奇异矩阵可以用于对行数的压缩;右奇异矩阵可以用于对列(即特征维度)的压缩。这就是我们用SVD分解协方差矩阵实现PCA可以得到两个方向的PCA降维(即行和列两个方向)。
三、PCA实现
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.datasets import load_iris
import numpy as np
data = load_iris()
y = data.target
x = data.data
pca = PCA(n_components=2)
reduced_x = pca.fit_transform(x)
# reduced_x = np.dot(reduced_x, pca.components_) + pca.mean_
red_x, red_y = [], []
blue_x, blue_y = [], []
green_x, green_y = [], []
# print(reduced_x)
for i in range(len(reduced_x)):
if y[i] == 0:
red_x.append(reduced_x[i][0])
red_y.append(reduced_x[i][1])
elif y[i] == 1:
blue_x.append(reduced_x[i][0])
blue_y.append(reduced_x[i][1])
else:
green_x.append(reduced_x[i][0])
green_y.append(reduced_x[i][1])
plt.scatter(red_x, red_y, c='r', marker='x')
plt.scatter(blue_x, blue_y, c='b', marker='D')
plt.scatter(green_x, green_y, c='g', marker='.')
plt.show()
四、总结
PCA是一种通过找到并使用数据的最大方差方向来简化数据集的统计技术。它通过将数据投影到由数据集的主成分构成的新空间来降低数据的维度,同时保留数据中的重要特征。PCA广泛应用于各种领域,如机器学习、数据挖掘、图像处理等。