知识点:

1. 协作型过滤——Collaboraive Filtering

  通常的做法是对一群人进行搜索,并从中找出与我们品味相近的一小群人,算法会对这些人的偏好进行考察,并将它们组合起来构造出一个经过排名的推荐列表

2.搜索偏好——Collecting Preferences

3.寻找相近的用户——Finding Similar Users

  3.1 通过相似度评价值来寻找相近的用户

  3.2 相似度评价值体系:欧几里得距离(Euclidean Distance ),皮尔逊相关度(Pearson Collelation)曼哈顿距离和Jaccard系数等

代码实现:

  1 # !/usr/bin/local/python3
2 # -*- coding utf-8 -*-
3 from math import sqrt
4
5 # prepare data
6 critics = {'Lisa Rose':{'Lady in the Water': 2.5, 'Snakes on a Plane': 3.5,
7 'Just My Luck': 3.0, 'Superman Returns': 3.5, 'You,Me and Dupree': 2.5,
8 'The Night Listener': 3.0},
9 'Gene Seymour': {'Lady in the Water': 3.0, 'Snakes on a Plane': 3.5, 'Just My Luck': 1.5,
10 'Superman Returns': 5.0, 'The Night Listener': 3.0, 'You,Me and Dupree': 3.5},
11 'Michale Phillips': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.0, 'Superman Returns': 3.5,
12 'The Night Listener': 4.0},
13 'Claudia Puig': {'Snakes on a Plane': 3.5, 'Just My Luck': 3.0, 'The Night Listener': 4.5,
14 'Superman Returns': 4.0,'You,Me and Dupree': 2.5},
15 'Mick LaSalle': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0, 'Just My Luck': 2.0,
16 'Superman Returns': 3.0, 'The Night Listener': 3.0,'You,Me and Dupree': 2.0},
17 'Jack Mattews': {'Lady in the Water': 3.0, 'Snakes on a Plane': 5.0, 'The Night Listener': '3.0',
18 'Superman Returns': 5.0, 'You,Me and Dupree': 3.5},
19 'Toby': {'Snakes on a Plane': 4.5, 'You,Me and Dupree': 1.0, 'Superman Returns': 4.0}}
20
21
22 # 测试数据
23 #data =critics['Lisa Rose']['Lady in the Water']
24 #print(data)
25
26 # 返回一个有关P1和P2的基于欧几里得距离的相似度评价
27 def sim_distance(prefs, p1, p2):
28 # 得到共同评价的电影列表
29 si = {}
30 for item in prefs[p1]:
31 if item in prefs[p2]:
32 si[item] = 1
33 # 如果两人没有共同之处,则返回0
34 if len(si) ==0: return 0
35 # 计算所有差值的的平方和
36 sum_of_squares = sum([pow(prefs[p1][item]-prefs[p2][item], 2) for item in prefs[p1]
37 if item in prefs[p2]])
38    # 表示偏好越相近,返回的值越大,(避免被零整除的错误,当返回为1表示两人具有一样的偏好)
39 return 1/(1+sqrt(sum_of_squares))
40
41
42 # 返回p1和p2的皮尔逊相关系数
43 def sim_pearson(prefs, p1, p2):
44 si={}
45 for item in prefs[p1]:
46 if item in prefs[p2]:
47 si[item] = 1
48
49 n = len(si)
50
51 if n == 0: return 1
52 # 求所有偏好之和
53 sum1 = sum([prefs[p1][it] for it in si])
54 sum2 = sum([prefs[p2][it] for it in si])
55
56 # 求偏好平方和
57 sum1Sq = sum([pow(prefs[p1][it], 2) for it in si])
58 sum2Sq = sum([pow(prefs[p2][it], 2) for it in si])
59
60 # 求两人偏好乘积之和
61 pSum = sum([prefs[p1][it] * prefs[p2][it] for it in si])
62
63 # 计算皮尔逊评价值
64 num = pSum - (sum1*sum2/n)
65 den = sqrt((sum1Sq-pow(sum1, 2)/n)*(sum2Sq-pow(sum2, 2)/n))
66 if den == 0: return 0
67    # 返回值介于-1和1之间,值为1则表示两个人对每一样物品均有着完全一致的评价
68 r = num/den
69 return r
70
71
72 # 从反映偏好的字典中返回最为匹配者
73 #  返回结果的个数和相似度函数均为可选参数
74 def topMatches(prefs, person, n=5, similarity=sim_pearson):
75 scores = [(similarity(prefs, person, other), other) for other in prefs if other != person]
76
77 # 对表进行排序,评价值最高的排在最前面
78 scores.sort()
79 scores.reverse()
80 return scores[0:n]
81
82
83 # 利用所有他人评价值的加权平均,为某人提供建议
84 def getRecommendations(prefs, person, similarity=sim_pearson):
85 totals = {}
86 simSum = {}
87 for other in prefs:
88 # 不和自己作比较
89 if other == person: continue
90 # 获取两人之间的相似度
91 sim = similarity(prefs, person, other)
92
93 # 忽略评价值小于零或者为零的情况
94 if sim <= 0: continue
95 for item in prefs[other]:
96 # 只对自己未看过的电影进行评价
97 if item not in prefs[person] or prefs[person][item] == 0:
98 # 相似度*评价值
99 totals.setdefault(item, 0)
100 totals[item] += sim * float(prefs[other][item])
101 # 相似度之和(多人评价对于特定电影的相似度之和)
102 simSum.setdefault(item, 0)
103 simSum[item] += sim
104
105 # 建立一个归一化的列表
106 rankings = [(total/simSum[item], item) for item, total in totals.items()]
107 print(simSum)
108 # 返回经过排序的列表
109 rankings.sort()
110 rankings.reverse()
111 return rankings
112
113
114 # 将人名和物品进行对调
115 def transforPrefs(prefs):
116 result = {}
117 for person in prefs:
118 for item in prefs[person]:
119 result.setdefault(item,{})
120 result[item][person] = prefs[person][item]
121 return result

总结:

1.相似性度量方法的选择问题:

  1.1  当采用Pearson方法进行评价时,它修正了‘夸大分值’的情况

  1.2 当采用Euclidean Distance方法进行评价时,适用于存在一定共性的数据之间

2.基于用户过滤和基于物品过滤的选择:
  2.1 基于用户过滤方法更容易实现,而且无需额外步骤,更适用于规模较小的变化非常频繁的内存数据集

  2.2 基于物品过滤明显比基于用户的过滤更快,不过在维护物品相似度表有额外的开销,更适用于稀疏数据集

《集体智慧编程学习笔记》——Chapter2:提供推荐的更多相关文章

  1. 并发编程学习笔记(4)----jdk5中提供的原子类及Lock使用及原理

    (1)jdk中原子类的使用: jdk5中提供了很多原子类,它会使变量的操作变成原子性的. 原子性:原子性指的是一个操作是不可中断的,即使是在多个线程一起操作的情况下,一个操作一旦开始,就不会被其他线程 ...

  2. 转 网络编程学习笔记一:Socket编程

    题外话 前几天和朋友聊天,朋友问我怎么最近不写博客了,一个是因为最近在忙着公司使用的一些控件的开发,浏览器兼容性搞死人:但主要是因为这段时间一直在看html5的东西,看到web socket时觉得很有 ...

  3. 多线程编程学习笔记——async和await(一)

    接上文 多线程编程学习笔记——任务并行库(一) 接上文 多线程编程学习笔记——任务并行库(二) 接上文 多线程编程学习笔记——任务并行库(三) 接上文 多线程编程学习笔记——任务并行库(四) 通过前面 ...

  4. Python 集体智慧编程PDF

    集体智慧编程PDF 1.图书思维导图http://www.pythoner.com/183.html p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12. ...

  5. 多线程编程学习笔记——使用异步IO(一)

    接上文 多线程编程学习笔记——使用并发集合(一) 接上文 多线程编程学习笔记——使用并发集合(二) 接上文 多线程编程学习笔记——使用并发集合(三) 假设以下场景,如果在客户端运行程序,最的事情之一是 ...

  6. 多线程编程学习笔记——使用异步IO

    接上文 多线程编程学习笔记——使用并发集合(一) 接上文 多线程编程学习笔记——使用并发集合(二) 接上文 多线程编程学习笔记——使用并发集合(三) 假设以下场景,如果在客户端运行程序,最的事情之一是 ...

  7. Java并发编程学习笔记

    Java编程思想,并发编程学习笔记. 一.基本的线程机制 1.定义任务:Runnable接口 线程可以驱动任务,因此需要一种描述任务的方式,这可以由Runnable接口来提供.要想定义任务,只需实现R ...

  8. 并发编程学习笔记(15)----Executor框架的使用

    Executor执行已提交的 Runnable 任务的对象.此接口提供一种将任务提交与每个任务将如何运行的机制(包括线程使用的细节.调度等)分离开来的方法.通常使用 Executor 而不是显式地创建 ...

  9. 并发编程学习笔记(13)----ConcurrentLinkedQueue(非阻塞队列)和BlockingQueue(阻塞队列)原理

    · 在并发编程中,我们有时候会需要使用到线程安全的队列,而在Java中如果我们需要实现队列可以有两种方式,一种是阻塞式队列.另一种是非阻塞式的队列,阻塞式队列采用锁来实现,而非阻塞式队列则是采用cas ...

随机推荐

  1. Quartz任务调度(1)概念例析快速

    实例解析概念 在quartz中,有几个核心类和接口:Job.JobDetail.Trigger.Calendar.Scheduler.下面我们结合实例来分析这些类的角色定位.现在我们有一个新闻网站,它 ...

  2. (二)MQTT客户端模拟连接阿里云并上传数据

    本文主要讲述使用MQTT.fx接入物联网平台 一.下载MQTT.fx客户端 官网链接 二.设置相关参数 打开MQTT单片机编程工具,将三元组复制进去,生成所需要的信息 单片机工具下载地址 三元组还记得 ...

  3. 交互式查询⼯具Impala

    Impala是什么: Impala是Cloudera提供的⼀款开源的针对HDFS和HBASE中的PB级别数据进⾏交互式实时查询(Impala 速度快),Impala是参照⾕歌的新三篇论⽂当中的Drem ...

  4. Linkerd 2.10(Step by Step)—控制平面调试端点

    Linkerd 2.10 系列 快速上手 Linkerd v2 Service Mesh(服务网格) 腾讯云 K8S 集群实战 Service Mesh-Linkerd2 & Traefik2 ...

  5. redis百万级数据存取

    Jedis jedis0 = new Jedis("localhost", 6379); jedis0.auth("123456"); Pipeline pip ...

  6. js函数和封装

    $就是jquery对象,$()就是jQuery(),在里面可以传参数,作用就是获取元素 js对象与jQuery对象的区别:jQuery对象是一个数组,jQuery对象转为js对象:[0] 取第一个即可 ...

  7. SpringBoot应用中使用AOP记录接口访问日志

    SpringBoot应用中使用AOP记录接口访问日志 本文主要讲述AOP在mall项目中的应用,通过在controller层建一个切面来实现接口访问的统一日志记录. AOP AOP为Aspect Or ...

  8. BUUCTF-[CISCN2019 总决赛 Day2 Web1]Easyweb

    BUUCTF-[CISCN2019 总决赛 Day2 Web1]Easyweb 就给了一个这个... 先打上robots.txt看看 发现有源码备份,但不是index.php.bak... 看源码发现 ...

  9. golang redis

    安装 下载第三方包: go get -u github.com/go-redis/redis/v9 连接 // 定义一个rdis客户端 var redisdb *redis.Client // 初始化 ...

  10. Docker容器管理——Docker容器常用命令

    1.查看所有的容器 docker ps 2.查看运行的容器 docker ps -a 3.启动.停止.重启docker容器 docker start ... docker stop ... docke ...