【深度学习】奇异值分解与Moore-Penrose伪逆

  • Post author:
  • Post category:其他


奇异值分解








A


=


U




D





V








T


















其中








A











是一个









m


×


n












的矩阵,








U













是一个









m


×


m












矩阵,








D











是一个









m


×


n












的矩阵,








V













是一个









n


×


n












矩阵。








U























V














是正交矩阵,








D











是对角矩阵。D的对角线元素就是奇异值。









U























V













的列向量称为左右奇异向量。

实际上对应特征值与奇异值有如下关系:









(





A






T









A


)





ν








i







=





λ






i










ν








i
















其中










σ








i







=









λ






i






















































μ






i







=





1









σ








i


















A





ν








i























σ













是奇异值,








μ











是左奇异向量,








ν













是右奇异向量。

在很多情况下,前10%甚至1%的奇异值的和就占了全部的奇异值之和的99%以上了。也就是说,我们也可以用前








r











大的奇异值来近似描述矩阵。

Moore-Penrose伪逆

若有









A












与其左逆








B











,有








A


x


=


y













以及







x


=


B


y












,则Moore-Penrose伪逆为










A






+







=


V







D






+










U








T

























D











的伪逆为非零元素取倒数之后再转置得到。










A












的列数大于行数,得到就是所有可行解中











L






2
















范数最小的一个,如果相反,就是











L






2







(


A


x





y




)











最小。

PCA

计算步骤


1. 计算均值并减去均值



2. 计算协方差矩阵



3. 求协方差的特征值和特征向量



4. 将特征值按照从大到小的顺序排序,选择其中最大的








k











个,然后将其对应的









k












个特征向量分别作为列向量组成特征向量矩阵



5. 将样本点投影到选取的特征向量上









r


e


c


o


n


M




a


t


=


d




a


t


a


M




a


t


×


F




e


a


t


u


r


e


V




e


c


t


o


r









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  

参考资料


  1. 机器学习中的数学(5)-强大的矩阵奇异值分解(SVD)及其应用

  2. 【机器学习算法实现】主成分分析(PCA)——基于python+numpy
  3. 《深度学习》花书