PCA算法的数学推导及其简单算例

PCA算法的数学推导及其简单算例

PCA算法操作简述

假设 X 是一个m*n矩阵,表示n个对象的m个特征表示数据,即每一列表示一个对象,每一行表示一个特征。我们希望将特征降为d维,d远小于m。输出结果为 Y ,一个d*n的矩阵。
- 记 X = [ x 1 , x 2 . . . x n ] ,计算每个对象点的平均值 x 0 = 1 n i = 1 n x i
- 对 X x 0 = Δ [ x 1 x 0 , x 2 x 0 . . . x n x 0 ] 做奇异值分解: X x 0 = U Λ V T
- 则 x 0 即为新坐标系的原点, U 的前d列即为去中心化后的新的坐标系,不妨记为 W 。那么,所有点在新坐标系下的表示为: Y = W T ( X x 0 ) 。同样地,要将新的投影点 y 还原到原坐标系中,可以写为: x 0 + W y

PCA算法一个极其简单的算例

假设小明和小红有身高和体重两个特征(实际操作数据要进行预处理,这里不做),如下图:

~ 小明 小红
身高 178 165
体重 70 65

那么此时 X = [ 178   165 ; 70   65 ] ,现在试图通过PCA降维,将身高和体重合并为一个特征。走一遍上面的过程,可得:

x 0 = [ 171.5   67.5 ]

X x 0 = [ 6.5 6.5 2.5 2.5 ]

X x 0 = U Λ V T

其中,
U = [ 0 .9333 0 .3590 0 .3590 0 .9333 ]

Λ = [ 9 .8489 0 0 0 ]

V = [ 0 .7071 0 .7071 0 .7071 0 .7071 ]

那么,有
W = [ 0 .9333 0 .3590 ] Y = [ 6 .9642 , 6 .9642 ]

那就是说,最后数据可降维为:

~ 小明 小红
PC1 -6.9642 6.9642

附上这个问题matlab计算的小程序:

clc
clear
X = [178 165; 70 65];
x0 = sum(X,2)/2;
X_x0 = X - [x0 x0];
[U,S,V] = svd(X_x0);
W = U(:,1);
Y = W'*(X_x0);
rebuild_X = [x0 x0]+W*Y;

PCA算法的数学推导

我们假设输入为p维的N个对象, X 表示如下图所示的一个矩阵:

Alt text

通过PCA降维,将其降为d维的N个对象,假设为 Y ,同前,每列表示一个对象,每行表示一个特征:
Alt text

我们要将所有点投影到新的坐标系中去,无非是寻找新坐标系的坐标原点和各个坐标轴。

我们假设 W 的每一列为新的坐标系中单位正交的坐标轴表示, x 0 为新坐标系的原点(相对于原坐标系)。
那么,我们要做的就是找到一个合适的 W x 0 ,使其极小化所有点到新的坐标平面的距离平方和。
容易知道,每一个点到新坐标系的距离平方为(其中 X _ = ( x 0 , W ) 表示的是位置参数):
Alt text

对其进行化简,可得:
Alt text

让所有点到投影点距离平方和最小,即求解约束优化问题:
Alt text
我们借助拉格朗日乘子法来求解此约束优化问题:
Alt text
Alt text

由两个偏导为0,可以得到:

Alt text

因为半正定矩阵的特征值非负,所以,原最小化损失函数可进行转化:
Alt text

我们利用矩阵的性质,要想最小化距离平方和,有:
Alt text

由此我们可以看到,要得到极小值,我们只要计算 X X T 矩阵的前d个最大特征值,是投影后样本具有最小损失的特点。那么此时的 W 就是 X X T 矩阵前d个最大特征值对应的特征向量。

不难知道,对于 X X T 的特征分解:

X X T = U Λ U T

这里的U就是前天提到的奇异值分解的U。同理,虽然我们这里没有用到 V ,但其实奇异值分解的 V 正式 X T X 的特征值分解的特征矩阵。

为了比较 X X T 特征分解和 X 进行奇异值分解的消耗,写了一段小程序,并使用matlab探查功能进行比较如下:

Alt text

这个比较事实上没有太大的意义。
所用的代码如下:

clc
clear
p = 10000;
N = 10;
d = 10;
AR = randn(p,N);

x0 = mean(AR,2);%计算样本均值
AR_shift = AR - repmat(x0,1,N);%中心平移每个训练样本
Sigma = AR_shift*AR_shift';
[W,D] = eigs(Sigma,d);%前d个特征向量作为wi
Lambda = diag(D);%提取特征值

%% 
[U,S,V] = svd(AR_shift);

猜你喜欢

转载自blog.csdn.net/lusongno1/article/details/80517808
今日推荐