• 郑捷《机器学习算法原理与编程实践》学习笔记(第四章 推荐系统原理)(三)SVD


      4.5.1 SVD算法回顾

      A = U∑VT

      其中:A是N*M的矩阵,U是M*M的方阵(里面向量正交,称为左奇异向量),∑是一个M*N的矩阵,VT是一个N*N的矩阵(里面向量正交,右奇异向量)

      那么奇异值是怎么对应起来的呢?首先,将矩阵A转置AT,将会得到一个方阵,这个方阵求特征值可以得到:

      (AAT)v = λv

      这里得到的v,就是我们上面的右奇异值,此外我们还可以得到:

      δ = λ1/2=>u=Av/δ

      δ就是奇异值,u就是上面说的左奇异向量。奇异值δ跟特征值类似,在矩阵∑中也是按从大到小排列。而且δ的减少特别快,在很多情况下,前10%甚至1%的奇异值的和就占了全部奇异值之和的99%以上,也就是,我们也可以用前r个奇异值来近似描述矩阵。这里定义一下部分奇异值分解:

      Am×n≈ Am×r = Um×rr×rVTr×n

      右边的三个矩阵相乘的结果将会是一个接近于A的矩阵,在这里,r越接近于n,则相乘的结果越接近于A。而这三个矩阵的面积之和(对于存储观点来说,矩阵面积越小,存储量就越小)要远远小于原始的矩阵A。我们如果想要压缩空间来表示矩

    阵,只要记录U、∑、V三个矩阵即可。

      例子:

      

    #coding:utf-8
    from numpy import *
    
    A        = mat([[5,5,3,0,5,5],
                    [5,0,4,0,4,4],
                    [0,3,0,5,4,5],
                    [5,4,3,3,5,5]])
    U         = A*A.T   #手工分解求矩阵的svd
    lamda,hU = linalg.eig(U) #hU:U特征向量
    VT        = A.T*A
    ev,hVT    = linalg.eig(VT)#hVT:VT特征向量
    hV        = hVT.T
    print "hU:",hU           #U矩阵
    print "hV:",hV           #V矩阵
    sigma     = sqrt(lamda)   #奇异值
    print"sigma:",sigma

      使用NumPy的Linalg中的svd函数计算如下。

    sigma     = np.zeros([shape(A)[0],shape(A)[1]])
    U,S,VT    = linalg.svd(A)
    print S

      4.5.2 常用的距离函数

      (1)欧式距离

    #欧式距离
    eps = 1.0e-6
    def distEclud(vecA,vecB):
        return linalg.norm(vecA-vecB) + eps

      (2)相关系数

      

    def distCorrcoef(vecA,vecB):
        return corrcoef(vecA,vecB,rowvar = 0)[0][1]

      (3)Jaccard距离

    import scipy.spatial.distance as dist
    def distJaccard(vecA,vecB):
        temp = mat([array(vecA.tolist()[0]),array(vecB.tolist()[0])])
        return dist.pdist(temp,'jaccard')

      (4)余弦定理

    def cosSim(vecA,vecB):
        return dot(vecA,vecB)/((linalg.norm(vecA)*(linalg.norm(vecB))+eps)

      4.5.3 SVD数据集

      SVD数据集用于计算奇异值分解测试。

      

    #加载修正后的数据
    trainset = mat([[0,0,0,0,0,4,0,0,0,0,5],
                    [0,0,0,3,0,4,0,0,0,0,3],
                    [0,0,0,0,4,0,0,1,0,4,0],
                    [3,3,4,0,0,0,0,2,2,0,0],
                    [5,4,5,0,0,0,0,5,5,0,0],
                    [0,0,0,0,5,0,1,0,0,5,0],
                    [4,3,4,0,0,0,0,5,5,0,1],
                    [0,0,0,4,0,4,0,0,0,0,4],
                    [0,0,0,2,0,2,5,0,0,1,2],
                    [0,0,0,0,5,0,0,0,0,4,0],])
    test = mat([[1,0,0,0,0,0,0,1,2,0,0]])

    4.5.4 SVD算法主函数

      根据SVD的原理,我们实现了最简单的SVD算法的主函数。

      

    #coding:utf-8
    __author__ = 'wuchuanying'
    
    #dataSet 训练集
    #testVect 测试集
    #r = 3 取前r个近似值
    #rank =1 ,结果排序
    #distCalc 相似度计算函数
    
    from numpy import *
    
    def recommand(dataSet,testVect,r = 3,rank = 1,distCalc = cosim):
        m,n = shape(dataSet)
        limit = min(m,n)
        if r > limit:
            r = limit
        U,S,VT = linalg.svd(dataSet.T)   #svd分解
        V      = VT.T
        Ur     = U[:,:r]
        Sr     = diag(S)[:r,:r]         #If v is a 1-D array, return a 2-D array with v on the k-th diagonal.
        Vr     = V[:,:r]
        testresult = testVect*Ur*linalg.inv(Sr)  #计算User E的坐标值
        #计算测试集与训练集每个记录的相似度
        resultarray = array([distCalc(testresult,vi) for vi in vr])
        descindx    = argsort(-resultarray)[:rank]  #排序结果---降序
        return descindx,resultarray[descindx]      #排序后的索引和值

      4.5.5 评估结果

      执行Recommend_lib中的推荐方法,获取执行结果

      

    trainset = mat([[0,0,0,0,0,4,0,0,0,0,5],
                    [0,0,0,3,0,4,0,0,0,0,3],
                    [0,0,0,0,4,0,0,1,0,4,0],
                    [3,3,4,0,0,0,0,2,2,0,0],
                    [5,4,5,0,0,0,0,5,5,0,0],
                    [0,0,0,0,5,0,1,0,0,5,0],
                    [4,3,4,0,0,0,0,5,5,0,1],
                    [0,0,0,4,0,4,0,0,0,0,4],
                    [0,0,0,2,0,2,5,0,0,1,2],
                    [0,0,0,0,5,0,0,0,0,4,0],])
    test = mat([[1,0,0,0,0,0,0,1,2,0,0]])
    
    indx,resultarray = recommand(A,test,r = 2,rank = 2,distCalc = cosSim)

      执行结果如下:

      [4,3]

      [0.99995847,0.99987554]

      返回最相似的两个向量,第一个相似度是99.996%,第二个相似度99.998%,可以将这两个向量的物品推荐给测试集中的用户。

      资料来源及版权所有:郑捷《机器学习算法原理与编程实践》 仅供学习研究

      

      

  • 相关阅读:
    EOS概念理解总结
    boost asio one client one thread
    EOS 数据签名与公匙验证代码用例
    EOS 智能合约编写(一)
    EOS多节点同步代码分析
    EOS 用户权限相关命令
    EOS 多主机多节点配置终极命令
    EOS多主机多节点环境配置
    ubuntu命令错误集
    java多线程中的调度策略
  • 原文地址:https://www.cnblogs.com/wuchuanying/p/6265699.html
Copyright © 2020-2023  润新知