博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一种基于共现的推荐算法
阅读量:6121 次
发布时间:2019-06-21

本文共 3562 字,大约阅读时间需要 11 分钟。

参考原文

现有所有用户的购物列表:

user1: G  A  Buser2: X  C  Yuser3: X  E  Fuser4: X  M  Y  Q  N  J  Huser5: W  Y user6: L  E  Z  W

现在要计算商品X的相似商品。

思路:要计算X和Y的相似度直接计算p(Y|X)即可。根据极大似然估计

\begin{equation} p(Y|X)=\frac{count(X,Y)}{count(X)}=\frac{2}{3} \label{orig} \end{equation}

公式(\ref{orig})有2个问题:

  1. 如果Y是一个很热门的商品,则它倾向于和任意商品共现。也就是说如果$count(X,Y)$比较大,并不能直接说明X和Y的相关度就大,也可能是因为Y商品非常地热门。
  2. 对于热衷于购物的用户,她会买很多东西,这些东西之间不一定有相关度。也就是说如果一个用户购物比较少,我们倾向于认为这些商品之间的相关度比较高;如果一个用户购物比较多,我们倾向于认为这些商品之间的相关度比较低。

符号约定:

$N_{XY}$:同时购买了商品X和Y的用户数

$p(Y)$:总体而言,商品Y被购买的概率。$p(Y)=\frac{Y被购买的次数}{卖出去的商品总数}$

$C_X$:购买了商品X的用户集合

$c$:$C_X$中的一个用户

$|c|$:用户$c$购物的总数减去用户$c$购买X的次数

先假设商品X和Y相互独立,则用户$c$除了买X外还买了$|c|$件其他商品,每次购买都看成是一次试验:是否购买商品Y。则用户$c$没有购买Y的概率为:

$$(1-p(Y))^{|c|}$$

用户$c$购买Y的期望为:

$$1-(1-p(Y))^{|c|}$$

用户集合$C_X$购买Y的期望次数为:

\begin{equation}E_{XY}=\sum_{c \in C_X}\left[1-(1-p(Y))^{|c|}\right]  \label{E} \end{equation}

实际上X和Y可能不是相互独立的,它们之间的相关度为:

\begin{equation} relevance(X,Y)=\frac{N_{XY}-E_{XY}}{\sqrt{E_{XY}}} \label{R} \end{equation}

联合(\ref{E})式和(\ref{R})式可知:$p(Y)越大(即Y越热门),X和Y的相关度越低;$$|c|$越大(即用户的购物列表越长),X和Y的相关度越低。正好解决(或者说缓和)了本文一开头提出的那2个问题。

# coding=utf-8__author__ = "orisun"import mathfrom collections import defaultdicttarget_position = set(    [3218357, 3222919, 3050675, 3097961, 3202165, 3122457, 2747795])  # 要为这些职位生成推荐deliver_list_dict = defaultdict(list)  # 包含target_position的投递列表deliver_prob_dict = {}def deliverCount(deliverFile):    """统计每个职位被投递的概率    """    global target_position    global deliver_list_dict    global deliver_prob_dict    total_deliver = 0  # 总投递次数    deliver_count_dict = defaultdict(int)  # 每个职位被投递的次数    with open(deliverFile, 'r') as f_in:        for line in f_in:            arr = line.strip().split()            if len(arr) > 1:                deliver_set = set()                for ele in arr[1:]:                    brr = ele.split(",")                    if len(brr) == 3:                        if "1" == brr[0]:                            pid = int(brr[1])                            total_deliver += 1                            deliver_count_dict[pid] += 1                            deliver_set.add(pid)                for target in target_position:                    if target in deliver_set:                        deliver_list_dict[target].append(list(deliver_set))    for pid, cnt in deliver_count_dict.items():        deliver_prob_dict[pid] = 1.0 * cnt / total_deliverdef recForPosition(pid):    global deliver_list_dict    global deliver_prob_dict    if pid in deliver_list_dict:        deliver_list_list = deliver_list_dict[pid]        cooccur_count_dict = defaultdict(int)        expect_count_dict = defaultdict(float)        for deliver_list in deliver_list_list:            for deliver in deliver_list:                if deliver != pid:                    cooccur_count_dict[deliver] += 1                    expect_count_dict[deliver] += 1 - \                        math.pow(                            1 - deliver_prob_dict[deliver], len(deliver_list) - 1)        relevant_dict = {}        for deliver, cnt in cooccur_count_dict.items():            relevant_dict[deliver] = 1.0 * (cnt - len(deliver_list_list) * expect_count_dict[                                            deliver]) / math.sqrt(expect_count_dict[deliver])        # 只取相关度最高的前50个作为推荐        return sorted(relevant_dict.items(), cmp=lambda x, y: cmp(y[1], x[1]))[:50]    return Noneif __name__ == '__main__':    deliverCount("/data/orisun/dnn_for_rec/behavior/allBehavior.txt")    for target in target_position:        print "neighbors of position", target        print recForPosition(target)

  

 

转载地址:http://wmgka.baihongyu.com/

你可能感兴趣的文章
20172303 2017-2018-2 《程序设计与数据结构》第5周学习总结
查看>>
eclipse中将一个项目作为library导入另一个项目中
查看>>
Go语言学习(五)----- 数组
查看>>
Android源码学习之观察者模式应用
查看>>
Content Provider的权限
查看>>
416. Partition Equal Subset Sum
查看>>
centos7.0 64位系统安装 nginx
查看>>
数据库运维平台~自动化上线审核需求
查看>>
注解开发
查看>>
如何用 Robotframework 来编写优秀的测试用例
查看>>
Django之FBV与CBV
查看>>
Vue之项目搭建
查看>>
app内部H5测试点总结
查看>>
Docker - 创建支持SSH服务的容器镜像
查看>>
[TC13761]Mutalisk
查看>>
三级菜单
查看>>
Data Wrangling文摘:Non-tidy-data
查看>>
加解密算法、消息摘要、消息认证技术、数字签名与公钥证书
查看>>
while()
查看>>
常用限制input的方法
查看>>