1、问题描述
通常情况下,特征是相关的。例如,考虑我们想要使用图像中每个像素的红色、绿色和蓝色分量来对图像进行分类(例如检测狗与猫)的情况。对红光最敏感的图像传感器也会捕获一些蓝光和绿光。
在这里我们生成随机数据并绘制 3D 数据,然后执行主成分分析以对数据进行去相关处理,并降低特征空间的维度。
请注意,matlab 具有执行 PCA 的优化函数:princomp()。 但是,在我们的脚本中,我们通过计算特征向量手动执行PCA,用于演示目的。
2、创建随机数据
我们创建334个随机数据点。
clear all;
close all;
% 创建随机点
s = [2 2 2]; % 偏斜因子
x = randn(334,1);
y1 = normrnd(s(1).*x,1)+3;
y2 = normrnd(s(2).*x,1)+2;
y3 = normrnd(s(3).*x,1)+1;
data = [y1 y2 y3];
3、可视化3D数据
我们首先绘制原始数据点,然后计算特征向量和特征值,之后进行特征向量的绘制。
%%%%%%%%%%%%% 绘制原始数据 %%%%%%%%%%%
% 获取数据均值的坐标
avg = mean(data);
X0=avg(1);
Y0=avg(2);
Z0=avg(3);
% 绘制原始数据
scatter3(data(:,1), data(:,2), data(:,3), 5, data(:,3), 'filled');
colormap(gray);
% 计算特征向量和特征值
covariance = cov(data);
[eigenvec, eigenval ] = eig(covariance);
% 获取最大特征向量的索引
largest_eigenvec = eigenvec(:, 3);
largest_eigenval = eigenval(3,3);
medium_eigenvec = eigenvec(:, 2);
medium_eigenval = eigenval(2,2);
smallest_eigenvec = eigenvec(:, 1);
smallest_eigenval = eigenval(1,1);
% 绘制特征向量
hold on;
quiver3(X0, Y0, Z0, largest_eigenvec(1)*sqrt(largest_eigenval), largest_eigenvec(2)*sqrt(largest_eigenval), largest_eigenvec(3)*sqrt(largest_eigenval), '-m', 'LineWidth',3);
quiver3(X0, Y0, Z0, medium_eigenvec(1)*sqrt(medium_eigenval), medium_eigenvec(2)*sqrt(medium_eigenval), medium_eigenvec(3)*sqrt(medium_eigenval), '-g', 'LineWidth',3);
quiver3(X0, Y0, Z0, smallest_eigenvec(1)*sqrt(smallest_eigenval), smallest_eigenvec(2)*sqrt(smallest_eigenval), smallest_eigenvec(3)*sqrt(smallest_eigenval), '-r', 'LineWidth',3);
hold on;
% 设置轴标签
hXLabel = xlabel('x');
hYLabel = ylabel('y');
hZLabel = zlabel('z');
%Xlim([-10,10]);
%Ylim([-10,10]);
%Zlim([-10,10]);
title('原始3D数据');
可视化结果,我们可以看到原始数据和特征向量
4、绘制去相关数据
这里我们对数据进行集中、规范化,去相关,然后重新绘制。
%%%%%%%%%%%%% 集中数据 %%%%%%%%%%%
data = data-repmat(avg, size(data, 1), 1);
%%%%%%%%%%%%% 规范化数据 %%%%%%%%%%%
stdev = sqrt(diag(covariance));
data = data./repmat(stdev', size(data, 1), 1);
%%%%%%%%%%%%% 去相关数据 %%%%%%%%%%%
decorrelateddata = (data*eigenvec);
% 绘制去相关数据
figure;
scatter3(decorrelateddata(:,1), decorrelateddata(:,2), decorrelateddata(:,3), 5, decorrelateddata(:,3), 'filled');
colormap(gray);
% 绘制特征向量 (现在是轴 (0,0,1), (0,1,0), (1,0,0)
% 居中数据的平均值为 (0,0,0)
hold on;
quiver3(0, 0, 0, 0, 0, 1*sqrt(largest_eigenval), '-m', 'LineWidth',3);
quiver3(0, 0, 0, 0, 1*sqrt(medium_eigenval), 0, '-g', 'LineWidth',3);
quiver3(0, 0, 0, 1*sqrt(smallest_eigenval), 0, 0, '-r', 'LineWidth',3);
hold on;
% Set the axis labels
hXLabel = xlabel('x');
hYLabel = ylabel('y');
hZLabel = zlabel('z');
%Xlim([-5,5]);
%Ylim([-5,5]);
%Zlim([-5,5]);
title('去相关的3D数据');
可视化的去相关数据
5、将数据降维到2D
在这里我们只取前两个主成分,然后可视化。
%%%%%%%%%%%%% 将数据投影到2个最大的特征向量上 %%%%%%%%%%%
eigenvec_2d=eigenvec(:,2:3);
data_2d = data*eigenvec_2d;
% Plot the 2D data
figure;
scatter(data_2d(:,1), data_2d(:,2), 5, data(:,3), 'filled');
colormap(gray);
% Plot the eigenvectors
hold on;
quiver(0, 0, 0*sqrt(largest_eigenval), 1*sqrt(largest_eigenval), '-m', 'LineWidth',3);
quiver(0, 0, 1*sqrt(medium_eigenval), 0*sqrt(medium_eigenval), '-g', 'LineWidth',3);
hold on;
% Set the axis labels
hXLabel = xlabel('x');
hYLabel = ylabel('y');
%Xlim([-5,5]);
%Ylim([-5,5]);
title('Projected 2D data');
grid on;
可视化效果如下
6、将数据降维到1D
这里我们就只保留最大的,第一个特征向量
%%%%%%%%%%%%% 将数据投影到最大的特征向量上 %%%%%%%%%%%
eigenvec_1d=eigenvec(:,3);
data_1d = data*eigenvec_1d;
% Plot the 1D data
figure;
scatter(repmat(0, size(data_1d,1), 1), data_1d, 5, data(:,3), 'filled');
colormap(gray);
% Plot the eigenvector
hold on;
quiver(0, 0, 0*sqrt(largest_eigenval), 1*sqrt(largest_eigenval), '-m', 'LineWidth',3);
hold on;
% Set the axis labels
hXLabel = xlabel('x');
hYLabel = ylabel('y');
%Xlim([-5,5]);
%Ylim([-5,5]);
title('Projected 1D data');
grid on;
可视化效果如下
评论(0)
您还未登录,请登录后发表或查看评论