Notas de estudio de MATLAB: calcule vectores propios y realice PCA manualmente

1. Descripción del problema

        Por lo general, las características están correlacionadas. Por ejemplo, considere una situación en la que queremos usar los componentes rojo, verde y azul de cada píxel de la imagen para clasificar una imagen (como detectar perros frente a gatos). Los sensores de imagen que son más sensibles a la luz roja también capturan algo de luz azul y verde.

        Aquí generamos datos aleatorios y trazamos los datos en 3D, luego realizamos un análisis de componentes principales para descorrelacionar los datos y reducir la dimensionalidad del espacio de características.

        Tenga en cuenta que matlab tiene una función de optimización que realiza PCA: princomp(). Sin embargo, en nuestro script, realizamos PCA manualmente mediante el cálculo de los vectores propios con fines de demostración.

2. Crea datos aleatorios

        Creamos 334 puntos de datos aleatorios.

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. Visualiza datos en 3D

        Primero trazamos los puntos de datos sin procesar, luego calculamos los vectores propios y los valores propios, y luego hacemos el trazado de los vectores propios.

%%%%%%%%%%%%% 绘制原始数据 %%%%%%%%%%%
% 获取数据均值的坐标
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数据');

        Al visualizar los resultados, podemos ver los datos sin procesar y los vectores de características.

4. Trazar datos no correlacionados

        Aquí centralizamos, normalizamos, decorrelacionamos y luego volvemos a representar los datos.

%%%%%%%%%%%%% 集中数据 %%%%%%%%%%%
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数据');

        Visualización de datos descorrelacionados 

5. Reducir la dimensionalidad de los datos a 2D

        Aquí solo tomamos los dos primeros componentes principales y los visualizamos.

%%%%%%%%%%%%% 将数据投影到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;

        La visualización es la siguiente 

 6. Reducir la dimensionalidad de los datos a 1D

        Aquí solo mantenemos el más grande, el primer vector propio

%%%%%%%%%%%%% 将数据投影到最大的特征向量上 %%%%%%%%%%%

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;

        La visualización es la siguiente

 

Supongo que te gusta

Origin blog.csdn.net/bashendixie5/article/details/124274461
Recomendado
Clasificación