详情见站内搜索 《每天进步一点点《协方差矩阵的实践》》.docx
上一次我们学习了PCA的过程,并且在最后还特意为大家介绍了协方差矩阵以及协方差矩阵的特征值和特征向量的作用。
Now , Review it Together…
1:协方差
2:协方差矩阵
换算成矩阵运算,假设矩阵A是M行N列,每一列是一个特征值。M是样本个数。
上述计算即为,先将每个特征均值中心化得到新的A, 再:(1/M) * AT * A。
3:协方差矩阵的意义:
它是个对称矩阵,对角线元素代表某个特征本身的方差,其他元素是某两个特征之间的协方差。因此是对称矩阵。
特征值分解后,可以得到,不同的特征向量是正交的,重根特征值对应的特征向量可以单位化和正交化变成单位正交向量。符合一般习惯,选择坐标系一般会选择一组正交的基。
且因为正交,不同维度之间是不相关的,各个维度向量之间独立。
4:协方差矩阵的特征值和特征向量有何意义?这里很关键!!!
协方差矩阵的最大的特征值对应的特征向量代表了数据分布的主要方向。次大的特征值对应的特征向量代表了数据分布的次要方向。
PCA的意义:
下面我们将用四个例子来说明下这个问题:
例子一:
clc;clear all;close all;
set(0,'defaultfigurecolor','w') ;
x = 0:0.5:100;
y = 80 - x + 10*rand(1, 201);
figure();
subplot(1,2, 1)
scatter(x, y, 'r', 'linewidth', 3);
xlim([0,100]);
ylim([0,100]);
axis equal;
grid on;
xlabel('heigth');
ylabel('weight');
% 形成矩阵
dataSet = [x;y]';
%步骤一:中心化处理(均值化处理)
meanVal = mean(dataSet);
dataSet(:,1) = dataSet(:,1)- meanVal(1);
dataSet(:,2) = dataSet(:,2)- meanVal(2);
%步骤二:求协方差矩阵,且是一个对称实数矩阵,那么可以将特征向量成单位正交阵,且特征值是实数。
% ====
R = dataSet' * dataSet;
%步骤三:求特征值、特征向量, 利用:eig 进行特征值分解
% ====
[V,D] = eig(R);
% [EigR,PosR] = sort(diag(D),'descend');
%VecR = V(:,PosR);
Proj = V;
% 绘制出两个转换后的新的坐标方向
x0 = -50:50;
subplot(1, 2, 2)
scatter(dataSet(:,1), dataSet(:,2), 'r', 'linewidth', 5);hold on; %打点
plot(x0, Proj(1,2)/Proj(1,1)*x0, 'b', 'linewidth', 3);hold on; %绘出投影方向
plot(x0, Proj(2,2)/Proj(2,1)*x0, 'b', 'linewidth', 3);hold on; %绘出投影方向
xlim([-50,50]);
ylim([-50,50]);
axis equal;
grid on;
xlabel('heigth');
ylabel('weight');
例子二,三,四
clc;clear all;close all;
set(0,'defaultfigurecolor','w');
figure();
% 椭圆: 4*X^2 + 25*Y^2 = 100
% 首先得到椭圆的圆边方程
x = -5:0.02:5;
y = sqrt((100 - 4 * x * diag(x)) / 25);
% 根据随机数,在椭圆内,得到随机的y点值
% X轴上下各一半
% =============================================================
y1 = y * diag(rand(1, 501));
y2 = - y * diag(rand(1, 501));
%%=============================================================
% X轴上下两组数据合并,合成一个坐标集合
% =============================================================
x_src = [x,x];
y_src = [y1, y2];
matrix = [x_src; y_src]';
%%=============================================================
%%%经过某个正交矩阵变换(只旋转角度,不改变各个向量的大小,称为几何不变性质),得到一个新的坐标集合
% =============================================================
delta = 1.123
trans = [cos(delta), sin(delta);
-sin(delta), cos(delta)];
matrix_1 = matrix * trans;
%%=============================================================
%%%经过某个正交矩阵变换(只旋转角度,不改变各个向量的大小,称为几何不变性质),得到一个新的坐标集合
% =============================================================
delta = -0.8
trans = [cos(delta), sin(delta);
-sin(delta), cos(delta)];
matrix_2 = matrix * trans;
% ======= 画图 =====
matrix_list = [matrix, matrix_1, matrix_2];
for x=1:3
dataSet = matrix_list(:, 2*x-1 : 2*x);
% 画图
subplot(2, 3, x);
scatter(dataSet(:,1), dataSet(:,2), 'r', 'linewidth', 3);
xlim([-6,6]);
ylim([-6,6]);
axis equal;
grid on;
xlabel('X-alias');
ylabel('Y-alias');
end;
% =============================================================
% =============================================================
% =============================================================
% 画出协方差,特征向量的表示方向
% =============================================================
matrix_list = [matrix, matrix_1, matrix_2];
for x=1:3
%步骤一:中心化处理(均值化处理)
dataSet = matrix_list(:, 2*x-1:2*x);
meanVal = mean(dataSet);
dataSet(:,1) = dataSet(:,1)- meanVal(1);
dataSet(:,2) = dataSet(:,2)- meanVal(2);
%步骤二:求协方差矩阵,且是一个对称实数矩阵,那么可以将特征向量成单位正交阵,且特征值是实数。
R = dataSet' * dataSet;
%步骤三:求特征值、特征向量
%利用:eig 进行特征值分解
[V,D] = eig(R);
% [EigR,PosR] = sort(diag(D),'descend');
%VecR = V(:,PosR);
Proj = V;
% 绘制出两个转换后的新的坐标方向
x0 = -10:10;
subplot(2, 3, 3+x)
scatter(dataSet(:,1), dataSet(:,2), 'r', 'linewidth', 5);hold on; %打点
plot(x0, Proj(1,2)/Proj(1,1)*x0, 'b', 'linewidth', 3);hold on; %绘出投影方向
plot(x0, Proj(2,2)/Proj(2,1)*x0, 'b', 'linewidth', 3);hold on; %绘出投影方向
xlim([-6,6]);
ylim([-6,6]);
axis equal;
grid on;
xlabel('X-alias');
ylabel('Y-alias');
end;
以上两个例子,都是随机画出来的点,都是由一个个的点组成,我们能看到,当对协方差矩阵进行特征值分解后,我们能得到一个新的坐标系,较大的特征值对应的特征向量代表了数据的最大的分布方向,其次是一个与之正交的向量,代表了另外个方向。
拓展到高维也是一样的,这里就用了几个二维的例子来描述了下,希望能更加清晰的认识。