知识点:

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. 通过PEB的Ldr枚举进程内所有已加载的模块

    一.几个重要的数据结构,可以通过windbg的dt命令查看其详细信息 _PEB._PEB_LDR_DATA._LDR_DATA_TABLE_ENTRY 二.技术原理 1.通过fs:[30h]获取当前进 ...

  2. Spring第一课:核心API(三)

    以上是Spring的核心部分,其中需要了解的是:BeanFactory.ApplicationContext[FileSystemXmlApplicationContext.ClassPathXmlA ...

  3. rabbitMq消费死循环

    消费过程发生错误容易造成死循环 1.控制重发次数 2.try+catch+手动ack 3.try+catch+手动ack+死信队列(重试次数就失效了,因为捕捉确认后被打入了相应的死信队列) void ...

  4. leaflet加载离线OSM(OpenStreetMap)

    本文为博主原创,如需转载需要署名出处. leaflet作为广为应用的开源地图操作的API,是非常受欢迎,轻量级的代码让使用者更容易操作. 废话不多说,下面直接给出范例. 首先在这个网站下载leafle ...

  5. Java数八大据类型的拓展

    public class 数据类型拓展问题 { public static void main(String[] args) { //================================= ...

  6. HTB Hack The Box -- Oopsiec

    信息收集 开放了22ssh,80端口,其中ssh有弱口令爆破端口 先打开网页,然后进行目录爆破,在这期间先看一下网页的大概信息 没爆到什么有用的东西,但是有uploads文件夹说明是不是说明有文件上传 ...

  7. Selenium系列(十九) - Web UI 自动化基础实战(6)

    如果你还想从头学起Selenium,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1680176.html 其次,如果你不懂前端基础知识, ...

  8. SNMP协议之序言

    最近两周公司分配一个任务:使用snmp协议做一个网管,来配置我们的产品.这可以说是我第一次听说这个协议,我问了一下周围的同事这是个什么协议,同事说"简单网络管理协议",其实这个协议 ...

  9. 异步处理方式之信号(一):基础知识和signal函数说明

    文章目录 1. 引言 2. 信号的概念 2.1 信号操作之忽略信号 2.2 信号操作之捕捉信号 2.3 信号操作之执行系统默认操作 2.4 常见的信号 3. 函数signal 3.1 signal函数 ...

  10. Coreos配置docker镜像加速器

    CoreOS配置docker镜像加速器 CoreOS下的Docker配置是通过flannel unit来实现的. 1) 通过命令 systemctl cat docker 可以看出配置文件的默认位置 ...