基于协同过滤构建简单推荐系统

本文只是对协同过滤的一个简单的知识总结,对该方面知识的学习,可参考《推荐系统实践》、《集体智慧编程》。这里并不给出原因,而只是一个该方面知识点的简单应用。通过这些简单的应用再反过来学习相关的知识点,应该能提升很大的兴趣。


先谈什么是机器学习:

机器学习:将一组数据传递给算法,并由算法推断出与这些数据的属性相关的信息——借助这些信息,算法就能够预测出未来有可能会出现的其他数据。
因为几乎所有的非随机数据中,都会包含这样或那样的“模式”,这些模式的存在使得机器得以据此进行归纳。为了实现归纳,机器会利用它所认定的出现于数据中的重要特征对数据进行“训练”,并借此得到一个模型。


什么是推荐系统:

如在线购物中的商品推荐、热门网站的推荐、以及帮助人们寻找音乐盒影片的应用。


什么是协同过滤Collaborative Filtering

对一大群人进行搜索,并从中找出与我们品位相近的一群人。算法会对这些人所偏爱的内容进行考察,并将它们组合起来构造出一个经过排名的推荐列表。


基于协同过滤算法构建一个推荐系统的过程:(Python实现)

1.收集偏好——可以使用一个嵌套的字典
2.寻找相近的用户
欧几里得距离
皮尔逊相关度
3.为评论者打分,并找到最接近的匹配结果
4.推荐物品


数据集:

一个可以用来做练习的数据集如下:

http://grouplens.org/datasets/movielens/


实例:

1.有如下数据集:描述的是一些用户对一些电影的评价

#list of movies
critics={'Lisa Rose': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.5,
 'Just My Luck': 3.0, 'Superman Returns': 3.5, 'You, Me and Dupree': 2.5, 
 'The Night Listener': 3.0},
'Gene Seymour': {'Lady in the Water': 3.0, 'Snakes on a Plane': 3.5, 
 'Just My Luck': 1.5, 'Superman Returns': 5.0, 'The Night Listener': 3.0, 
 'You, Me and Dupree': 3.5}, 
'Michael Phillips': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.0,
 'Superman Returns': 3.5, 'The Night Listener': 4.0},
'Claudia Puig': {'Snakes on a Plane': 3.5, 'Just My Luck': 3.0,
 'The Night Listener': 4.5, 'Superman Returns': 4.0, 
 'You, Me and Dupree': 2.5},
'Mick LaSalle': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0, 
 'Just My Luck': 2.0, 'Superman Returns': 3.0, 'The Night Listener': 3.0,
 'You, Me and Dupree': 2.0}, 
'Jack Matthews': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0,
 'The Night Listener': 3.0, 'Superman Returns': 5.0, 'You, Me and Dupree': 3.5},
'Toby': {'Snakes on a Plane':4.5,'You, Me and Dupree':1.0,'Superman Returns':4.0}}

2.寻找相近的用户

这里需要计算的是不同人之间品位的相似程度。常用算法有欧几里德距离和皮尔逊相关度。(详细内容参考相关书籍)

计算方法这里不详述。

算法1:欧几里德距离

from math import sqrt

def sim_distance(prefs,person1,person2):
    si = {}
    for item in prefs[person1]:
        if item in prefs[person2]: si[item]=1
                         
    if len(si)==0:
            return 0

    sum_of_squares=sum([pow(prefs[person1][item]-prefs[person2][item],2)
                        for item in prefs[person1] if item in prefs[person2]])

    return 1/(1+sqrt(sum_of_squares))
这里对其加1并取倒数的原因是:避免遇到零整除的错误。

这样总能得到一个介于0到1之间的小数,数越大,表示偏好越相近


算法2:皮尔逊相关度:

皮尔逊相关系数用来判断两组数据与某一直线的拟合程度。

通过这种算法,首先会找出两位评论者都评价过的物品,然后计算两者的评分总和与平方和,并求得评分的乘积和。从而计算出皮尔逊相关系数。

def sim_pearson(prefs,p1,p2):
    si = {}
    for item in prefs[p1]:
        if item in prefs[p2]: si[item]=1

    n=len(si)
    if n==0: return 1

    sum1=sum([prefs[p1][it] for it in si])
    sum2=sum([prefs[p2][it] for it in si])

    sum1Sq=sum([pow(prefs[p1][it],2) for it in si])
    sum2Sq=sum([pow(prefs[p2][it],2) for it in si])

    pSum=sum([prefs[p1][it]*prefs[p2][it] for it in si])

    num=pSum-(sum1*sum2/n)
    den=sqrt((sum1Sq-pow(sum1,2)/n)*(sum2Sq-pow(sum2,2)/n))
    if den==0: return 0

    r=num/den

    return r

该函数返回一个介于-1到1之间的数值,越大越相似。


3.为评论者打分,得到相近的匹配结果

def topMatches(prefs,person,n=5,similarity=sim_pearson):
    scores=[(similarity(prefs,person,other),other)
            for other in prefs if other!=person]

    scores.sort()
    scores.reverse()
    return scores[0:n]
上面对列表进行方向排序,使得相似度最高的排在前面。


4.推荐物品:
思想是:通过一个加权评价值(考虑到一些影片不同的质量,如收到越多的人评价的电影权重应该更高点)来为影片打分。

def getRecommendations(prefs,person,similarity=sim_pearson):
    totals={}
    simSums={}
    for other in prefs:
        if other == person: continue
        sim=similarity(prefs,person,other)

        if sim<=0: continue
        for item in prefs[other]:

            if item not in prefs[person] or prefs[person][item]==0:
                totals.setdefault(item,0)
                totals[item]+=prefs[other][item]*sim

                simSums.setdefault(item,0)
                simSums[item]+=sim

    rankings=[(total/simSums[item],item) for item,total in totals.items()]

    rankings.sort()
    rankings.reverse()
    return rankings


通过上面这些步骤,可以构建出一个基本的推荐系统。我们所要做的只是:构建涉及人员、物品和评价值的字典,然后借此来为用户提供建议。


注:关于上面引用的代码的具体解释,可以参考 《集体智慧编程》一书。
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值