3_基于用户的协同过滤方法

1 直观描述

用户A有几个“关系很好”的朋友 B、C、D,通常B或C或D买了什么东西的话,A也要跟着买。昨天,B新买了一个物品 g ,而用户A之前也从没见过物品 g ,那么,购物平台就将 g 推荐给A。

2 基于用户协同过滤的步骤

⑴ 计算用户间的相似度。

    \omega_{uv} =\frac{同时被用户u和用户v喜欢的物品数}{用户u喜欢的物品数乘以用户v喜欢的物品数,再对乘积开根号}

⑵ 预测某一用户对物品集中他尚未进行评分的物品的评分,并依据计算出来的评分高低来进行推荐。也可以先对所有物品进行评分预测,然后剔除掉已评分的物品,对剩下的物品进行排序。

3 用户相似度的计算

用两个for循环遍历user_dict中的用户,通过集合的交集运算,很容易得到同时被用户u和用户v喜欢的物品数,至于每个用户喜欢的物品数,通过len()函数很容易得到,于是就得到所有的\omega_{uv} 了。

上面这种做法将会把每两个用户之间的相似度都算一遍,计算量太大而且也没必要,因为在实际场景下,与用户A“关系很好”的朋友的数量通常是有限的。我们将用户A “关系很好 ”的那几个朋友找出来并计算他们与A的相似度就行了。

这就可以用上倒排表了。所谓倒排表,指的是从用户评分文件转换而来的物品用户倒排表。设倒排表为字典 T,则 T 中记录的是各个物品被哪些用户操作过。之后我们只计算操作过同一物品的不同用户之间的相似度就行了,计算的方法就是:对一个物品,用for循环遍历两遍其用户集。当然,我们还需要把所有物品给遍历一遍,这样才能累加得到同时被用户u和用户v喜欢的物品数。

下面我们定义一个函数实现用户相似度的计算。

def  user_similarity( user_dict ):

        # 构建倒排表

        item_users = dict()

        for u, u_items in user_dict.items():

                for i in u_items.keys():

                        item_users.setdefault( i, set() )

                        if user_dict[u][i] > 0.0:

                                item_users[ i ].add(u)    # 把用户u加入到物品 i 的用户集合中去

        # 上面的过程得到了倒排表 item_users

        # 构建用户在物品集上的同现矩阵,只对出现在同一个用户集里的两个用户进行计算

        user_itemcount = dict()    # 记录每个操作的物品数,后面要当做分母

        count = dict()   # 同现矩阵

         for i , i_users in item_users.items():

                for u in i_users:

                        user_itemcount.setdefault( u, 0 )

                        user_itemcount[u] += 1

                        count.setdefault(u, {} )

                        for v in i_users:

                                count[u].setdefault( v, 0 )

                                if u == v:

                                        continue

                                count[u][v] += 1 / math.log( 1 + len(i_users) )  

                                # len(i_users)表示操作过物品 i 的用户集里用户的数目,此处对热门物品进行了惩罚

        similarity = dict()    # 记录用户相似度

        for u , u_users in count.items():

                similarity.setdefault(u, {})

                for v, v_u in  u_users.items():

                        if u == v:

                                continue

                        similarity[u].setdefault(v, 0.0)

                        similarity[u][v] = v_u / math.sqrt( user_itemcount [u] * user_itemcount[v] )

        return similarity

4 预测评分的过程

我们可以定义一个近邻用户数 k 。在对某个用户进行推荐时,我们把与该用户 “关系最好”的其它 k 个用户所操作过的物品全部找出来,并从中剔除掉该用户已经操作过的物品,然后只对剩下的物品进行评分预测。

我们先找出该用户评价过的所有物品,假设保存在 item_of_thisuser字典里,字典的键为各个评价过的物品。事实上, item_of_thisuser 很容易从原始评分文件user_dict中提取出来。

下面我们定义一个函数实现评分预测的过程,暂时不考虑最终的排序问题。

def prediction(thisuser, k=8):

        result = dict()

        sort_similarity = sorted( similarity[ thisuser ].items(), key=lambda x: x[1], reverse=True)

        for v, wuv in sort_similarity[0: k]:

                for i, r_vi in user_dict[v].items():

                        if i in item_of_thisuser:

                                continue

                        result.setdefault(i, 0)

                        result[i] += r_vi * wuv

        return result

5 用户协同与物品协同的比较

从推荐场景而言,在电子商务、电影网站和图书网站等领域,用户数量远大于物品数量,且物品的数量更新速度并不快,可以考虑物品协同的方法。

对于新闻、博客等类似于信息流的领域,由于内容更新频率非常高,且内容很容易过时,可以考虑用户协同的方法。

用户协同更注重社会化因素,而物品协同更注重个性化因素。

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

推荐阅读更多精彩内容