机器学习-主成分分析
主成分分析
主成分:假设在三维空间中的一系列数据分布在一个二维平面上,如果使用正常的自然坐标系表示,那么需要三个坐标来表示,但是如果将坐标轴通过变换,使得数据所在的平面与$xOy$平面重合,则可以通过$x'$,$y'$两个维度表示原始数据,并且没有任何的损失,如此便完成了数据的降维。
比如,$a_1\left(1,1,2 \right), a_2\left(3,-2,1 \right), a_3\left(2,3,5 \right), a_4\left(5,-1,4 \right)$位于平面$z = x+y$上,如果使用普通坐标系进行表示,则需要$x,y,z$三个坐标轴表示。
但是如果利用坐标轴变换 $x' = x$, $y' = y-z$, 则可以使用$x',y'$两个坐标轴表示:$a_1'\left(1,-1 \right), a_2'\left(3,-3 \right), a_3'\left(2,-2 \right), a_4'\left(5,-5 \right)$
主成分分析通过将原始数据映射到一个低维超平面来降低数据的维度。其主要思想源于信号处理领域,即在信号处理领域,认为信号具有较大的方差,噪声具有较小的方差,信号与噪声之比称为信噪比。信噪比越大意味着数据的质量越好。反之,信噪比越小意味着数据的质量越差。因此,主成分分析方法主要通过将高维数据映射到一个特殊的低维超平面,在此超平面上,数据的方差最大,即在此平面上数据的分布更散,即主成分分析的目标是最大化投影方差。
对于给定的一组数据点:$\left \{ \mathit{v_1,v_2,...,v_n}\right \}$,其中所有的向量都是列向量,中心化后表示为:
$\left \{ \mathit{x_1,x_2,...,x_n}\right \}=\left \{ \mathit{v_1-\mu,v_2-\mu,...,v_n-\mu}\right \}$,其中$\mu =\frac{1}{n}\sum _{i=1}^{n}v_i$。
由于向量内积的几何意义是第一个向量投影在第二个向量的长度,因此$x_i$在$\omega$(单位方向向量)上的的投影$(x_i,\omega ) = x_i^{T}\omega $。因此其目标就是找到一个投影方向$\omega$,使得,$\left \{ \mathit{x_1,x_2,...,x_n}\right \}$ 在$\omega$上的投影的方差最大化。
如何寻找投影方向?
由于投影后的均值为0 [1],因此投影后的方差可以表示为:
$D(x) = E(x-E(x))^2 = E(x^2) = \frac{1}{n}\sum _{i=1}^{n}(x_i^{T}\omega)^2 =\frac{1}{n}\sum _{i=1}^{n}\omega ^{T}x_ix_{i}^{T}\omega$
其中,$\frac{1}{n}\sum _{i=1}^{n}x_ix_{i}^{T}$是样本协方差[2],将其写作$\Sigma$,$\omega$是单位向量,$\omega^{T}\omega=1$。因此寻找投影方向转化为一个最优化问题:
$\begin{matrix}
\\max{\omega ^{T}\Sigma \omega }
\\s.t.\; \; \omega ^{T} \omega=1
\end{matrix}$
则引入拉格朗日乘子,并对$\omega$求导令其为0,可以推出$\Sigma \omega = \lambda \omega$。带入$D(x)$,有
$D(x) = \omega ^{T}\Sigma \omega = \lambda \omega^{T} \omega$
即,$x$投影后的方差就是协方差矩阵的特征值,特别的,最大的方差就是协方差矩阵的最大特征值,最佳的投影方向就是最大特征值对应的特征向量。次佳投影方向位于最佳投影方向的正交空间中,是第二大特征值对应的特征向量。以此类推。由此便可以得到主成分分析的求解方法。
PCA求解方法
- 对样本数据进行中心化处理
- 求样本协方差矩阵
- 对协方差矩阵进行特征值分解,将特征值从大到小排序
- 去特征的前d大对应的特征向量$\omega_1,...,\omega_d$,通过以下映射将$n$维样本映射到$d$维
$x_i'=\begin{bmatrix}
\omega_1^{T}x_i\\
\omega_2^{T}x_i\\
...\\
\omega_d^{T}x_i
\end{bmatrix}$
新的$x_i'$的第$d$维就是$x_i$在第$d$个主成分$\omega_d$方向上的投影,通过选取最大的$d$个特征值对应的特征向量,
将方差较小的特征(噪声)放弃,使得每个$n$维列向量$x_i$被映射成为$d$维的新的列向量$x_i'$,定义降维后的信息占比为
$\eta =\sqrt{\frac{\sum_{i=1}^{d}\lambda _{i}^{2}}{\sum_{i=1}^{n}\lambda _{i}^{2}}}$
Python 实现代码
手写代码实现:
#计算均值,要求输入数据为numpy的矩阵格式,行表示样本数,列表示特征 def meanX(dataX): return np.mean(dataX,axis=0)#axis=0表示依照列来求均值。假设输入list,则axis=1 def pca(XMatrix,k): ''' XMatrix: 原始样本矩阵,每一列代表一个样本 k:主成分的个数 return finalData: 降维的数据输出 ''' average = meanX(XMatrix) m,n = np.shape(XMatrix) data_adjust = [] avgs = np.tile(average,(m,1)) data_adjust = XMatrix-avgs #中心化 covX = np.cov(data_adjust.T) #样本协方差矩阵 flambda,fomega = np.linalg.eig(covX) #特征值与特征向量 index = np.argsort(-flambda) #从大到小排序 finalData = [] if k>n: print ("k must lower than feature number") return else: selectomega = np,matrix(fomega.T[index[:k]]) finalData = data_adjust * selectomega.T #最终的调整后的数据return finalData
基于sklearn的实现
from sklearn.decomposition import PCA estimator = PCA(n_components=5) #n_components 主成分维度 X_pca=estimator.fit_transform(X_digits) #x_digits原始数据,x_pca输出数据
[1] $\mu' = \frac{1}{n}\sum _{i=1}^{n}x_i^{T}\omega = \left (\frac{1}{n}\sum _{i=1}^{n}x_i^{T} \right )\omega =\frac{1}{n}\left ( v_1+v_2+...+v_n-n\mu \right )\omega =0$
[2] $Cov(X,X) = E(X-EX)(X-EX) = E(XX^T)$
参考文献
[1] 百面机器学习-算法工程师带你去面试,葫芦娃,人民邮电出版社。
[2] https://www.cnblogs.com/youngsea/p/9334773.html
[3] https://www.cnblogs.com/clnchanpin/p/7199713.html