奇异值分解
A=UDVT
其中 A 是一个
实际上对应特征值与奇异值有如下关系:
σi=λi−−√
μi=1σiAνi
σ
是奇异值,
μ
是左奇异向量,
ν
是右奇异向量。
在很多情况下,前10%甚至1%的奇异值的和就占了全部的奇异值之和的99%以上了。也就是说,我们也可以用前 r 大的奇异值来近似描述矩阵。
Moore-Penrose伪逆
若有
x=By
,则Moore-Penrose伪逆为
A+=VD+UT
D
的伪逆为非零元素取倒数之后再转置得到。 PCA
计算步骤
1. 计算均值并减去均值
2. 计算协方差矩阵
3. 求协方差的特征值和特征向量
4. 将特征值按照从大到小的顺序排序,选择其中最大的
k
个,然后将其对应的
5. 将样本点投影到选取的特征向量上
reconMat=dataMat×FeatureVector
python实现PCA
import numpy as np
def calMean(dataMat):
"""
dataMat: 原数据
return:
mean: 均值
newData: 原数据 - 均值
"""
mean = np.mean(dataMat,axis = 0)
newData = dataMat - mean
return newData, mean
def getK(eigVals, percentage):
"""
确定选择k多少
"""
sortEigvals = np.sort(eigvals)
sortEigvals = sortEigvals[-1::-1]
sum = sum(sortEigvals)
temSum = 0
for k, eigval in enumerate(sortEigvals):
temSum += eigval
if temSum >= sum * percentage:
return k
def pca(dataMat,percentage=0.99):
newData,mean=calMean(dataMat)
covMat=np.cov(newData,rowvar=0) #求协方差矩阵,return ndarray;若rowvar非0,一列代表一个样本,为0,一行代表一个样本
eigVals,eigVects=np.linalg.eig(np.mat(covMat))#求特征值和特征向量,特征向量是按列放的,即一列代表一个特征向量
k=getK(eigVals,percentage) #要达到percent的方差百分比,需要前n个特征向量
eigValIndice=np.argsort(eigVals) #对特征值从小到大排序
k_eigValIndice=eigValIndice[-1:-(k+1):-1] #最大的n个特征值的下标
k_eigVect=eigVects[:,k_eigValIndice] #最大的n个特征值对应的特征向量
lowDataMat=newData*k_eigVect #低维特征空间的数据
reconMat=(lowDataMat*k_eigVect.T)+meanVal #重构数据
return lowDataMat,reconMat