主成分分析及MATLAB和SPSS求解整理
文章目录
前言
主成分分析是一种数据降维的方法,在数据模型的建立以及机器学习数据白化过程中都是有十分广泛的应用。本文是作者在学习PCA方法及求解过程中整理所得到的内容,主要包含第一部分PCA原理的解释,第二部分关于不同工具(即MATLAB和SPSS)对于PCA求解应用对比。
一、PCA原理解释
1.为什么要用PCA?
因为在数据建模时多个变量之间往往会有一定的相关性,会显著增加问题分析的复杂性,有必要采取将多个变量综合为少数有代表性的变量,这些变量能够代表原始数据的大多数信息且不相关,有助于分析建模,主成分分析就能达到这种目的。
2.PCA基本思想
数学上的方法就是将原来的变量做线性组合,作为新的综合变量,这种线性组合有可以有很多,具体选取哪几种呢。如果选取第一个线性组合即第一个综合变量 ,这里需要它更多的反映原来变量的信息,这里的“信息”用方差来表示,即:
根据所选的主成分数(K)这里方差越大表示 F1所代表的信息也越多,同时 F2中包含的信息,为了有效的反映原来的信息, F1中已有的信息就不需要再出现在 F2中了,用数学语言表示则为:
这是主成分的基本思想,本质就是数据降维,使得保留的信息最大化,其具体数学推导也是很有意思的,内容较多,我后面有时间更新,作者的这篇博客对于其算法原理的解释通过数据向量的角度出发,个人认为解释也十分清楚,可以试着看看。
3.PCA算法求解步骤
设有m条P维数据。
1)将原始数据按列组成n行P列矩阵X
2)数据标准化
3)求出相关系数矩阵(有些地方说的是协方差矩阵,其实本质是一样的,因为相关系数矩阵其实就是协方差矩阵的标准化形式)
4)求出相关系数矩阵的特征值及对应的特征向量
5)将特征向量按对应特征值大小从上到下按行排列成矩阵,选取累计贡献率在85%(常规标准)以上的特征值对应特征向量,最后组成mk的主成分特征向量矩阵
6)将标准化后的数据(np)和主成分特征向量矩阵(nk)相乘,得到降维后的主成分得分,即为降维到k维后的数据(nk)
7)每个样本的主成分得分和和每个主成分的贡献率相乘可以得到每个样本综合得分
4.根据求解思路进行求解
第一步:对数据标准化处理
假设样本观测数据为:
其中表示有n个样本、P个维度
数据标准化处理:
标准化求解(可以直接调用matlab的函数)
A=x(I,j)%样本数据
Std(A)%求解每一列的标准差
Mean(A)%求解每一列的均值
%%或者直接用zscore(X)直接求得标准化样本数据矩阵
zscore(X)
第二步:求解样本相关系数(求解每一个属性下样本的相关系数,即每一列的相关系数)
其中: 对于相关系数矩阵的求解也是可以直接调用matlab中的函数进行求解Corrcoef(a)%求解a的相关系数矩阵(有的地方提到的是协方差矩阵,其实相关系数矩阵就是协方差矩阵的标准化(无量纲化)的形式
第四步:求解相关系数矩阵的特征值以及特征向量
注意:这里的特征值直接代表的是对应主成分的方差大小,因为特征值表示的是伸缩的比例,占总的特征值越多的话,表示越贡献率越大。具体解释可以参考这篇博客的内容,个人认为讲解的是很形象清楚的,对于理解PCA的原理有一定帮助。
R的特征值
对应特征向量(所求的特征向量即所求的变换之后的坐标轴,数值代表每个维度的基)
步骤五:选择主成分
主成分的选择根据特征值的大小来选择,例如:选择前k个,但一般要求累计贡献率达到85%以上
步骤六:主成分表达式
步骤七:主成分得分,即降维后的数据步骤八:根据前文求得的各个主成分的贡献比例作为权重,计算的到综合得分
注意:我这里的求解思路和前面写的列的求解提纲思路是一样的,但在表达上不是一致,这个不影响。
二、PCA案例求解
根据上文对于PCA原理的解释以求求解的数学过程分析,这里结合实际案例以及不同工具进行求解,具体数据为15个企业的8个经营数据进行降维分析,通过PCA对主成分进行打分,以及得出综合得分,最终求解得到各个企业的综合得分,并进行排序,达到对企业综合实力的排序目的。
数据的百度网盘链接
链接:https://pan.baidu.com/s/1RGx_jAdIqTx5S1h1lwT6mA
提取码:k80w
1.利用SPSS求解
SPSS没有直接进行主成分分析的命令,但可以通过自带的因子分析数据降维方式进行转换最终得到进行主成分的分析的目的
第一步:数据标准化处理
点击“分析——降维——因子分析”
这里抽取可以基于特征值也可以固定数量,我这里上面分析得到三个累计贡献达到了85%以上,就直接固定了数量为3个
具体输出结果
不能直接进行主成分分析,需要进行变换才能得到系数矩阵(特征向量矩阵)
主成分系数=成分矩阵中的数据/sqrt(主成分对应特征值)
最后根据上式进行换算,得到得分系数矩阵(特征向量矩阵)
然后根据主成分公式计算得到主成分得分和综合得分,具体的就求解了,这里的目的是为了说明SPSS不能直接进行主成分分析,需要将得到的成分矩阵进行转换最后才能得到特征向量矩阵(得分系数矩阵),然后进行PCA降维
2.利用MATLAB求解
MATLAB对于PCA求解可以直接调用函数,也可以根据前文的算法原理以及求解的步骤自己编写代码,我将两种方法均进行求解,最终得到的结果也是相同,先将代码放出
% pca主成分分析整理
clc
clear
A=xlsread('Coporation_evaluation.xlsx', 'B2:I16');%调用15家企业的经济数据进行主成分分析
SA=zscore(A)
%%
%直接调用pcacov函数做主成分分析
%[COEFF,latent,explained] = pcacov(PHO);
%其中PHO为相关系数矩阵,可以通过PHO=corrcoef(A) 求得
%COEFF为调用函数求得的主成分表达式的系数矩阵,即特征向量矩阵,这里第一类所代表的特征向量即对应特征值最大的向量(自动排序)
% latent为特征向量对应的特征值
% explained主成分贡献率
%调用函数计算得到
[COEFF,latent,explained] = pcacov(corrcoef(SA));
% 为了更加直观,以元胞数组形式显示结果
result1(1,:) = {'特征值', '贡献率', '累积贡献率'};
result1(2:9,1) = num2cell(latent);
%diff函数式用于求导数和差分的.
%result1(2:9,2) = num2cell(-diff(latent));
%cumsum函数通常用于计算一个数组各行的累加值。
result1(2:9,2:3) = num2cell([explained, cumsum(explained)]);
%根据上面的result1可以知道,前三个主成分贡献率为
% 以元胞数组形式显示前3个主成分表达式
s = {'标准化变量';'x1:净利润率';'x2:固定资产利润率';'x3:总产值利润率';'x4:销售收入利润率';'x5:产品成本利润率';'x6:物耗利润率';'x7:人均利润率';'x8:流动资金利润率';};
result2(:,1) = s ;
result2(1, 2:4) = {'特征向量1', '特征向量2', '特征向量3'};
result2(2:9, 2:4) = num2cell(COEFF(:,1:3));
%result2即主成分特征向量矩阵
report=SA*COEFF(:,1:3);%每个主成分的得分
explained0=explained./100;%得到贡献率
report_total=report*explained0(1:3,1);%综合得分
i=1:15;%定义一个序列
xu=i';%
report_totalz=[report,report_total,xu];%输出降维后的各个样本的数据以及综合得分以及序号
last_score=sortrows(report_totalz,-4);%对综合得分进行降序排序(减号表示降序)
%注意可视化之类的
plot3(report(:,1),report(:,2),report(:,3),'ko')
%% 手动编写
%
clc
clear
A=xlsread('Coporation_evaluation.xlsx', 'B2:I16');%调用15家企业的经济数据进行主成分分析
% Transfer orginal data to standard data
a=size(A,1); % Get the row number of A确定行数
b=size(A,2); % Get the column number of A确定列数
for i=1:b
SA(:,i)=(A(:,i)-mean(A(:,i)))/std(A(:,i)); % Matrix normalization%数据标准化处理
end
% Calculate correlation matrix of A.标准化的原始数据的相关系数矩阵
CM=corrcoef(SA);
% Calculate eigenvectors and eigenvalues of correlation matrix.
%其中v代表求得的特征向量矩阵,这里的V的排序,调用eig可能出来的是按特征值升序排序
%D代表特征值(对角矩阵),
[V, D]=eig(CM);%计算特征值(对角矩阵)和特征向量
% Get the eigenvalue sequence according to descending and the corrosponding
% attribution rates and accumulation rates.
for j=1:b
DS(j,1)=D(b+1-j, b+1-j);%对特征值进行排序
end
for i=1:b
DS(i,2)=DS(i,1)/sum(DS(:,1));%贡献率
DS(i,3)=sum(DS(1:i,1))/sum(DS(:,1));%累积贡献率
end
% Calculate the numvber of principal components.
T=0.9; % set the threshold value for evaluating information preservation level.主成分信息保留率
for K=1:b
if DS(K,3)>=T
Com_num=K;%得到保留的主成分数
break;%终止循环
end
end
% Get the eigenvectors of the Com_num principal components
for j=1:Com_num
PV(:,j)=V(:,b+1-j);
end
% Calculate the new socres of the orginal items
new_score=SA*PV;%主成分得分
for i=1:a
%total_score(i,2)=sum(new_score(i,:));%求解综合得分,这里是对每一个主成分的简单求和
%total_score(i,2)=new_score(i,1)*DS(1,2)+new_score(i,2)*DS(2,2)+new_score(i,3)*DS(3,2)
n=1:3;
total_score(i,2)=new_score(i,n)*DS(n,2);
total_score(i,1)=i;%给个序列
end
result_report=[new_score,total_score]%最终输出每个主成分得分以及综合得分以及每个序号所对应的综合排名
result_report=sortrows(result_report,-5)
% 显示结果
disp('特征值及贡献率:')
DS
disp('阀值T对应的主成分数与特征向量:')
Com_num
PV
disp('主成分分数:')
new_score
disp('主成分分数排序:')
result_report
调用函数求解结果
调用函数求解得到的特征值及贡献率
对比上文的SPSS求解这个是没有问题的
得到的特征向量矩阵
前文SPSS没有求解,但根据换算的公式,最终的到结果理论也应该是如此
最后的主成分得分以及综合得分以及综合实力排序
同理,自己根据原理编写代码相关结果如下:
特征值及其贡献率
得到的特征向量矩阵
最终主成分得分及其综合得分排名
排名有一些出入,主要是由于调用函数的代码部分在进行综合得分输出的时候的每个主成分的权重和自己编写的时候权重的大小(根据贡献大小确定对应权重)有些差异导致。但结果基本一致。