相关推荐与个性化推荐

做市场类的产品,往往会有一些推荐功能,淘宝、亚马逊猜用户喜欢的产品,豆瓣猜用户喜欢的节目等。各种应用市场都会有给用户推荐应用的功能,比较常见的有下载完软件推荐相关的软件和根据用户记录个性化推荐应用。前一种比较好实现,个性化推荐则麻烦一些,需要较大的数据做支撑。这几天实现了相关推荐和实现了一个简单版本的个性化推荐,简要记录下来。

有几篇关于推荐的文章,推荐一下:
探索推荐引擎内部的秘密,第 1 部分: 推荐引擎初探
探索推荐引擎内部的秘密,第 2 部分: 深入推荐引擎相关算法 - 协同过滤
探索推荐引擎内部的秘密,第 3 部分: 深入推荐引擎相关算法 - 聚类

##相关推荐
应用的相关推荐原理比较简单,简单的说就是下载过这个应用的人还下载了哪些应用。下图是360手机助手的截图,相关性很明显地被显示出来,下载了这个应用的人里面有百分多少的人下载了另一个软件,这种关系就是计算一个应用与另一个的相关性,也就是协同过滤里说的,item与item之间的相关性。

相关推荐最关键的就是计算两个应用的相关性。也就是要求两个应用的下载群体的交集。为了带有一定的时效性,也为了节省计算量,我在计算相关性时只使用了半个月的下载日志。

  • 首先,将下载日志整理成”用户ID 应用1,应用2,应用3…”的形式,并对用户下载记录去重。
  • 接着统计应用对,也就是每个用户的下载列表中的用户一一对应组成一个软件对(软件对的数据非常大,如果内存容量不够,应该写到文件中再做统计)。
  • 统计每个软件对出现的次数,以及每个软件各自的下载次数。
  • 按一定的计算规则算出两个软件的相关性。(这里不能直接用软件出现的次数做为相关性的权重,要考虑到被推荐应用本身的下载量,有些很热门的软件容易出现在还下载的列表中,但他们不一定相关)。
  • 最后按权重排序,取前N个软件,记录入库就可以了,我是用redis存储。

以上步骤如果结合awk、sort、uniq命令与python一起使用的话,程序会非常简短,小几百行就能搞定了。
这里比较关键的是热门应用的处理。淘宝或亚马逊那种购物类的推荐出现大热门产品的可能性较少,一般相似的产品都比较有代表性,而应用推荐就有大热门应用的问题,没有做相应的处理的话,像QQ、微信、淘宝这种大热软件就会被一些跟他们没有什么关系的应用推荐出来。

大热应用的处理我是通过被推荐软件本身的下载量来调整的,被推荐应用的下载越大,最终的权重就下调越多。
还有一个特殊榜单的问题,应用市场一般都会有一个装机必备的列表,或者排行榜之类的特殊榜单,这些榜单上的应用被一起下载的可能性很高,会影响最终的结果。怎么去掉这些榜单的数据,就对日志的记录的要求就比较高了,操作从哪到哪都要记录下来。
最终效果:(加入广告的功能是必不可少的:D)。

##个性化推荐
个性化推荐相对复杂一些,而且对数据量要求也比较大。在开头的那几篇文章里有关于个性化推荐中协同过滤的实现方法。协同过滤过滤分为以物品为基础的Item CF算法和以用户为基础的User CF

以用户为基础的User CF原理如下图:

基于用户的 CF 的基本思想相当简单,基于用户对物品的偏好找到相邻邻居用户,然后将邻居用户喜欢的推荐给当前用户。计算上,就是将一个用户对所有物品的偏好作为一个向量来计算用户之间的相似度,找到 K 邻居后,根据邻居的相似度权重以及他们对物品的偏好,预测当前用户没有偏好的未涉及物品,计算得到一个排序的物品列表作为推荐。图 2 给出了一个例子,对于用户 A,根据用户的历史偏好,这里只计算得到一个邻居 - 用户 C,然后将用户 C 喜欢的物品 D 推荐给用户 A。

简单地说就是,User CF是通过喜好相似的用户所喜欢的物品作为推荐内容的。

以物品为基础的Item CF原理图:

基于物品的 CF 的原理和基于用户的 CF 类似,只是在计算邻居时采用物品本身,而不是从用户的角度,即基于用户对物品的偏好找到相似的物品,然后根据用户的历史偏好,推荐相似的物品给他。从计算的角度看,就是将所有用户对某个物品的偏好作为一个向量来计算物品之间的相似度,得到物品的相似物品后,根据用户历史的偏好预测当前用户还没有表示偏好的物品,计算得到一个排序的物品列表作为推荐。图 3 给出了一个例子,对于物品 A,根据所有用户的历史偏好,喜欢物品 A 的用户都喜欢物品 C,得出物品 A 和物品 C 比较相似,而用户 C 喜欢物品 A,那么可以推断出用户 C 可能也喜欢物品 C。

也就是说,Item CF是通过用户当前喜欢的物品作为基础,推荐与之相似的物品。

那我们要用哪种方法呢?

在应用推荐这个范围内,基于用户推荐是比较难实现的。所先,由于热门应用的存在,用户下载的应用一般都有很大的相似度。再者,用户不同时期下载的应用可能很分散,难以具体分析其喜好,需要较大的数据做支撑。一般应用市场常用被下载的应用都在十几二十万这个数量级,而用户量一般是千万级别,通过物品做关联的算法复杂度要低得多。

在做相关推荐的时候,就已经算出了应用的相关性,所以,基于应用的协同过滤算法可以直接引用相关推荐的数据。通过用户近期下载的软件,寻找相关度较高的应用作为推荐。

##一些问题
本文简要的阐述了相关推荐和个性化推荐的实现过程,不过这里面还有几个问题没有解决。

推荐一般是通过相似度做为关似的,这种方式在电影书籍或衣物等类别的产品是比较适合的,比如一个人喜欢看一类电影,那他可能会去找这个类别的电影一个个去看。但是应用就不一样了,你可能会在下载的时候下载同一类应用,来做比较,但最终你需要的可能就一个,好比说我下载了酷狗音乐,那再推荐天天动听是否合适?用户需要两个音乐播放的应用吗?而这在游戏上可能又不适用,用户就可能会安装多个相似的游戏。也就是说,有部分应用是有唯一性的,不适合推荐同类应用,需要用其他方法处理。

“冷启动”问题,也就是新应用和新用户没有相关的记录,如何推荐?

榜单效应问题。有一些应用榜单如上升最快、下载排行、编辑推荐、装机必备等,这些榜单上的应用很可能会被一起下载,但是他们之间可能完全没有相似度,会导致计算相似度时的误差。计算时需要去掉这类榜单的记录,这就需要日志记录下相关的信息,如下载所在的模块、位置等信息。

还有一个问题是,用户喜好的准确性。很多用户会同时下载多个应用,试用后将部分应用删除,也就是说单纯从“用户下载了这个应用”就判断用户喜欢这个应用是有问题的。至于分析用户评分、评论之类的就比较不现实现了,大部分应用都是没有评分及评论的。

个性化推荐是一个可以做得很复杂很深入的方向,有很多优化的方向,很多东西要学习。