协同过滤推荐系统搭建总结•什么是协同过滤现今的推荐技术和算法中,最被大家广泛认可和采用的就是基于协同过滤的推荐方法。协同过滤是利用集体智慧的一个典型方法,协同过滤一般是在海量的用户中发掘出一小部分和你品位比较类似的,在协同过滤中,这些用户成为邻居,然后根据他们喜欢的其他东西组织成一个排序的目录作为推荐给你。当然其中有一个核心的问题:•如何确定一个用户是不是和你有相似的品位?•如何将邻居们的喜好组织成一个排序的目录?要实现协同过滤,需要一下几个步骤•收集用户偏好•找到相似的用户或物品•计算推荐收集用户偏好以下图为例,用户偏好收集的表示方式用户行为类型特征作用评分显式整数量化的偏好,可能的取值是[0,n];n一般取值为5或者是10通过用户对物品的评分,可以精确的得到用户的偏好投票显式布尔量化的偏好,取值是0或1通过用户对物品的投票,可以较精确的得到用户的偏好转发显式布尔量化的偏好,取值是0或1通过用户对物品的投票,可以精确的得到用户的偏好。保存书签显式布尔量化的偏好,取值是0或1通过用户对物品的投票,可以精确的得到用户的偏好点击流(查看)隐式一组用户的点击,用户对物品感兴趣,需要进行分析,得到偏好用户的点击一定程度上反映了用户的注意力,所以它也可以从一定程度上反映用户的喜好。页面停留时间隐式一组时间信息,噪音大,需要进行去噪,分析,得到偏好用户的页面停留时间一定程度上反映了用户的注意力和喜好,但噪音偏大,不好利用•在一般应用中,我们提取的用户行为一般都多于一种,关于如何组合这些不同的用户行为,有两种方式:1.将不同的行为分组:一般可以分为“查看”和“购买”等等,然后基于不同的行为,计算不同的用户/物品相似度。类似于当当网或者Amazon给出的“购买了该图书的人还购买了...”,“查看了图书的人还查看了...”2.根据不同行为反映用户喜好的程度将它们进行加权,得到用户对于物品的总体喜好。一般来说,显式的用户反馈比隐式的权值大,但比较稀疏,毕竟进行显示反馈的用户是少数;同时相对于“查看”,“购买”行为反映用户喜好的程度更大,但这也因应用而异。•收集了用户行为数据,还需要对数据进行预处理,其中最关键的工作就是减噪和归一化。减噪:用户行为数据是用户在使用应用过程中产生的,它可能存在大量的噪音和用户的误操作,可以通过经典的数据挖掘算法过滤掉行为数据中的噪音,这样可以使分析更加准确。归一化:在计算用户对物品的喜好程度时,可能需要对不同的行为数据进行加权。但不同行为的数据取值可能相差很大,比如,用户的查看数据必然比购买数据大的多,如何将各个行为的数据统一在一个相同的取值范围中,从而使得加权求和得到的总体喜好更加精确,就需要进行归一化处理。最简单的归一化处理,就是将各类数据除以此类中的最大值,以保证归一化后的数据取值在[0,1]范围中。•进行预处理后,根据不同应用的行为分析方法,可以选择分组或者加权处理,之后可以得到一个用户偏好的二维矩阵,一维是用户列表,另一维是物品列表,值是用户对物品的偏好,一般是[0,1]或者[-1,1]的浮点数值。•找到相似的用户或物品•当已经对用户行为进行分析得到用户喜好后,就可以根据用户喜好计算相似用户和物品,然后基于相似用户或者物品进行推荐,这就是最典型的CF的两个分支:基于用户的CF和基于物品的CF,这两种方法都需要计算相似度•相似度的计算•相似度的计算,现有的几种基本方法都是基于向量(Vector)的,其实就是计算两个向量的距离,距离越近相似度越大。在推荐的场景中,在用户-物品偏好的二维矩阵中,我们可以将一个用户对所有物品的偏好作为一个向量来计算用户之间的相似度,或者将所有用户对某个物品的偏好作为一个向量来计算物品之间的相似度。•常用的相似度计算方法欧几里德距离,x,y是n维空间的两个点,它们之间的欧几里德距离是:•当n=2时,欧几里德距离就是平面上两个点的距离。当用欧几里德距离表示相似度,采用以下公式进行转换,距离越小,相似度越大。皮尔逊相关系数,皮尔逊相关系数一般用于计算两个变量间联系的紧密程度,它的取值在[-1,+1]之间•相似邻居的计算如何根据相似度找到用户-物品的邻居,常用的挑选邻居的原则可以分为两类1.固定数量的邻居:K-neighborhoods或者Fix-sizeneighborhoods不论邻居的“远近”,只取最近的K个,作为其邻居。如下图中的A,假设要计算点1的5-邻居,那么根据点之间的距离,我们取最近的5个点,分别是点2,点3,点4,点7和点5。但这种方法对于孤立点的计算效果不好,因为要取固定个数的邻居,当它附近没有足够多比较相似的点,就被迫取一些不太相似的点作为邻居,这样就影响了邻居相似的程度,比如图1中,点1和点5其实并不是很相似。2.基于相似度门槛的邻居:Threshold-basedneighborhoods与计算固定数量的邻居的原则不同,基于相似度门槛的邻居计算是对邻居的远近进行最大值的限制,落在以当前点为中心,距离为K的区域中的所有点都作为当前点的邻居,这种方法计算得到的邻居个数不确定,但相似度不会出现较大的误差。如下图中的B,从点1出发,计算相似度在K内的邻居,得到点2,点3,点4和点7,这种方法计算出的邻居的相似度程度比前一种优,尤其是对孤立点的处理。•计算推荐经过前面的计算已经得到了相邻用户和相邻物品,接下来就是基于这些信息为用户进行推荐,基于协同过滤的推荐算法可以分为基于用户的CF和基于物品的CF。基于用户的CF(UserCF)基于用户的CF的基本思想比较简单,基于用户对物品的偏好找到相邻邻居用户,然后将邻居用户喜欢的推荐给当前用户。计算上,就是将一个用户对所有物品的偏好作为一个向量来计算用户之间的相似度,找到K邻居后,根据邻居的相似度权重以及他们对物品的偏好,预测当前用户没有偏好的未涉及物品,计算得到一个排序的物品列表作为推荐。以下图为例,对于用户A,根据用户的历史偏好,这里只计算得到一个邻居-用户C,然后将用户C喜欢的物品D推荐给用户A,基于物品的CF(ItemCF)基于物品的CF的原理和基于用户的CF类似,只是在计算邻居时采用物品本身,而不是从用户的角度,即基于用户对物品的偏好找到相似的物品,然后根据用户的历史偏好,推荐相似的物品给他。从计算的角度看,就是将所有用户对某个物品的偏好作为一个向量来计算物品之间的相似度,得到物品的相似物品后,根据用户历史的偏好预测当前用户还没有表示偏好的物品,计算得到一个排序的物品列表作为推荐。以下图为例,对于物品A,根据所有用户的历史偏好,喜欢物品A的用户都喜欢物品C,得出物品A和物品C比较相似,而用户C喜欢物品A,那么可以推断出用户C也可能喜欢物品C•基于ApacheMahout实现协同过滤推荐ApacheMahout是ApacheSoftwareFoundation(ASF)旗下的一个开源项目,提供一些可扩展的机器学习领域经典算法的实现,旨在帮助开发人员更加方便快捷地创建智能应用程序。ApacheMahout中提供的一个协同过滤算法的高效实现,它是一个基于Java实现的可扩展的,高效的推荐引擎。下图给出了ApacheMahout中协同过滤推荐实现的组件图。•数据表示:DataModel•Preference•基于协同过滤的推荐引擎的输入是用户的历史偏好信息,在Mahout里它被建模为Preference(接口),一个Preference就是一个简单的三元组用户ID,物品ID,用户偏好,它的实现类是GenericPreference,可以通过以下语句创建一个GenericPreference。•GenericPreferencepreference=newGenericPreference(123,456,3.0f);•这其中,123是用户ID,long型;456是物品ID,long型;3.0f是用户偏好,float型。这个例子中,单单一个GenericPreference的数据就占用20bytes,所以你会发现如果只简单实用数组Array加载用户偏好数据,必然占用大量的内存,Mahout在这方面做了一些优化,它创建了PreferenceArray(接口)保存一组用户偏好数据,为了优化性能,Mahout给出了两个实现类,GenericUserPreferenceArray和GenericItemPreferenceArray,分别按照用户和物品本身对用户偏好进行组装,这样就可以压缩用户ID或者物品ID的空间。下面的代码以GenericUserPreferenceArray为例,展示了如何创建和使用一个PreferenceArray。•创建和使用PreferenceArray•为了提高性能Mahout还构建了自己的HashMap和Set:FastByIDMap和FastIDSet,•DataModel•Mahout的推荐引擎实际接受的输入是DataModel,它是对用户偏好数据的压缩表示,通过创建内存版DataModel的语句我们可以看出:•DataModelmodel=newGenericDataModel(FastByIDMapPreferenceArraymap);•他保存在一个按照用户ID或者物品ID进行散列的PreferenceArray,而PreferenceArray中对应保存着这个用户ID或者物品ID的所有用户偏好信息。•DataModel是用户喜好信息的抽象接口,它的具体实现支持从任意类型的数据源抽取用户喜好信息,具体实现包括内存版的GenericDataModel,支持文件读取的FileDataModel和支持数据库读取的JDBCDataModel,•创建各种DataModel•支持文件读取的FileDataModel,Mahout没有对文件的格式做过多的要求,只要文件的内容满足以下格式:1.每一行包括用户ID,物品ID,用户偏好2.逗号隔开或者Tab隔开3.*.zip和*.gz文件会自动解压缩,Mahout建议在数据量过大时采用压缩的数据存储•支持数据库读取的JDBCDataModel,Mahout提供一个默认的MySQL的支持,它对用户偏好数据的存放有以下简单的要求:1.用户ID列需要是BIGINT而且非空2.物品ID列需要是BIGINT而且非空3.用户偏好列需要是FLOAT•实现推荐:RecommenderMahout提供的协同过滤的推荐策略一般来说有三种,UserCF,ItemCF和SlopeOne基于Mahout实现UserCF从文件建立DataModel,采用前面所使用的的FileDataModel,这里用户的喜好信息存放在preferences.dat文件中,基于用户偏好数据计算用户的相似度,上图中采用的是PearsonCorrelationSimilarity,前面也介绍各种计算相似度的方法,Mahout中提供了基本的相似度的计算,它们都UserSimilarity这个接口,实现用户相似度的计算,包括常用的:PearsonCorrelationSimilarity:基于皮尔逊相关系数计算相似度EuclideanDistanceSimilarity:基于欧几里德距离计算相似度•ItemSimilarity也是类似的:•根据建立的相似度计算方法,找到邻居用户。这里找邻居用户的方法根据前面说过的的,也包括两种:“固定数量的邻居”和“相似度门槛邻居”计算方法,Mahout提供对应的实现:–NearestNUserNeighborhood:对每个用户取固定数量N的最近邻居–ThresholdUserNeighborhood:对每个用户基于一定的限制,取落在相似度门限内的所有用户为邻居。•基于DataModel,UserNeighborhood和UserSimilarity构建GenericUserBasedRecommender,实现UserCF推荐策略。•基于Mahout实现ItemCF•SlopeOneUserCF和ItemCF是最常用的两种CF的推荐策略,但在大数据量