方法一:
1:用zscore函数对原始数据S进行标准化。
2:用cov函数求出标准化后的数据的协方差。
3:求出此协方差的特征向量与特征根(eig函数)。
4:将产生的特征向量依据特征根大小从大到小进行排列(即将特征向量按列倒序)。
5:依据需求取出倒序后的向量的前几列(一般根据特征根来算贡献率,使得累计贡献率大于85%),组成新的矩阵T
6:做S*T得到分析后的新的数据。
7:依据特征根算贡献率,并绘图。
代码如下:
X=load('shuju.txt')
z=zscore(X) %数据标准化
M=cov(z) %协方差
[V,D]=eig(M); %求出协方差矩阵的特征向量、特征根
d=diag(D); %取出特征根矩阵列向量(提取出每一主成分的贡献率)
eig1=sort(d,'descend') %将贡献率按从大到小元素排列
v=fliplr(V) %依照D重新排列特征向量
S=0;
i=0;
while S/sum(eig1)<0.85
i=i+1;
S=S+eig1(i);
end %求出累积贡献率大于85%的主成分
NEW=z*v(:,1:i) %输出产生的新坐标下的数据
W=100*eig1/sum(eig1)
figure(1)
pareto(W); %画出贡献率的直方图
方法二:
1:用zscore函数对原始数据S进行标准化,(同上)。
2:利用matlab自带的princomp函数直接求得其特征向量,新坐标下的数据,特征根(并且已经排列好了)。
3:选择恰当的前几项主成分与标准化后的数据相乘。得到在新坐标下的数据。
4:如方法一,利用特征根算贡献率。
代码如下:
X=load('shuju.txt')
x=zscore(X) %标准化
[coef,score,eig,t]=princomp(x); %利用princomp处理矩阵
t %每一组数据在新坐标下到原点的距离
s=0;
i=1;
while s/sum(eig)<0.85
s=s+eig(i);
i=i+1;
end %获得累计贡献率大于85%几组数据
NEW=x*coef(:,1:i-1) %输出新的数据
figure
pareto(eig/sum(eig)); %输出贡献率直方图
figure(2)
plot(eig,'r+');
hold on
plot(eig,'b-');
1:归一化、均值化、标准化、白化
归一化:将数据归结到某两个数之间。
计算公式:y = (ymax - ymin)*(x - xmin)/(xmax - xmin) + ymin
Matlab实现方法:利用mapminmax函数,具体格式为[y,ps] = mapminmax(x,ymin,ymax)(矩阵中以行来归一化)。
均值化:将数据中的每一个数除以其相应指标的平均值(数据矩阵中由于一般每一列描述一个特征,matlab处理时要按列处理)(这种方法可以说修正了常用的标准化会浪费部分数据的情况,可以替代标准化对数据进行预处理)。
标准化:使数据均值为0方差为1,即将每一个数据减去所在列的均值后对数据矩阵每一列除以其对应的方差。
Matlab实现方法:使用zscore函数。
主成分分析中,原始数据的单位不同,需要使用一种数据处理方法使其转换为无量纲数,归一化与标准化都有消除量刚的作用,但是,主成分分析根据方差来建立新坐标系的,所以归一化矩阵可能不适用于PCA中,所以,基本上主成分分析在数据预处理上都用的是标准化,但是,标准化矩阵本身会损失一部分信息,而均值化不会损失信息,均值化可以更好的改进PCA算法(网上找到的一篇论文中说到的)。
白化:白化通常为独立成分分析中的数据处理方式,其与PCA处理方式基本一致,个人理解ICA就是对PCA数据作的进一步处理,找到其中相互独立的部分。
2:princomp函数与eig函数的不同
在开始我一直以为利用princomp函数与eig函数产生的特征向量只有顺序有所不同,但是我发现,即使是同一组数据,其产生的特征向量也有所不同,表现为某几个数据正负号不同,具体如下:
原始数据:
使用eig函数的得到的特征向量:
可以看出,不仅是列的位置有所不同,某些数据的正负情况也有所不同,这也是我的一个疑惑:相同数据的特征向量为什么会有正负号的偏差?为保险起见,我觉得matlab自带的princomp函数可能更准确。
3:PCA与ICA的异同
几何意义上:PCA是在找寻保留最大信息的方向,而ICA是在找寻各个独立的分量,也就是说PCA的第一主成分贡献率永远最大并且贡献率主成分次数增高逐渐降低,而ICA并没有,他只是将原有的信号解混,并不考虑信息量的大小。
处理方式上:处理ICA时要先用PCA做白化处理,因为PCA协方差矩阵为对角阵,其必不相关,独立必不相关,所以通过PCA使数据之间没有相关性,之后再进行迭代操作,求出相互独立的分量。