机器学习:降维工具

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 ''




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