机器学习:降维工具 - SVD

Posted moonlight-lin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了机器学习:降维工具 - SVD相关的知识,希望对你有一定的参考价值。

SVD(Singular Value Decomposition,奇异值分解)是一种强大的降维工具
??
很多情况下,数据的一小段携带了大部分信息,其他要么是噪声,要么就是毫不相关的信息,SVD 是矩阵分解的一种,可以把 SVD 看成是从噪声数据中抽取相关特征
??
优点:简化数据,去除噪声,提高算法的结果
缺点:数据的转换可能难以理解
??
应用例子
??隐性语义索引
??推荐系统
??
SVD 将原始的数据集矩阵 (small Data) 分解成三个矩阵 (small U)(small Σ)(small V^{T})
如果原矩阵 (small Data)mn 列,那么 (small U)(small Σ)(small V^{T}) 分别是 mm 列、mn 列、nn
??
??(small Data(m,n) = U(m,m) imes Σ(m,n) imes V^{T}(n,n))
??
(small Σ) 矩阵只有对角元素,其他元素均为 0,非 0 元素的个数是 m 或 n (取小的那个)
(small Σ) 的对角元素是从大到小排列的,这些对角元素称为奇异值 (Singular Value),它们对应了原始数据集矩阵 (small Data) 的奇异值,奇异值和特征值是有关系的,这里的奇异值是矩阵 (small Data imes Data^{T}) 的特征值的平方根
??
在科学和工程中,一直存在这样一个普遍事实:在某个奇异值的数目(r个)之后,其他的奇异值都置为 0,这就意味着数据集中仅有 r 个重要特征,而其余特征则都是噪声或冗余特征
??
numpy 解奇异矩阵

"""
data 如果不是矩阵的话,需要通过 np.mat() 函数转换为矩阵

Sigma 以行向量返回,但其代表的是矩阵,维度 m*n
因为该矩阵除了对角线外都是 0,所以用一行代表对角线上的每个值,节省空间

将 Sigma 转换为矩阵
    if m > n:
        Sigma = np.mat(np.eye(n)*Sigma)
        Sigma = np.row_stack((Sigma, np.zeros((m-n,n))))
    elif m < n:
        Sigma = np.mat(np.eye(m)*Sigma)
        Sigma = np.column_stack((Sigma, np.zeros((m,n-m))))

结果满足 data = U * Sigma * VT
"""
U,Sigma,VT = np.linalg.svd(data)


(small Σ) 取前 r 个值,则有
??(small Data(m,n) approx U(m,r) imes Σ(r,r) imes V^{T}(r,n))
??
确定要保留的奇异值的数目有很多启发式的策略
??
其中一个典型的做法就是保留矩阵中 90% 的能量信息
将所有的奇异值求平方和,将奇异值的平方和累加到总值的 90% 为止
??
另一个启发式策略就是,当矩阵上有上万的奇异值时,那么就保留前面的 2000 或 3000 个
??
假设 (small data) 每行是用户,每列是物品
(small V^{T}) 矩阵会将用户映射到物品分类空间去
类似地 (small U) 矩阵会将物品映射到物品分类空间去
??
基于 SVD 的图像压缩

# coding=utf-8
import numpy as np


def imgCompress(numSV=3, thresh=0.8):
    """
    numSV - 保留的奇异值数目
    thresh - 阀值,大于这个值当成 1
    """

    myl = []
    # 将图片读入存储在矩阵中,假设是黑白只有 01 值
    for line in open('0_5.txt').readlines():
        newRow = []
        for i in range(32):
            newRow.append(int(line[i]))
        myl.append(newRow)

    myMat = np.mat(myl)
    print "****original matrix******"
    printMat(myMat, thresh)

    # 求解奇异值矩阵
    U, Sigma, VT = np.linalg.svd(myMat)

    SigRecon = np.mat(np.zeros((numSV, numSV)))
    for k in range(numSV):
        # 将 Sigma 转换为 numSV 阶矩阵
        SigRecon[k, k] = Sigma[k]

    # 通过奇异值矩阵降维
    reconMat = U[:, :numSV] * SigRecon * VT[:numSV, :]
    
    print "****reconstructed matrix using %d singular values******" % numSV
    printMat(reconMat, thresh)


def printMat(inMat, thresh=0.8):
    for i in range(32):
        for k in range(32):
            if float(inMat[i, k]) > thresh:
                print 1,
            else:
                print 0,
        print ''

??



以上是关于机器学习:降维工具 - SVD的主要内容,如果未能解决你的问题,请参考以下文章

机器学习实战基础(二十六):sklearn中的降维算法PCA和SVD 附录

机器学习——降维(主成分分析PCA线性判别分析LDA奇异值分解SVD局部线性嵌入LLE)

机器学习实战基础(二十三):sklearn中的降维算法PCA和SVD PCA与SVD 之 PCA中的SVD

机器学习实战基础(二十三):sklearn中的降维算法PCA和SVD PCA与SVD 之 PCA中的SVD

机器学习(十七)— SVD奇异值分解

机器学习实战精读--------奇异值分解(SVD)