特征值分解协方差矩阵实现PCA

您所在的位置:网站首页 pca协方差矩阵怎么计算 特征值分解协方差矩阵实现PCA

特征值分解协方差矩阵实现PCA

#特征值分解协方差矩阵实现PCA| 来源: 网络整理| 查看: 265

PCA(Principal Component Analysis),即主成分分析方法,是一种使用最广泛的数据降维算法。

PCA的主要思想

将n维特征映射到k维上,这k维是全新的正交特征,也被称为主成分,是在原有n维特征的基础上重新构造出来的k维特征。

PCA工作流程:方差最大化

PCA的工作就是从原始的空间中顺序地找一组相互正交的坐标轴,新的坐标轴的选择与数据本身是密切相关的。其中,第一个新坐标轴选择是原始数据中方差最大的方向,第二个新坐标轴选取是与第一个坐标轴正交的平面中使得方差最大的,第三个轴是与第1,2个轴正交的平面中方差最大的。依次类推,可以得到n个这样的坐标轴。通过这种方式获得的新的坐标轴,我们发现,大部分方差都包含在前面k个坐标轴中,后面的坐标轴所含的方差几乎为0。于是,我们可以忽略余下的坐标轴,只保留前面k个含有绝大部分方差的坐标轴。这相当于只保留包含绝大部分方差的维度特征,而忽略包含方差几乎为0的特征维度,实现对数据特征的降维处理。

如何得到这些包含最大差异性的主成分方向呢?

通过计算数据矩阵的协方差矩阵,然后得到协方差矩阵的特征值和特征向量,选择特征值最大(即方差最大)的k个特征所对应的特征向量组成的矩阵。这样就可以将数据矩阵转换到新的空间当中,实现数据特征的降维。

协方差定义

X、Y是两个随机变量,$X、Y$的协方差$cov(X,Y)$定义为:$cov(X,Y) = E[(X-\mu_x)(Y-\mu_y)]$其中E(X) = \mu_x , E(Y) =\mu_y

协方差矩阵的定义

矩阵中的数据按行排列与按列排列求出的协方差矩阵是不同的,我们假定默认数据是按行排列。即每一行是一个样本,每一列就是一个随机变量。

$$X_{m\times n} = \begin{bmatrix} a_11 & a_12 & ··· & a_1n \ a_21 & a_22 & ··· & a_2n\ \vdots & \vdots & \vdots & \vdots \ a_m1 & a_m2 & ··· & a_mn \end{bmatrix} = [c_1 \quad c_2 \quad··· \quad c_n]$$

协方差矩阵:$$covMatrix = \frac{1}{m-1} \begin{bmatrix} cov(c_1,c_1) & cov(c_1,c_2) & ··· & cov(c_1,c_n) \ cov(c_2,c_1) & cov(c_2,c_2) & ··· & cov(c_2,c_n)\ \vdots & \vdots & \vdots & \vdots \ cov(c_n,c_1) & cov(c_n,c_2) & ··· & cov(c_n,c_n) \end{bmatrix}$$

举个例子

矩阵X按行排列: $$ X = \begin{bmatrix} 1 & 2 & 3 \ 3 & 1 & 1 \ \end{bmatrix} = [c_1 \quad c_2 \quad c_3]$$

1.求每个维度的平均值 $$ \overline{c} = [2,1.5,2] = [\overline{c}_1,\overline{c}_2,\overline{c}_3]$$

2.将$X$的每一列减去平均值 $$ X = \begin{bmatrix} -1 & 0.5 & 1 \ 1 & -0.5 & -1 \ \end{bmatrix} $$

3.计算协方差矩阵 $$cov = \frac{1}{m-1}X^TX = \frac{1}{2-1} \begin{bmatrix} 2 & -1 & -2 \ -1 & 0.5 & 1 \ -2 & 1 & 2 \ \end{bmatrix}$$

特征值分解协方差矩阵实现PCA,算法流程如下:

输入:数据集 $X_{m\times n}=\left{ x_{1},x_{2},x_{3},...,x_{n} \right}$ ,需要降到k维。

1) 去平均值(即去中心化),即每一位特征减去各自的平均值。

2) 计算协方差矩阵 $\frac{1}{m-1}X^TX$,注:这里除或不除$m-1$,其实对求出的特征向量没有影响。

3) 用特征值分解方法求协方差矩阵$\frac{1}{m-1}X^TX$ 的特征值与特征向量。

4) 对特征值从大到小排序,选择其中最大的k个。然后将其对应的k个特征向量组成特征向量矩阵$P$。

5) 将数据转换到k个特征向量构建的新空间中,即$Y=XP^T$。

PCA的Python实现

使用NumPy库,声明一个矩阵X,我们使用PCA将X降为2维。X.shape返回矩阵的行列数,分别赋予变量n_samples,n_features。

import numpy as np X = np.array([[1,2,3],[3,1,1]]) n_samples, n_features = X.shape X.shape (2, 3)

根据列进行循环,求每列的平均值,组合成一个numpy数组

mean=np.array([np.mean(X[:,i]) for i in range(n_features)]) mean array([2. , 1.5, 2. ])

求得平均化之后的矩阵

norm_X=X-mean norm_X array([[-1. , 0.5, 1. ], [ 1. , -0.5, -1. ]])

计算协方差矩阵

cov_matrix=np.cov(norm_X,rowvar=False) cov_matrix array([[ 2. , -1. , -2. ], [-1. , 0.5, 1. ], [-2. , 1. , 2. ]])

计算特征值(eig_val)和特征向量(eig_vec)

eig_val, eig_vec = np.linalg.eig(cov_matrix) print(eig_val,'\n', eig_vec) [4.50000000e+00 1.12979871e-50 0.00000000e+00] [[-6.66666667e-01 1.11327836e-16 1.11327836e-16] [ 3.33333333e-01 -8.94427191e-01 -8.94427191e-01] [ 6.66666667e-01 4.47213595e-01 4.47213595e-01]]

将特征值和特征向量组进行组合(eig_pairs),以便于之后的排序

eig_pairs = [(eig_val[i], eig_vec[:,i]) for i in range(n_features)] eig_pairs [(4.5, array([-0.66666667, 0.33333333, 0.66666667])), (1.1297987114863136e-50, array([ 1.11327836e-16, -8.94427191e-01, 4.47213595e-01])), (0.0, array([ 1.11327836e-16, -8.94427191e-01, 4.47213595e-01]))]

按特征值从大到小排序

eig_pairs.sort(key = lambda x:x[0],reverse=True) eig_pairs [(4.5, array([-0.66666667, 0.33333333, 0.66666667])), (1.1297987114863136e-50, array([ 1.11327836e-16, -8.94427191e-01, 4.47213595e-01])), (0.0, array([ 1.11327836e-16, -8.94427191e-01, 4.47213595e-01]))]

选取特征值中最大的2个对应的特征向量,组成新的特征向量矩阵feature

feature=np.array([ele[1] for ele in eig_pairs[:2]]) feature array([[-6.66666667e-01, 3.33333333e-01, 6.66666667e-01], [ 1.11327836e-16, -8.94427191e-01, 4.47213595e-01]])

相乘得到降维后的新矩阵data

data=np.dot(norm_X,np.transpose(feature)) data array([[ 1.50000000e+00, 1.66533454e-16], [-1.50000000e+00, -1.66533454e-16]])

如果降为1维,只需选取特征值最大的1个特征向量即可

feature1=np.array([ele[1] for ele in eig_pairs[:1]]) data=np.dot(norm_X,np.transpose(feature1)) data array([[ 1.5], [-1.5]])总结

我们将上述过程用函数封装:

import numpy as np def pca(X,k):#X代表数据,k代表降到k维 n_samples, n_features = X.shape #1、去平均值 mean=np.array([np.mean(X[:,i]) for i in range(n_features)]) norm_X=X-mean print('norm_X:',norm_X) #2、计算协方差矩阵 cov_matrix=np.cov(norm_X,rowvar=False) print('cov_matrix:',cov_matrix) #3、计算特征值和特征向量 eig_val, eig_vec = np.linalg.eig(cov_matrix) eig_pairs = [(np.abs(eig_val[i]), eig_vec[:,i]) for i in range(n_features)] print('eig_pairs:',eig_pairs) #4、对特征值从大到小排序,选取其中最大的k个 eig_pairs.sort(key = lambda x:x[0],reverse=True) feature=np.array([ele[1] for ele in eig_pairs[:k]]) print('feature:',feature) #5、得到新数据 data=np.dot(norm_X,np.transpose(feature)) return data X = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) print(pca(X,1)) norm_X: [[-3. -3. -3.] [ 0. 0. 0.] [ 3. 3. 3.]] cov_matrix: [[9. 9. 9.] [9. 9. 9.] [9. 9. 9.]] eig_pairs: [(0.0, array([-0.81649658, 0.40824829, 0.40824829])), (27.000000000000007, array([0.57735027, 0.57735027, 0.57735027])), (0.0, array([ 0. , -0.70710678, 0.70710678]))] feature: [[0.57735027 0.57735027 0.57735027]] [[-5.19615242] [ 0. ] [ 5.19615242]]



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3