码迷,mamicode.com
首页 > 其他好文 > 详细

机器学习:降维工具 - SVD

时间:2020-03-14 21:37:56      阅读:75      评论:0      收藏:0      [点我收藏+]

标签:系统   降维   str   compress   original   理解   关系   一个   class   

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) \times Σ(m,n) \times V^{T}(n,n)\)
??
\(\small Σ\) 矩阵只有对角元素,其他元素均为 0,非 0 元素的个数是 m 或 n (取小的那个)
\(\small Σ\) 的对角元素是从大到小排列的,这些对角元素称为奇异值 (Singular Value),它们对应了原始数据集矩阵 \(\small Data\) 的奇异值,奇异值和特征值是有关系的,这里的奇异值是矩阵 \(\small Data \times 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) \times Σ(r,r) \times 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

标签:系统   降维   str   compress   original   理解   关系   一个   class   

原文地址:https://www.cnblogs.com/moonlight-lin/p/12494265.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!