协作性过滤

基于用户的协作性过滤

  简单理解从众多用户中先搜索出与目标用户‘品味’相似的部分人,然后考察这部分人的偏爱,根据偏爱结果为用户做推荐。这个过程也成为基于用户的协作性过滤(user_based collaborative filtering)。

以推荐电影为例

数据集

  偏好数据集,嵌套字典,格式为:{用户:{电影名称:评分}}。

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}}

寻找相近用户

  从众多用户中先搜索出与目标用户‘品味’相似的人。相似度的计算用欧几里得距离和皮尔逊相关度来计算。

  皮尔逊相关度公式:

from math import sqrt

#欧几里得距离
#将得到的距离1/(1+distance),保持sim_distance值在(0,1),且sim_distance越大,两者越近
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 + sum_of_squares) #皮尔逊系数
#对不整齐/规范数据更有效,如本例具有相同品味但某一人评价更严格,在欧几里得距离看来是不相近的,但pearsion会找到最佳拟合线(best_fit line)所以更准确
def sim_pearson(prefs, person1, person2):
si = {}
for item in prefs[person1]:
if item in prefs[person2] :
si[item] = 1 # 两者有相似的个数
n = len(si) if n==0 :
return 1 sum1=sum([prefs[person1][it] for it in si])
sum2=sum([prefs[person2][it] for it in si]) sum1Sq=sum([pow(prefs[person1][it],2) for it in si])
sum2Sq=sum([pow(prefs[person2][it],2) for it in si]) pSum=sum([prefs[person1][it]*prefs[person2][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

测试:

确定计算相关度方法后,找相关度最高用户:

#为评论者打分
#找到相关度最高的用户,similarity指定相关度方法,n指定返回最相似用户人数
def topMatches(prefs, person, n = 5, similarity = sim_distance):
scores = [(similarity(prefs, person, other), other)
for other in prefs if other != person]
scores.sort()
scores.reverse()
return scores[0:n]

测试:

推荐物品

  经过搜索到‘品味’相同的人后,可以选择从最相似用户看过的电影随机选一部,这是可行的,但可能刚好有一部你想看的但最相似的用户没看过。由此需要对推荐物品做处理:1.对所有相似用户做加权,突出更相似用户比重;2.抑制被评论更多的影片对结果的影响。下表可反应该过程:

#推荐
def getRecommendations(prefs, person, similarity = sim_distance):
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
#print(totals[item]) simSums.setdefault(item,0)
simSums[item]+=sim for item, total in totals.items():
pass #对自己可能想看的电影评分
rankings=[(total/simSums[item],item) for item, total in totals.items()] rankings.sort()
rankings.reverse()
return rankings

测试:

至此,一个简易的基于用户的推荐系统完成。但实际中更多可能存在基于物品推荐的情况,以该列说明,给定一个电影推荐相似电影。通过查看那些用户喜欢该电影,再搜索这些用户还喜欢其他电影的程度/评价来做相似度匹配,在该例中通过改变数据集即可实现。

#转换数据集
def transformPrefs(prefs):
result={}
for person in prefs:
for item in prefs[person]:
result.setdefault(item,{}) result[item][person] = prefs[person][item]
return result

转换结果如下:{电影名:{用户:评分}}

测试:

基于物品的协作型过滤

  基于用户的过滤方法在数据量小时较为有效,但当数据量变大时,每次为用户推荐都逐个用户比较显然不合理,基于物品的过滤(item_based collaborative filtering)预先计算好相近物品,当对用户进行推荐时,只要查看预先构造好的列表即可。而且该计算无需不停计算,只要及时的在网络流量不大情况下进行即可。

构造相似物品数据集

 构造包含相近物品的完整数据集。构造完成后在需要推荐时使用。

#构造包含相近物品的完整数据集
def calculateSimilarItems(prefs,n=10):
result = {}
#数据集以物品为中心 {物品:{用户:评分}}
itemprefs = transformPrefs(prefs)
c = 0
for item in itemprefs:
c+=1
if c%100==0: print('%d / %d' %(c,len(itemprefs))) #构造最相似物品集合
scores=topMatches(itemprefs,item, n=n,similarity=sim_distance)
result[item]=scores
return result

测试:

获得推荐

   经过以上,已经事先得到各电影之间的相似度,在推荐时使用。对各相似电影相似度加权,具体如下:

#推荐
def getRecommendedItems(prefs,itemMatch,user):
userRatings = prefs[user]
scores={}
totalSim={} for (item,rating) in userRatings.items(): #print ('item= %s rating= %s' % (item,rating))
for (similarity,item2) in itemMatch[item]:
#print('similarity=%s item2=%s'%(similarity,item2))
#如果已经评价过则忽略
if item2 in userRatings: continue scores.setdefault(item2,0)
scores[item2]+=similarity*rating totalSim.setdefault(item2,0)
totalSim[item2]+=similarity rankings = [(score/totalSim[item],item) for item,score in scores.items()]
rankings.sort()
rankings.reverse()
return rankings

测试:

  

----------------------------------------------------------

本系列为较早学习《集体智慧编程》的笔记,多注释在代码出,现重写在Blog,多有理解不当之处,望指教。

PCI_Making Recommendations的更多相关文章

  1. 【转载】Recommendations with Thompson Sampling (Part II)

    [原文链接:http://engineering.richrelevance.com/recommendations-thompson-sampling/.] [本文链接:http://www.cnb ...

  2. <Programming Collective Intelligence> Chapter2:Making Recommendations

    <Programming Collective Intelligence> Chapter2:Making Recommendations 欧几里得距离评价 皮尔逊相关度评价 它相比于欧几 ...

  3. C# - Recommendations for Abstract Classes vs. Interfaces

     The choice of whether to design your functionality as an interface or an abstract class can somet ...

  4. xDB and sitecore 8 hardware Recommendations

    xDB and sitecore 8 hardware Recommendations as below: xDB hardware guidelines https://doc.sitecore.n ...

  5. XML Publisher Report Issues, Recommendations and Errors

    In this Document   Purpose   Questions and Answers   References APPLIES TO: Oracle Process Manufactu ...

  6. Netflix Recommendations

    by Xavier Amatriain and Justin Basilico (Personalization Science and Engineering) In part one of thi ...

  7. Best Practices and Recommendations for RAC databases with SGA size over 100GB (文档 ID 1619155.1)

    Best Practices and Recommendations for RAC databases with SGA size over 100GB (文档 ID 1619155.1) APPL ...

  8. 1950261 - SAP HANA Database Backup Policy Recommendations and Regular Backup Script

    =====Symptom For SAP Business One, version for SAP HANA users, SAP HANA provides a range of database ...

  9. 【RS】Amazon.com recommendations: item-to-item collaborative filtering - 亚马逊推荐:基于物品的协同过滤

    [论文标题]Amazon.com recommendations: item-to-item collaborative filtering (2003,Published by the IEEE C ...

随机推荐

  1. 2017·iOS学习资料

    我的两个想法更新了,欢迎新老司机出来槽点一下 star →[iOS·UIKit & Foundation框架-Annotations & Category注解工具类

  2. iOS11和机器学习CoreML库

    随着iOS11的发布,苹果公司也正式加入了机器学习的战场.在新的iOS11中内置了CoreML,虽然还是Beta版本,但是功能已经非常强大了. 在这个CoreML库里面,已经集成了一些训练好的模型,可 ...

  3. 一位菜鸟的java 最基础笔记

    java的特性 简单性(Simple). 结构体系中立(Architecture Neutral). 面向对象(Object Oriented). 易于移植(Portable). 分布式(Distri ...

  4. Vulkan Tutorial 12 Fixed functions

    操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 早起的图形API在图形渲染管线的许多阶段提供了默认的状态.在Vulkan中,从vie ...

  5. 2017年Web前端开发工程师薪资越来越高?

    放眼全球,不仅在国内的互联网行业,在国外,前端工程师一样是需求旺盛.供不应求的香饽饽.所以在供不应求的前端招聘市场上,优秀的前端工程师才是有话语权的那一方. 前端开发是做什么的? 前端是互联网时代软件 ...

  6. Spring学习(8)--- @Autowired注解(一)

    可以将@Autowired注解为“传统”的setter方法 package com.mypackage; import org.springframework.beans.factory.annota ...

  7. 利用canvas压缩图片

    现在手机拍的照片动不动就是几M,当用户上传手机里的照片时一个消耗流量大,一个上传时间长,为了解决这个问题,就需要压缩图片: 想法:利用canvas重绘图片,保持宽高比不变,具体宽高根本具体情况而定. ...

  8. angular.js的ng-app 指令定义一个 AngularJS 应用程序。

    <!DOCTYPE html> <html lang="en" ng-app> <head> <meta charset="UT ...

  9. Java(14)继承

    1.继承(extends) 1.1 继承:遗传 1.2 语法 public class 子类 extends 父类{ } public class Dog extends Pet{ } public ...

  10. MVC 树节点Table格式授权

    这几夜心里颇不平静, 奈何 JS水平有限,前台效果耗时四天,后台传值一天,直至昨夜丑时测试初步完成,其实就是一个给tree来授权,网上开源的插件很多,如treejs.easyui 等等,只是这里授权稍 ...