奇异值分解SVD实现与应用

SVD是一种提取信息的强大工具,通过SVD实现我们能够用小的多的数据集来表示原始数据集,这样做实际就是去除噪声和冗余信息。

隐性语义索引

SVD最早应用就是信息检索,我们称利用SVD方法为隐性语义索引(LSI),在LSI中一个矩阵是由文档和词语组成,当应用SVD到矩阵上时,就会构建多个奇异值。这些奇异值代表了文档中概念或主题,这一特点可以更高效的文档搜索。

推荐系统

SVD的另外一个应用就是推荐系统,简单版本实现推荐系统就是计算item或者user之间相似性。更先进的方法就是利用SVD从数据中构建一个主题空间,然后在该空间下计算相似度。

基于python对SVD方法在简单推荐系统中实现。

中间用到了python两个很常用函数方法

sorted 方法和 nonzero 方法。

sorted方法是python内置的方法,我们实现中要用到对元组进行排序,如下:

>>> student_tuples = [
    ('john', 'A', 15),
    ('jane', 'B', 12),
    ('dave', 'B', 10),
]
>>> sorted(student_tuples, key=lambda student: student[2])   # sort by age
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

参考链接:sorted方法

nonzero返回二维的不为0的index,看例子:

>>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> a > 3
array([[False, False, False],
       [ True,  True,  True],
       [ True,  True,  True]], dtype=bool)
>>> np.nonzero(a > 3)
(array([1, 1, 1, 2, 2, 2]), array([0, 1, 2, 0, 1, 2]))

参考链接:nonzero方法

# encoding=utf8
import numpy as np
from numpy import *
from numpy import linalg as la
from operator import itemgetter

def loadExData():
    return [[4,4,0,2,2],
            [4,0,0,3,3],
            [4,0,0,1,1],
            [1,1,1,2,0],
            [2,2,2,0,0],
            [1,1,1,0,0],
            [5,5,5,0,0]]

def loadExData2():
    return[[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],
           [1, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0]]

def ReconstructSigma(Sigma):
    return np.mat([[Sigma[0],0,0],[0,Sigma[1],0],[0,0,Sigma[2]]])

def ReconstructData(U,Sigma,VT):
    return U[:,:3]*Sigma*VT[:3,:]

# 计算相似性函数
def eulidSim(inA,inB):
    return 1.0/(1.0 + la.norm(inA - inB))#默认计算列做为一个元素之间的距离

def pearsSim(inA,inB):
    if(len(inA)<3): return 1.0
    return 0.5 + 0.5*np.corrcoef(inA, inB, rowvar=0)[0][1]# 这里返回是一个矩阵,只拿第一行第二个元素

def cosSim(inA,inB):
    num = float(inA.T * inB)
    denom = la.norm(inA) * la.norm(inB)
    return 0.5 + 0.5 * (num/denom)
'''
standEst 需要做的就是估计user 的item 评分,
采用方法是  根据物品相似性,及每一列相似性
要估计item那一列与其他列进行相似性估计,获得两列都不为0的元素计算相似性
然后用相似性乘以 评分来估计未评分的数值 。
'''
def standEst(dataMat,user,simMeas,item):
    n = np.shape(dataMat)[1]
    simTotal = 0.0 ; ratSimTotal = 0.0
    for j in range(n):
        userRating = dataMat[user,j]
        if(userRating == 0): continue
        overLap = nonzero(logical_and(dataMat[:,item].A > 0,dataMat[:,j].A >0))[0]# 返回元素不为0的下标
        '''
        nonzero 返回参考下面例子,返回二维数组,第一维是列方向,第二位是行方向
        '''
        if(len(overLap)) == 0 :similarity = 0
        else:
            similarity = simMeas(dataMat[overLap,item],dataMat[overLap,j])
        print 'the %d and %d similarity is : %f' %(item,j,similarity)
        simTotal += similarity
        ratSimTotal += similarity * userRating
    if simTotal == 0: return 0
    else : return ratSimTotal/simTotal

def recommend(dataMat,user ,N = 3,simMeas= cosSim,estMethod = standEst):
    unratedItems = nonzero(dataMat[user,:].A == 0)[1]# .A 使得矩阵类型转为array
    '''
    >>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
    >>> a > 3
    array([[False, False, False],
       [ True,  True,  True],
       [ True,  True,  True]], dtype=bool)
    >>> np.nonzero(a > 3)
    (array([1, 1, 1, 2, 2, 2]), array([0, 1, 2, 0, 1, 2]))
    '''
    if len(unratedItems) == 0: return 'you rated everything'
    itemScores = []
    for item in unratedItems:
        estimatedScore = estMethod(dataMat,user,simMeas,item)
        itemScores.append((item,estimatedScore))
    return sorted(itemScores,key=itemgetter(1),reverse = True)[:N]

def svdEst(dataMat , user, simMeas,item):
    n = shape(dataMat)[1]
    simTotal = 0.0 ; ratSimTotal = 0.0
    U,Sigma,VT = la.svd(dataMat)
    Sig4 = mat(eye(4) * Sigma[:4]) # 保留最大三个奇异值
    xformedItems = dataMat.T * U[:,:4] * Sig4.I
    print xformedItems
    for j in range(n):
        userRating = dataMat[user,j]
        if userRating == 0 or j==item: continue
        similarity = simMeas(xformedItems[item,:].T,                             xformedItems[j,:].T)
        print 'the %d and %d similarity is: %f' % (item, j, similarity)
        simTotal += similarity
        ratSimTotal += similarity * userRating
    if simTotal == 0: return 0
    else: return ratSimTotal/simTotal

if __name__=="__main__":
    '''
    # 测试中间数据
    Data = loadExData()
    MatData = np.mat(Data)
    U,Sigma,VT = np.linalg.svd(Data)
    print Sigma
    Sigma = ReconstructSigma(Sigma)
    print Sigma
    print ReconstructData(U, Sigma, VT)
    print eulidSim(MatData[:,0], MatData[:,4])
    print cosSim(MatData[:,0], MatData[:,4])
    print pearsSim(MatData[:,0], MatData[:,0])
    '''
    Data = loadExData()
    dataMat = np.mat(Data)
    dataMat2 = mat(loadExData2())
    print dataMat2
    print recommend(dataMat2, 1,estMethod=svdEst)
    

实现细节参考机器学习实战。

时间: 2024-11-05 10:29:32

奇异值分解SVD实现与应用的相关文章

奇异值分解(SVD) --- 几何意义 (转载)

PS:一直以来对SVD分解似懂非懂,此文为译文,原文以细致的分析+大量的可视化图形演示了SVD的几何意义.能在有限的篇幅把 这个问题讲解的如此清晰,实属不易.原文举了一个简单的图像处理问题,简单形象,真心希望路过的各路朋友能从不同的角度阐述下自己对SVD实际意义的理 解,比如 个性化推荐中应用了SVD,文本以及Web挖掘的时候也经常会用到SVD. 原文:We recommend a singular value decomposition 关于线性变换部分的一些知识可以猛戳这里  奇异值分解(S

[机器学习笔记]奇异值分解SVD简介及其在推荐系统中的简单应用

本文先从几何意义上对奇异值分解SVD进行简单介绍,然后分析了特征值分解与奇异值分解的区别与联系,最后用python实现将SVD应用于推荐系统. 1.SVD详解 SVD(singular value decomposition),翻译成中文就是奇异值分解.SVD的用处有很多,比如:LSA(隐性语义分析).推荐系统.特征压缩(或称数据降维).SVD可以理解为:将一个比较复杂的矩阵用更小更简单的3个子矩阵的相乘来表示,这3个小矩阵描述了大矩阵重要的特性. 1.1奇异值分解的几何意义(因公式输入比较麻烦

机器学习中的数学(5)-强大的矩阵奇异值分解(SVD)及其应用

机器学习中的数学(5)-强大的矩阵奇异值分解(SVD)及其应用 版权声明: 本文由LeftNotEasy发布于http://leftnoteasy.cnblogs.com, 本文可以被全部的转载或者部分使用,但请注明出处,如果有问题,请联系[email protected] 前言: 上一次写了关于PCA与LDA的文章,PCA的实现一般有两种,一种是用特征值分解去实现的,一种是用奇异值分解去实现的.在上篇文章中便是基于特征值分解的一种解释.特征值和奇异值在大部分人的印象中,往往是停留在纯粹的数学计

奇异值分解(SVD)

特征值分解是利用矩阵的对角化来完成的:A=Q∧Q-1,但这种分解方法需要满足一个前提条件,即A是方阵. 奇异值分解(SVD)可以对m x n的矩阵进行分解.我们希望找到一个n x n的正交方阵V.一个m x m的正交方阵U和一个m x n的矩阵∑,使得A满足式子AV=U∑.因为V是正交矩阵,所以V是可逆,且V-1=VT,所以AV=U∑又可以写成A=U∑VT.下面分两步来找到V和U. 1)注意到ATA是一个对称方阵,如果存在一个n x n的正交方阵V.一个m x m的正交方阵U和一个m x n的矩

奇异值分解(SVD)原理详解及推导

声明:转自http://blog.csdn.net/zhongkejingwang/article/details/43053513 在网上看到有很多文章介绍SVD的,讲的也都不错,但是感觉还是有需要补充的,特别是关于矩阵和映射之间的对应关系.前段时间看了国外的一篇文章,叫A Singularly Valuable Decomposition The SVD of a Matrix,觉得分析的特别好,把矩阵和空间关系对应了起来.本文就参考了该文并结合矩阵的相关知识把SVD原理梳理一下. SVD不

用 GSL 求解超定方程组及矩阵的奇异值分解(SVD)

用 GSL 求解超定方程组及矩阵的奇异值分解(SVD) 最近在学习高动态图像(HDR)合成的算法,其中需要求解一个超定方程组,因此花了点时间研究了一下如何用 GSL 来解决这个问题. GSL 里是有最小二乘法拟合(Least-Squares Fitting)的相关算法,这些算法的声明在 gsl_fit.h 中,所以直接用 GSL 提供的 gsl_fit_linear 函数就能解决这个问题.不过我想顺便多学习一些有关 SVD 的知识.所以就没直接使用 gsl_fit_linear 函数. SVD

【简化数据】奇异值分解(SVD)

[简化数据]奇异值分解(SVD) @author:wepon @blog:http://blog.csdn.net/u012162613/article/details/42214205 1.简介 奇异值分解(singular Value Decomposition),简称SVD,线性代数中矩阵分解的方法.假如有一个矩阵A,对它进行奇异值分解,可以得到三个矩阵: 这三个矩阵的大小: 矩阵sigma(即上图U和V中间的矩阵)除了对角元素不为0,其他元素都为0,并且对角元素是从大到小排列的,前面的元

奇异值分解(SVD) --- 几何意义

PS:一直以来对SVD分解似懂非懂,此文为译文,原文以细致的分析+大量的可视化图形演示了SVD的几何意义.能在有限的篇幅把这个问题讲解的如此清晰,实属不易.原文举了一个简单的图像处理问题,简单形象,真心希望路过的各路朋友能从不同的角度阐述下自己对SVD实际意义的理解,比如 个性化推荐中应用了SVD,文本以及Web挖掘的时候也经常会用到SVD. 原文:We recommend a singular value decomposition 关于线性变换部分的一些知识可以猛戳这里  奇异值分解(SVD

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

机器学习--降维(主成分分析PCA.线性判别分析LDA.奇异值分解SVD.局部线性嵌入LLE) 以下资料并非本人原创,因为觉得石头写的好,所以才转发备忘 (主成分分析(PCA)原理总结)[https://mp.weixin.qq.com/s/XuXK4inb9Yi-4ELCe_i0EA] 来源:?石头?机器学习算法那些事?3月1日 主成分分析(Principal components analysis,以下简称PCA)是最常用的降维方法之一,在数据压缩和消除冗余方面具有广泛的应用,本文由浅入深的

自适应滤波:奇异值分解SVD

作者:桂. 时间:2017-04-03  19:41:26 链接:http://www.cnblogs.com/xingshansi/p/6661230.html 声明:欢迎被转载,不过记得注明出处哦~ [读书笔记10] 前言 广义逆矩阵可以借助SVD进行求解,这在上一篇文章已经分析.本文主要对SVD进行梳理,主要包括: 1)特征向量意义: 2)特征值分解与SVD: 3)PCA与SVD: 内容为自己的学习记录,其中多有借鉴他人之处,最后一并给出链接. 一.特征向量 第一反应是:啥是特征向量?为什