常见的数据降维算法有:奇异值分解(SVD)、主成分分析(PCA)、因子分析(FA)、独立成分分析(ICA)。
PCA降维的基本思想:通过计算数据矩阵的协方差矩阵,然后得到协方差矩阵的特征值、特征向量、选择特征值最大(即方差最大)的K个特征所对应的特征向量组成的矩阵,这样可以将数据矩阵转换到新的空间当中,实现数据特征的降维。
PCA降维有两种思路:一种是特征值分解协方差矩阵,一种是奇异值分解协方差矩阵。下面介绍基于奇异值分解的方法
一:关于特征值分解
a)特征值与特征向量
如果一个向量v是矩阵A的特征向量,将一定可以表示成下面的形式
其中,λ是特征向量v对应的特征值,一个矩阵的一组特征向量是一组正交向量。
b)特征值分解矩阵
对于矩阵A,有一组特征向量v,将这组向量进行正交化单位化,就能得到一组正交单位向量。特征值分解,就是将矩阵A分解为如下式:
其中,Q是矩阵A的特征向量组成的矩阵,则是一个对角阵,对角线上的元素就是特征值。
二:SVD分解矩阵原理
奇异值分解是一个能适用于任意矩阵的一种分解的方法,对于任意矩阵A总是存在一个奇异值分解:
假设A是一个m*n的矩阵,那么得到的U是一个m*m的方阵,U里面的正交向量被称为左奇异向量。Σ是一个m*n的矩阵,Σ除了对角线其它元素都为0,对角线上的元素称为奇异值,是v的转置矩阵,是一个n*n的矩阵,它里面的正交向量被称为右奇异值向量。而且一般来讲,我们会将Σ上的值按从大到小的顺序排列。
SVD分解矩阵A的步骤:
(1) 求的特征值和特征向量,用单位化的特征向量构成 U。
(2) 求的特征值和特征向量,用单位化的特征向量构成 V。
(3) 将或者的特征值求平方根,然后构成 Σ
三:实现PCA算法的步骤:
(1)去均值(即去中心化)每一位特征减去各自的平均值。
(2)计算协方差矩阵1/n*xx'
(3) 用奇异值分解法求协方差矩阵1/n*xx'的特征值与特征向量
(4)对特征值从大到小排序,选择其中最大的k个,然后将其对应的k个特征向量分别作为行向量组成特征向量矩阵P
(5)将数据转换到K个特征向量构建的新空间中即Y=PX
如何选择主成分个数K
1- <=t
Sii为SVD分解时产生的S矩阵
t的值可以自己设置,t取0.01则代表PCA保留了99%的信息。
最好的K维特征是将n维样本点转换为K维后,每一维上的样本方差都很大。
补:matlab自带的mean函数用法。mean(x)默认求矩阵列的平均值。mean(x,2)求矩阵行的平均值。
std函数:求矩阵的标准差
std(A)是最常见的求标准差的函数,除以的是N-1
std(A,flag)代表的是用哪一个标准差函数,如果取0则代表除以N-1,如果1代表的是除以N
std(A,flag,dim)第三个参数代表的是按照列求标准差,还是按照行求标准差。
repmat函数处理大矩阵且内容重复时会用到
eg B=repmat([1 2;3 4],2,3)
B= 1 2 1 2 1 2
3 4 3 4 3 4
1 2 1 2 1 2
3 4 3 4 3 4
length(x)矩阵 M行N列返回M和N这两个数的最大值。
归一化(按列减均值)
标准化(按列缩放到指定范围)
正则化(范数)
eig函数的用法
a=[-1,1,0;-4,3,0;1,0,2]
eig(a)= [2,1,1]'
[v,d]=eig(a)
v =
0 0.4082 0.4082
0 0.8165 0.8165
1.0000 -0.4082 -0.4082
d =
2 0 0
0 1 0
0 0 1
v是特征向量对应的特征矩阵。d是特征向量组成的矩阵。
rot函数的用法
b=rot90(a)逆时针旋转90度
b=rot90(a,-1)顺时针旋转90度
matlab代码实现(待改进:此方法采用的是基于特征值分解的方法,改进为用奇异值分解的方法)
function S=princa(X)
[m,n]=size(X); %计算矩阵的行m和列n
%-------------第一步:标准化矩阵-----------------%
mv=mean(X); %计算各变量的均值
st=std(X); %计算各变量的标准差
X=X-repmat(mv,m,1); %标准化矩阵X
%-------------第二步:计算相关系数矩阵-----------------%
% R1=X'*X/(m-1); %方法一:协方差矩阵计算公式
% R2=cov(X); %方法二:协方差矩阵计算函数
R=corrcoef(X); %方法三:相关系数矩阵函数
%-------------第三步:计算特征向量和特征值-----------------%
[V,D]=eig(R); %计算矩阵R的特征向量矩阵V和特征值矩阵D,特征值由小到大
%将特征向量矩阵V从大到小排序
%将特征值矩阵由大到小排序
E=diag(D); %将特征值矩阵转换为特征值向量
%-------------第四步:计算贡献率和累计贡献率-----------------%
ratio=0; %累计贡献率
for k=1:n
r=E(k)/sum(E); %第k主成份贡献率
ratio=ratio+r; %累计贡献率
if(ratio>=0.8) %取累计贡献率大于等于90%的主成分
q=k;
break;
end
end
%-------------第五步:计算得分-----------------%
V=V(:,1:q);
S=X*V;
python代码实现
import numpy as np
def pca(X,k):
n_samples, n_features = X.shape
mean=np.array([np.mean(X[:,i]) for i in range(n_features)])
norm_X=X-mean
scatter_matrix=np.dot(np.transpose(norm_X),norm_X)
eig_val, eig_vec = np.linalg.eig(scatter_matrix)
eig_pairs = [(np.abs(eig_val[i]), eig_vec[:,i]) for i in range(n_features)]
eig_pairs.sort(reverse=True)
feature=np.array([ele[1] for ele in eig_pairs[:k]])
data=np.dot(norm_X,np.transpose(feature))
return data
#print(eig_pairs)
X = np.array([[-1, 1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
print(pca(X,1))
利用sklearn中的PCA函数实现
from sklearn.decomposition import PCA
import numpy as np
X = np.array([[-1, 1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
pca=PCA(n_components=1)
pca.fit(X)
print(pca.transform(X))
#ske
参考资料:写得巨好超级推荐https://blog.csdn.net/program_developer/article/details/80632779