《统计学习方法》笔记--奇异值分解

奇异值分解(singular value decomposition,SVD)一种矩阵因子分解的方法,在主要成分分析和潜在语义分析都会用到这一重要的工具。

其即是将一个的实矩阵A,表示成三个实矩阵乘积形式,

其中U是m阶的正交矩阵,V是n阶的正交矩阵,而是由A矩阵的奇异值由降序排列成对角线组成的对角矩阵。

分解的几何解释是将任意一个n维向量,根据公式从右到左,先经过坐标系的旋转或反转变换,再经过坐标轴的放缩变化,以及坐标系的旋转或反转变换,最后得到向量,变换图像如下

图1-1 奇异值分解的几何解释图

在实际应用中,奇异值分解可用于对矩阵进行压缩,分为紧凑形式和截断形式的。紧凑形式是将矩阵分解后,奇异值矩阵的秩与原矩阵的秩相等,对应着数据的无损压缩;而截断形式的则是将矩阵分解后,奇异值矩阵的秩小于原矩阵的秩,对应着数据的有损压缩

奇异值分解的计算可以根据奇异值分解的性质进行计算,所利用到的性质主要有:

  1. 因此奇异值分解算法可如下:

    输入:矩阵A;

    输出:左奇异矩阵,奇异值矩阵和右奇异矩阵

    (1)先求的特征值和特征向量,

    得到特征值(其中前r个大于零,剩余的值为0),并将其从大到小排序;将排好序的特征值代入方程求得对应特征向量

    (2)将特征向量单位化,得到的单位化的特征向量构成右奇异矩阵

    (3)将求得的排好序的特征值开平方,,并其将构造成的对角矩阵,即奇异值矩阵

    (4)根据 求得A的前 r 个正奇异值的对应的左奇异矩阵的前 r 个列向量

    再由求奇异值为0对应的左奇异矩阵的列向量,则左奇异矩阵

     

    用 sklearn 简单实现 SVD 对图像的压缩测试

    import numpy as np

    import numpy.linalg as la

    import matplotlib.pyplot as plt

    from skimage import io

     

     

    #获取图片并转化为矩阵

    def getImgFromFileToMat(filename):

    img = io.imread(filename, as_grey=True)

    return np.mat(img)

     

    def compressWithSVD(img, k):

    # 获得图像的左奇异矩阵U,奇异值矩阵s和右奇异矩阵V

    U, s, V = la.svd(img)

    # 选择三个矩阵的前k个元素

    Uk = U[:, 0:k]

    Sk = np.diag(s[0:k])

    Vk = V[0:k, :]

    #利用三个截断矩阵恢复图像

    img_new = Uk * Sk * Vk

    return img_new

     

    #显示图片

    def showImg(imgMat):

    plt.imshow(imgMat, cmap=plt.cm.gray)

    plt.show()

    可以看到k越小时,图像被压缩的越厉害,损失越大。

    而损失的大小可根据弗罗贝尼乌斯范数和其引理

    进行计算,假设原矩阵A的秩为r,进行截断式奇异值分解后,得到秩为k(k<r)的奇异值矩阵,则分解后,其损失函数为 L

    即损失了原矩阵的奇异值矩阵后面n-k个非零奇异值的范数。

posted @ 2020-03-24 22:14  lincoding`  阅读(987)  评论(0编辑  收藏  举报