机器学习经典算法12-SVD及其在推荐中的应用

1.基本介绍

         就个人看来,其实SVD(singular valur decomposition)和PCA的功能是一样的,可以用来降低维度、去除噪声,经过PCA和SVD处理后的数据可以做各种处理,包括之前的各个分类和回归的经典算法等,可以说SVD和PCA是高级别的预处理(相对于均值归一化、属性范围调整等)。

2.SVD简要说明

机器学习经典算法12-SVD及其在推荐中的应用_第1张图片
                     一般地,获得sigma矩阵中,绝大多数对角元素为0;一般选择部分来简化数据,即sigma的维度变为m*k,U的维度变为m*k。

3.基于协同过滤的推荐

        这里我们假设有m个用户,n个物品,原始的数据矩阵Data为m*n维度,矩阵中的元素是用户对物品的评分,如果用户没有对该物品进行评分,则评分为0。协同过滤较为经典的两个是基于物品相似度的和基于用户相似度的,在基于物品相似度计算时,物品的特征维度是用户,数据是评分;在基于用户相似度时,用户的特征维度是物品,数据是评分。可以看到用户和物品互相为特征,但是其中有很多杂质掺杂其中,用SVD可以很好的进行过滤,从而提升推荐结果。
       具体做法是(基于物品相似度):对于某个用户u推荐某个物品v时,计算该物品v与u已经评分过的物品相似度,在计算的时候,其特征是通过上面矩阵分解后的V公式重构的,可以看成将物品的特征维度将为了k,物品特征矩阵为n*k,而不是之前的n*m。

4.进一步的改进LFM 

     在进行SVD运算时,随着物品和项目的增多,计算复杂度会非常高。这时出现了LFM即latent factor model,这里的假设和SVD十分相似,即评分矩阵Data是由两个矩阵乘积所得,一个是用户特征矩阵,其维度为m*k,另外一个是物品特征矩阵,其维度为n*k,那么用户特征矩阵*物品特征矩阵的转置,即得到了评分矩阵。需要对m*k+n*k个参数进行求解,而求解的目标就是让得到的评分和实际评分平方差之和最小。这个具体可以参照《推荐系统实战》,里面有相关的代码和说明。

5.SVD用于推荐的示例

         三种不同计算相似度的方法:ecludSim/pearsSim/cosSim;standEst是基于原始数据计算非评分物品和评分物品之间的相似度;而svdEst在计算之前,对数据进行了重构(这里默认重构为n*4的矩阵);主函数recommend中可以指定相似度计算和评分预测方法,还有物品推荐个数N(默认为3)。
from numpy import *
import matplotlib.pyplot as plt
from numpy import linalg as la
def ecludSim(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*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)
def standEst(dataMat, user, simMeas, item):
    n=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]
        if len(overLap)==0:
            simliarity=0
        else:
            similarity=simMeas(dataMat[overLap,item],dataMat[overLap,j])
        simTotal+=similarity
        ratSimTotal+=similarity*userRating
    if simTotal==0:return 0
    return ratSimTotal/simTotal
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
    for j in range(n):
        userRating=dataMat[user,j]
        if userRating==0 or j==item:continue
        similarity=simMeas(xformedItems[item,:].T,xformedItems[j,:].T)
        simTotal+=similarity
        ratSimTotal+=similarity*userRating
    if simTotal==0:return 0
    return ratSimTotal/simTotal
def recommend(dataMat, user, N=3, simMeas=cosSim, estMethod=standEst):
    unratedItems=nonzero(dataMat[user,:].A==0)[1]
    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=lambda jj:jj[1], reverse=True)[:N]
myData=[[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]]
myMat=mat(myData)
print "standESt"
print recommend(myMat,2)
print "svdEst"
print recommend(myMat,2,3,cosSim,svdEst)


你可能感兴趣的:(机器学习经典算法12-SVD及其在推荐中的应用)