常见推荐系统算法浅谈
如今,网购的人已经习惯了收到系统为他们做出的个性化推荐。腾讯视频推荐你可能会喜欢看的视频。网易云音乐会通过预测我们想要听什么歌曲从而生成个性化歌单。所有这些推荐结果都来自于各式各样的推荐系统。它们根据顾客的浏览、搜索、下单和喜好,为用户选择他们可能会喜欢、有可能会购买的商品,从而为用户服务。推荐系统的设计初衷是帮助电商提高销售额,现在这是一块儿规模巨大且不断增长的业务。
随着越来越多不同类型网站的用户数据变得可用,推荐系统得以将创新算法应用于这些数据之上,推荐系统变得越发精准和垂直,常常看起来比你自己还要了解你。推荐算法是怎么“猜你喜欢”的?你有没有想过自己在淘宝眼中是什么样子?答案是:你是一个很大、很大的表格里一串很长的数字。这串数字描述了你所看过的每一样东西,你点击的每一个链接以及你在淘宝上买的每一件商品;表格里的其余部分则代表了其他数百万到淘宝购物的人。你每次登陆网站,你的数字就会发生改变;在此期间,你在网站上每动一下,这个数字就会跟着改变。这个信息又会反过来影响你在访问的每个页面上会看到什么,还有你会收到什么样的推送。
比如彩蛋君刚逛了淘宝看了雪板,而淘宝下面的推送全变成了雪具的推荐
许多年来,推荐系统的开发者试过用各种各样的方法来采集和解析所有这些数据。目前,多数人都选择使用被称为个性化协同推荐 (Personalized Collaborative Recommender)的算法。这也是亚马逊、Netflix、Facebook 等海外一些主站选用的算法。说它 “个性化”,是因为这种算法会追踪用户的每一个行为(如浏览过的页面、订单记录和商品评分),以此进行推荐。而所谓的 “协同”,是这种算法会根据许多其他的顾客也购买了这些商品或者对其显示出好感(评分、浏览记录等),而将两样物品视为彼此关联,它不是通过分析商品特征或者关键词来进行判断的。User-User (用户关联)算法:计算用户之间的相似度这种类型的算法会计算一对用户之间的 “距离”,根据的是他们对同一物品打分的相似程度。举例来说,如果王二狗和张小花都给《爱乐之城》这部电影打了 5 分,那么他们之间的距离就是 0。如果二狗给同类型的《红磨坊》打了 5 分,而小花只打了 3 分,那么他们之间的距离就变大了。按照这样的计算得出来品味相对 “靠近” 的用户,我们把他们称之为共有一个 “邻集”(nei**orhood)。
但是,这种用户关联的策略效果并不是很好。首先,形成有意义的邻集很难:很多用户两两之间只有很少几个共同评分,有的就完全没有;而仅有的那几个都打了分的项目往往是票房大片,基本上人人都喜欢的那种。再来,由于用户之间的距离可以变得很快,算法必须即时进行大部分的计算;而这可能会比一个在网站上这儿点点那儿戳戳的人下一个动作发出之前需要更久的时间去计算。Item-Item (物品关联)算法:计算物品之间的关联大部分的推荐系统如今都依靠“物-物关联”(item-item)的算法,这种算法计算的是两本书、两部电影或者两个其他什么东西之间的距离,依据的是给它们打过分的用户的相似度。喜欢苏青的人很可能会给张爱玲的作品打高分,因此苏青和张爱玲的书就共处一个邻集。一对物品之间的距离可能是根据成百上千万的用户的评分计算得出,在一段时间里往往保持相对稳定,因此推荐系统可以预先计算距离,并更快的生成推荐结果。亚马逊和Netflix 都曾公开表示过他们使用的是物-物关联算法的变种,但对细节都绝口不提。
用户关联算法和物-物关联算法都有的一个问题,是用户评分的不一致性。当给他们机会再评一次分时,用户往往会对同一件物品给出不同的得分。品味在变、心情在变、印象也在变。而开发者们也在一直在尝试不同的方法在模型中纳入这一变量;比如用户给某个商品了打一个分,但这个评分与推荐算法所了解的关于这个人和这个商品的其他相关信息不相符,有的推荐算法就会邀请用户再次对这个商品进行评价。降维算法:把事物特征一般化不过,用户关联算法和物-物关联算法还存在一个比一致性更大的问题:它们太刻板了。就是说,它们能发现都喜欢同一样东西的人,但却忽略了爱好非常相似的潜在用户组合。比如说你喜欢齐白石的虾。那么,在这位大师画的 100 幅虾中,你最喜欢哪一幅?在一群喜欢齐白石的人当中,可能每个人喜欢的虾都不相同,而基本的算法就可能识别不出这些人都有着共同的爱好。
开发者们后来想出了一个办法,通过一个叫降维(Dimensionality Reduction)的过程,把事物更一般化的表现出来。这种方法在计算量上比用户关联和物-物关联算法要密集得多,因此也就没有那么快的得到采用。但随 着计算机变更快更便宜,降维算法也逐步取得了一些进展。
为了弄清降维算法是怎么工作的,我们来看看你爱吃的东西,以及如何把它跟其他一百万人爱吃的东西做比较。你可以把这些信息用一个巨型矩阵表示出来,每一条竖线代表一样食物, 每个人爱吃什么东西就自然形成了一行。在你的这一行上面或许会显示你给了卤煮 5 颗星、红烧肉 4 星半、烤猪蹄 3 颗星、豆腐脑 1 颗星、小龙虾 5 颗星、炒肝 4 颗星等等。(写到这儿我都饿了...)
然而,使用这个矩阵的推荐算法并不关心你给哪种食物评了多少颗星。它想要了解的是你一般而言的喜好,这样它可以将这个信息应用到更丰富多样的食物上。比如基于你上面给出的信息,算法可能会认为你喜欢猪肉、内脏类食物和地方菜品,不喜欢任何油炸食物和蔬菜,依此类推。你爱吃的食物所拥有的特点(或者说维度),它的数量和符合你要求的食物的数量比起来要小得多——至多可能 50 或 100。通过查对这些维度,推荐算法可以迅速决定你是否会喜欢一种新的食物(比方说羊杂汤),方法就是把这种食物的各项维度(地方菜品、内脏、不是鸡肉、不是炒的、不是蔬菜、不是烤的)同你的资料进行比对。这种更为一般性的呈现使得推荐算法能准确的发现有着相似但不同喜好的用户。而且它大幅压缩了矩阵的规模,使算法变得更加高效。
这是一个很酷的解决方案。不过,你爱吃的食物的维度该上哪儿去找呢?肯定不是去问厨师。推荐系统会使用一种称为奇异值分解的数学方法来计算维度。这种方法涉及到把最初的一个巨型矩阵分解为两个 “口味矩阵”——其中一个包含了所有的用户和 100 项口味维度,另一个则包含了所有的食物和 100 项口味维度——再加上第三个矩阵,当乘以前面两个矩阵中的任意一个时,会得到最初的那个矩阵。
计算用的维度既不是描述性的,也一点儿都不直观;它们是纯抽象的值,只要这些值最终生成准确的推荐结果就行了。这种方法的主要缺点是,创建矩阵所需要的时间会随着客户和产品数量的增多而飞速增长——创建一个拥有 2.5 亿名客户和 1000 万种产品的矩阵,需要花上创建一个 25 万名客户和 1 万种产品的矩阵 10 亿倍那么多的时间。而且这一过程还需要经常重复。一旦收到新的评分,矩阵就已经过时;在像亚马逊这样的公司,每一秒钟都会收到新的评论。幸运的是,就算略微过时,矩阵仍然能以一个挺不错的水平运作。开发者们也已经在设计新的算法,为奇异值分解提供可用的近似值并显著缩短计算时间。
页:
[1]