@ 2009/03/26; 2009/04/03 ; 2009/04/04
因为此文原存储地址(blog.qingyu.org)域名在国内注册,基于一些因素考虑将部分还未失去时效性的日志转贴此处,照成不便还请见谅。
这两天读的一本叫《Web信息架构》的书中经常提及“协同过滤”这个字眼,我后来突然发现,原来协同过滤在现在的Web2.0网站中被应用得如此普遍,尤其是在社会化音乐网站中更是被发挥到了极致。
其中最典型的应用比如:全球最大的B2C电子商务网站Amazon,网页资源的挖掘机Digg和StumbleUpon,社会化音乐服务Last.fm和iLike等。
下面便是这几天对协同过滤这个概念的学习笔记。主要参考维基百科中文和英文两个词条。
什么是协同过滤
协同过滤在我看来让大众用户难以理解的并非它背后复杂的过滤算法和推荐算法,而是它一些相对晦涩的概念和原理。
简单来说协同过滤是:推荐系统把与你臭味相投之用户喜欢的东西推荐给你。
比如说豆瓣用户登陆后在首页看到的那些由豆瓣推荐给你的电影、图书、音乐、评论、活动。
豆瓣网通过你以前在豆瓣上的记录(对音乐、图书这类资源所打的星级等)来找出豆瓣上其它与你有着相似爱好和相似经验(豆瓣活动)的豆友,并把它们喜欢的东西推荐给你。
协同过滤便是基于这样的假设:在一组兴趣相似的用户中,那么协同过滤便认为用户既然在一部事物(系统数据库中已经存在的记录)上有共同兴趣,那么这一组用户中一个用户的感兴趣的东西很可能也会被另一个用户青睐。
协同过滤的简单工作原理
协同过滤深谙臭味相投的道理。假设这里有由用户A和用户B构成的用户组,系统已经采集到(知道)这两个用户的兴趣,其中用户A对1,2,3,4非常感兴趣,而用户B对1,2,3,5亦有很大兴趣。其中1,2,3是两个用户共同的爱好。那么协同过滤就认为4和5有可能是用户B和用户A感兴趣的,于是将4推荐给用户B,把5推荐给用户A。
当然这是一个绝对简单化了的流程。事实上协同过滤要复杂得多,首先一个系统内就不仅仅存在两个用户,而且用户的喜好也是极其复杂的。
在完成对用户的推荐之前,协同过滤系统需要完成对用户兴趣的采集、近邻搜索、最终完成推荐。而协同过滤主要又分为基于用户、基于项目和基于模型三大类。
Last.fm中基于用户的协同过滤实例
上面从概念层面上介绍了协同过滤的基本原理。协同过滤在目前一些主流社会化音乐服务的推荐音乐上有着极高的地位。协同过滤一般情况下分为基于用户和基于项目。其中以用户为基础的协同过滤主要通过一定算法找出和某个用户偏好匹配的更多内容,而基于项目的协同过滤主要是要找出针对某一项目找出与其匹配的其它项目。
举一个非常熟悉的例子:在豆瓣网首页中用户看到的“今日推荐的书、影、音……”就是一种典型的基于用户的协同过滤,因为豆瓣网协同过滤算法给出的这些推荐内容是为用户量身定做且独一无二的,其参考了用户自身在豆瓣网上的行为及其好友的行为;而在豆瓣网中某一条目(比如一张专辑)的页面中用户看到的“喜欢听”这张唱片”的人也喜欢 ……”就是种典型的基于项目的协同过滤,它根据用户在豆瓣网上给这些内容的打分和与其它内容的关联算出与这张专辑相似的专辑并列出来。
协同过滤在社会化音乐中得到了非常普遍的应用,下面将以Last.fm和Spotify为例,在推荐表现上他们分别通过网页和客户端来呈现推荐结果。
Last.fm作为一个非常典型的网络电台,它的过滤机制也主要用在电台服务上。
在Last.fm个性化的电台中通过诸如以上四个这样的电台来为用户推荐更多与用户口味相匹配的音乐。
在Last.fm首页上看到的如上界面就是一基于用户的协同过滤非常典型的应用。
而Last.fm为用户推荐不仅仅局限于音乐,还包括免费的MP3下载,音乐视频和一些发生在用户周围的活动。
Last.fm的榜单在整个系统中得到了非常广泛的应用,它不仅要影响那些对用户的推荐曲目,本身也是一种协同过滤的TOP N形式。Last.fm将用户所有听过的音乐进行排序,找出用户听得最多的音乐(一般情况下也默许是用户非常喜欢的)。
Last.fm还会根据相似的音乐偏好为用户推荐其它Last.fm用户(在Last.fm里叫做邻居),方便用户知道他们邻居正在听的音乐是什么,在前面那篇文章已经提到过,你邻居喜欢的音乐会不会也是你喜欢的呢?
在完成所有推荐之前,Last.fm需要对用户的音乐偏好进行信息采集,Last.fm主要通过像上面这样的“记录用户的收听历史”来采集用户兴趣的信息。然后就可以结合其它同类的信息完成推荐了。
Spotify中基于用户的协同过滤实例
Spotify并不会像Last.fm那样会永久地保存用户的音乐收听历史,就更不用说为用户建立音乐数据库了,它在客户端首页上的推荐一般是基于用户最近收听的音乐,所以我们很容易发现Spotify的推荐清单很容易随着我们收听音乐的变化而变化。
而Spotify的Top Lists则和Last.fm中的流行榜单类似,将所有Spotify用户的收听音乐记录进行排序。最终实现一个Spotify的流行榜单。比较特殊的是 Spotify还可以排出不同国家的Spotify流行榜单。
而Spotify也同Last.fm类似通过记录用户最近收听的音乐历史推算出用户可能感兴趣的音乐。
有意思的是Spotify也支持通过Audioscrobbler将Spotify上播放的音乐历史提交给用户的Last.fm账户,这样在 Spotify上的大量音乐记录也可以帮助Last.fm采集的用户信息更加完整。
基于用户的协同过滤流程
在一个产品设计中,产品设计者、开发者无论是否需要装成用户去思考问题,用户在整个Web2.0网站的设计哲学中都是至关重要的。尤其是那些需要用户来为你产生内容的网站。
那么在一些寄希望通过协同过滤来为用户提供服务的社会化音乐网站中,用户的地位有多高呢?
在前面的文字中,大量的插图告诉我们似乎协同过滤就是一件用户的“声音”来为用户提供更多“声音” 的服务。如果没有用户参与进来,那么一切都变得难堪起来。
再复杂的协同过滤系统大致都需要经过以上三个步骤:网站通过大量交互应用收集用户对网站提供的服务内容的兴趣偏好,然后把其它用户的数据整合进来进行近邻搜索,最终抽离掉那些无法与用户现有兴趣数据匹配的内容,生成推荐结果。
在这样一个用户隐私意识越来越高的环境下,网站想要尽可能地收集更多的用户信息是非常困难的,网站向用户索取那些可能不会被用户意识到严重性的数据时需要想尽一切办法,拐弯抹角。有像亚马逊那样的记录用户购买历史,有豆瓣那样的添星功能,也有Last.fm那样通过插件来记录用户音乐播放历史,添加标签等途径。
所以在一个以推荐起家的网站来说如果用户基数将直接影响网站的最终推荐效果,太少的用户数据只能让那些协同过滤算法显得笨拙不堪。
但当用户增加到一定程度上来时,对用户依赖程度高的协同过滤算法的计算量就开始快速增加,几乎是呈线性增长。这极大地限制了系统的性能和响应速度,这也就限制了基于用户的协同过滤更广泛的应用。如果能有一种不过多依赖用户的推荐就可以解决这个问题了,因为强大的缓存机制可以缓减高负荷的系统压力。而下面将要介绍的“基于项目的协同过滤”似乎就正是为这种需求而生的。