机器学习之基于协同过滤的推荐引擎

一、推荐方法的介绍

   目前,主要的推荐方法包括:基于内容推荐、协同过滤推荐、基于关联规则推荐、基于效用推荐、基于知识推荐和组合推荐。今天我们仅仅了解一下协同过滤推荐,如果想了解其他推荐内容,我会在最后参考文章中给出链接。
首先,我们先看一个例子:

机器学习之基于协同过滤的推荐引擎_第1张图片


    协同过滤推荐算法主要分为基于用户(user-based)的协同过滤推荐算法和基于项目(item-based)的协同过滤推荐算法。
其中基于用户的协同过滤推荐是根据邻居用户的偏好信息产生对目标用户的推荐。通过相似性度量方法计算出相似用户,并将相似用户的评分结果作为推荐预测结果返回给用户。由图可以看出Mary对这几部的电影的评价和Tom对这几部的电影评价很相近,所以我们就认为Mary是Tom的相似用户,那么在预测Tom对《枪王之王》时会利用Mary对这部电影的评价结果。

    同样,基于项目的协同过滤推荐是根据相似项目的评价信息来预测目标项目的评价分数。由图可以知道所有用户对《唐山大地震》和《阿凡达》的评价分数很相近,那么就认为《唐山大地震》和《阿凡达》是相似项目。那么在预测Lucy对《阿凡达》的评价时会利用此项目的相似项目评价结果来进行预测。


二、用Python进行实现(此代码来自机器学习实战,王斌译这本书)


1、首先,我们输入原始数据。其中行代表用户,列代表项目(即电影),里面的值代表用户对电影的评价,0代表该用户没有对该电影进行评价。

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

2、选择相似度方法。这里给出了三种相似度计算方法。我们都把相似度归一化到了0到1之间,欧式距离方法用相似度等于1/(1+距离),皮尔逊相关系数原来的取值范围为-1到1之间,余弦相似度的取值范围原来也是在-1到1之间。

def ecludSim(inA,inB): #欧氏距离计算相似度
    return 1.0/(1.0 + la.norm(inA - inB))

def pearsSim(inA,inB): #皮尔逊相关系数(Pearson correlation)计算相似度
    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)

3、计算项目相似度并推荐。
   主要思路:
*寻找用户没有评价的电影,即数据集中0值得位置。
*计算预测项目和其他项目之间的相似度并对该项目进行评价。
*将这些项目的评分进行从高到低排序。

'''
功能:估计预测
输入变量:
dataMat:原始数据集
user:用户编号
simMeas:相似度计算方法
item:项目编号
输出变量:预测的评价分
'''
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 #如果某个物品评价为0,意味着用户没有对该物品评价,跳过
        overLap = nonzero(logical_and(dataMat[:,item].A>0,dataMat[:,j].A>0))[0] #(1)
        print 'item,j =',item,j
        print 'overLap=',overLap
        if len(overLap) == 0: similarity = 0 # 如果两者没有任何重合元素,则相似度为0
        else: similarity = simMeas(dataMat[overLap,item],dataMat[overLap,j]) #计算这两个项目的相似度
        print 'the %d and %d similarity is: %f' % (item, j, similarity)
        simTotal += similarity #这两句代码的作用是使评价分值在0到5之间
        ratSimTotal += similarity * userRating
    if simTotal == 0: return 0
    else: return ratSimTotal/simTotal

'''
功能:推荐(预测)未评价的目标项目
输入变量:
dataMat:原始数据集
user:用户编号
N:返回前3个推荐(预测)结果
simMeas:选择余弦相似度公式
estMethod:估计预测
'''
def recommend(dataMat, user, N=3, simMeas=cosSim, estMethod=standEst):
    unratedItems = nonzero(dataMat[user,:].A==0)[1]#find unrated items 找到未评价的项目元素
    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] #并对预测得分进行排序
运行结果:
>>> 
[(2, 2.6645016297307467)]

分析:即预测第2个用户对第2个电影评价为2.66分


参考文章:1、http://blog.sina.com.cn/s/blog_73de143c010153vp.html

  2、http://my.oschina.net/BreathL/blog/62519

推荐方法总结:http://blog.sina.com.cn/s/blog_73de143c01014uy6.html


你可能感兴趣的:(机器学习,协同过滤)