zoukankan      html  css  js  c++  java
  • 机器学习:降维工具

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




  • 相关阅读:
    Windows XP下 Android开发环境 搭建
    Android程序的入口点
    在eclipse里 新建android项目时 提示找不到proguard.cfg
    64位WIN7系统 下 搭建Android开发环境
    在eclipse里 新建android项目时 提示找不到proguard.cfg
    This Android SDK requires Android Developer Toolkit version 20.0.0 or above
    This Android SDK requires Android Developer Toolkit version 20.0.0 or above
    Android requires compiler compliance level 5.0 or 6.0. Found '1.4' instead
    Windows XP下 Android开发环境 搭建
    Android程序的入口点
  • 原文地址:https://www.cnblogs.com/moonlight-lin/p/12494265.html
Copyright © 2011-2022 走看看