《写给程序员的数据挖掘实践指南》学习笔记二

协同过滤——隐式评级及基于物品的过滤

第一篇讲的是显示评级,是用户确实打了的分,是过于理想的情况,现实中有很多不可控因素,有时用户打分口是心非,有时懒得打分,有时初次评价之后即使后来发现当初打分打低了,有时仅仅是与个人联系紧密的独家偏好……
隐式评级,不要求用户打分,而是观察用户的行为,可观察的维度很多:
上述讲的都是基于用户的过滤,也叫基于内存的过滤,意思是要进行大量的计算,尤其当用户很多的时候,对计算机内存要求比较高。现在亚马逊有上百万用户,计算扩展性是一个问题,更重要的是有时找不到最近邻。基于以上原因,最好采用基于物品的过滤。也叫基于模型的过滤。

1. 基于物品的过滤

利用物品之间的相似度进行推荐。从所有商品中找出与用户购买过的商品最相似的商品推荐给用户。

2. 计算物品之间的相似度,使用调整后的余弦相似度

和第一篇的余弦相似度类似,为了消除分数贬值,调整后的余弦相似度与余弦相似度公式有一点不同,用户U给物品i的打分减去用户U对所有物品打分的平均值。因为是基于物品的推荐,所以如果使用之前的余弦相似度,就要用物品的每一列属性中的每一项减去这一列的平均值,显然与实际情况不符。

调整后的余弦相似度计算公式

U 表示所有同时对i和j 进行过评级的用户的集合。
这个公式计算的是** 物品 i 和物品 j 之间的相似度 **。这个公式的直观解释是:

要计算 物品i 和 物品j 之间的相似度
 1. 找出同时对物品i和物品j打分的用户
 2. 计算每个用户对自己购买的书打分的平均值 R
 3. 按照公式计算
利用改进后的余弦相似度计算两个物品之间的相似度

Python 代码:

# -*- coding: utf-8 -*-
from math import sqrt
users3 = {"David": {"Imagine Dragons": 3, "Daft Punk": 5,
"Lorde": 4, "Fall Out Boy": 1},
"Matt": {"Imagine Dragons": 3, "Daft Punk": 4,
"Lorde": 4, "Fall Out Boy": 1},
"Ben": {"Kacey Musgraves": 4, "Imagine Dragons": 3,
"Lorde": 3, "Fall Out Boy": 1},
"Chris": {"Kacey Musgraves": 4, "Imagine Dragons": 4,
"Daft Punk": 4, "Lorde": 3, "Fall Out Boy": 1},
"Tori": {"Kacey Musgraves": 5, "Imagine Dragons": 4,
"Daft Punk": 5, "Fall Out Boy": 3}}

def computeSimilarity(band1, band2, userRatings):
    averages = {}
    for (key, ratings) in userRatings.items():
        averages[key] = (float(sum(ratings.values())) /len(ratings.values()))
    num = 0 # 分子
    dem1 = 0 # 分母的第一部分
    dem2 = 0
    for (user, ratings) in userRatings.items():
        if band1 in ratings and band2 in ratings:
            avg = averages[user]
            num += (ratings[band1] - avg) * (ratings[band2] - avg)
            dem1 += (ratings[band1] - avg) ** 2
            dem2 += (ratings[band2] - avg) ** 2
    return num / (sqrt(dem1) * sqrt(dem2))

print computeSimilarity('Kacey Musgraves', 'Lorde', users3)
print computeSimilarity('Imagine Dragons', 'Lorde', users3)
print computeSimilarity('Daft Punk', 'Lorde', users3)

得到的结果填入表中:

各物品之间的相似度矩阵

3. 利用相似度矩阵进行预测

公式如下图,p(u,i) 指的是用户u将对物品i的评分的预测值(即用户u对物品i的喜欢程度)。
N 是用户u的所有评级物品中每个和物品i得分相似的物品。存在在相似度矩阵中。R(u,N) 是u给N的评分。S(i,N)是i和N的相似度。

书中的图

4. 对用户的打分结果归一化

类似皮尔逊相关系数对结果做处理的原因,让用户对物品的评分结果值位于-1到1之间。
公式如下图所示,NR(u,N) 是归一化的结果,即用户u对物品N打分的结果的处理。MinR表示评级范围(比如1~5)中的最小值,MaxR表示最大值。


对打分结果归一化公式

计算举例,很简单,比如某人的对某本书的打分是2分,归一化后结果如下:


将第3点里面的预测用户打分的公式更新为:


最后用归一化的结果反推真实的分数公式:



就得到了预测的打分。

5. Slope One 算法

据说 Slope One 算法简洁,易实现,来自 Daniel Lemire 和 Anna Machlachlan 的论文 ↓

Slope One Predictors for Online Rating-Based Collaborative
Filtering” by Daniel Lemire and Anna Machlachlan (http://www.daniel-lemire.com/fr/abstracts/SDM2005.html).

1. 问题描述

假设 Amy 给 PSY 打了 3分,给 WH 打了 4 分,Ben 给 PSY 打了 4 分,想预测 Ben 给 WH 打多少分?
描述如图:


我们直观进行预测,依据只能是 Amy 对 WH 的打分,相对而言,Ben 对 WH 的打分可能是 5 分。
Slope One 算法将问题看成两部分:

第一部分: 计算所有物品对的偏差
第二部分: 利用偏差进行预测

2. 计算偏差

数据如下:

计算物品i 到 物品j 的平均偏差的公式:
其中,card(S) 是S集合中的元素个数,X 是整个评分集合。
card(S(X))即为所有同时对i和j评分的用户个数。

物品i到物品j的偏差的计算公式

举个例子:

物品 swift 到 psy 的偏差
物品 psy 到 swift 的偏差

3. 利用加权的 Slope One 算法进行预测

公式如下:
该公式最终得出的结果是用户对某物品的打分的预测值。其中,c(i,j) 表示所有同时对物品i和物品j打分的用户数。


加权的 Slope One 算法

用户u对所有除j(即要预测值的物品)外的打过分的物品

公式看似复杂,计算却不复杂,举个例子:
给出了Ben的评分表及物品之间的偏差表:

Ben的评分表及物品之间的偏差表
所有用户打分情况

计算过程

6. 加权 Slope One : 推荐模块

通过 Slope One 算法得出用户对某一商品的预测值,如何对用户推荐呢?
(整个的利用 Slope One 算法推荐商品的代码在这里)

  1. 先从一大堆商品中找出用户没有打过分的商品,并且用户评过分的商品与未评过分的商品之间的偏差存在。
  1. 用 Python 程序计算所有用户对未评过分的商品的可能评分。
  2. 根据预测分数由高到低展示出来(可只展示前几项),排名越靠前,推荐给用户的可能性越高。

作业:对 数据集 中的10部影片进行评级,看看 Slope One 推荐系统会给你推荐哪些影片。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容