PCA主成分分解和可视化
PCA,即主成分分析(Principal Component Analysis),是一种广泛使用的数据分析方法,尤其在数据降维方面表现出色。PCA的核心思想是通过正交变换将原始特征空间中的线性相关变量转换为新的线性无关变量,这些新变量称为主成分。下面,我将为您介绍PCA的推导和流程。
PCA推导
PCA的推导主要基于两个原则:最大化数据投影后的方差以及最小化投影造成的损失。这里我们主要关注第一个原则,即最大化方差。
假设我们有一个数据集,其中每个数据点都可以表示为一个向量。PCA的目标是找到一个新的坐标系,使得数据点在这个新坐标系上的投影具有最大的方差。换句话说,我们希望找到一个方向,使得数据点在这个方向上的投影尽可能分散。
在数学上,这可以通过求解数据协方差矩阵的特征值和特征向量来实现。协方差矩阵的特征值表示了数据在各个方向上的分散程度,而特征向量则对应着这些方向。通过选择协方差矩阵的最大特征值对应的特征向量,我们可以找到方差最大的投影方向。
PCA流程
以下是PCA的基本流程:
- 数据标准化:首先,对原始数据进行标准化处理,消除不同特征之间的量纲差异。
- 计算协方差矩阵:计算标准化后数据的协方差矩阵。
- 求解特征值和特征向量:对协方差矩阵进行特征值分解,得到特征值和对应的特征向量。
- 选择主成分:根据特征值的大小,选择前k个最大的特征值对应的特征向量作为主成分。这些主成分构成了一个新的坐标系。
- 数据投影:将原始数据投影到新的坐标系上,得到降维后的数据。
通过PCA,我们可以将高维数据转换为低维数据,同时保留数据中的主要信息。这使得PCA在数据分析、机器学习等领域具有广泛的应用。
需要注意的是,PCA是一种无监督学习方法,它不需要标签数据就可以进行降维。但是,PCA并不能解决所有的降维问题,有时还需要结合其他方法一起使用。
此外,PCA虽然能降低数据的维度,但也可能会导致一些信息的损失。因此,在选择是否使用PCA以及选择多少主成分时,需要根据具体的应用场景和需求进行权衡。
以下对二维坐标点样本进行pca分解举例,多维则根据具体情况选前k个主成分。
%%PCA降维测试以及可视化测试
clear; close all;
%测试数据
x=-100:100;
a=-10;
b=10;
R = 10*a + (b-a).*randn(size(x));
y=x+R;
PcaTrainData=[x',y'];
%%去均值
PcaMean= mean(PcaTrainData,1);
[row,col]=size(PcaTrainData);
%PcaMean=repmat(PcaMean,row,1);
NormData=PcaTrainData-repmat(PcaMean,row,1);
%%计算协方差矩阵
C=cov(NormData);
%%Pca
%%方法一:
%%P:特征向量
%%L:特征值
%%由于特征值(向量)是由小到大,所以逆序
%%特征向量按列排序,每一个列为一个特征向量
[P,L]=eig(C);
%%方法二:
%%pca的方法计算的coeff,score,latent和eig的结果一样,且已经降序排序过
%%各样本属性分数:score
%%特征值:latent
[coeff,score,latent]=pca(NormData);
%%特征向量coeff和P中,每个特征向量的平方和为1,每两个特征向量互相垂直
%%排序
ev=(diag(L))';
ev=ev(:,end:-1:1);
%对特征值归一化,只取前85%左右的特征
P=P(:,end:-1:1);
%egi=P(:,1:20);
%%----------可视化---------
%%同过分数和特征向量可以计算出,去中心化后的原始数据
% figure;
% tt=score*coeff';
% plot(tt(:,1),tt(:,2),'.');
% figure;
% tt=score*coeff;
% plot(tt(:,1),tt(:,2),'.');
norm_ev=ev/(sum(ev));
figure;
bar(norm_ev);
title('各特征值所占比率')
Rrange=300;
XRange = [-Rrange;Rrange];
figure;
axis([XRange',XRange']);
%%显示原样本
hold on;
plot(x,y,'.','color','g');
xx=NormData(:,1);
yy=NormData(:,2);
%%去中心化样本
hold on;
plot(xx,yy,'.','color','r');
%%分别用两种方法画特征向量
%%注:每个特征向量为一个坐标轴,二维举例,每一列的特征向量(x,y),以(0,0)为中心
%%如果在原图上,则需要加上偏移PcaMean:(还原去白化)
%%第一种:向量画线
xsize=Rrange;
vect1=[P(:,1)*(-1) P(:,1)];
vect1=vect1*xsize;
plot(vect1(1,:),vect1(2,:));
vect2=[P(:,2)*(-1) P(:,2)];
vect2=vect2*xsize;
hold on;
plot(vect2(1,:),vect2(2,:));
title('样本图像和特征向量图')
%%第二种:计算斜率,已经去中心化了,不用计算计算截距
% xsize=-Rrange:Rrange;
% k1=P(2,1)/P(1,1);
% vect1=k1*xsize;
% hold on;
% plot(xsize,vect1);
%
% k2=P(2,2)/P(1,2);
% vect2=k2*xsize;
% hold on;
% plot(xsize,vect2);
%%这个还不清楚
% figure;
% plot(ev,'o');
% v={'x' ,'y'};
% biplot(coeff(:,1:2),'scores',score(:,1:2),'VarLabels',v);
%可视化前两个主成分的得分:
%x:数据在第一个主成分上的变异性大小及区间
%y:数据在第二个主成分上的变异性大小及区间
figure;
scatter(score(:,1), score(:,2)); % 绘制得分散点图
%%
title('样本在两个主成分向量上的变异性大小')
%%%%%%%%%%%%%%%