目前流行的推荐系统基本上通过3种方式联系用户兴趣和物品。
第一种方式是利用用户喜欢过的物品,给用户推荐与他喜欢过的物品相似的物品,这就是前面提到的基于物品的算法。
第二种方式是利用和用户兴趣相似的其他用户,给用户推荐那些和他们兴趣爱好相似的其他用户喜欢的物品,这是前面提到的基于用户的算法。
第三种重要的方式是通过一些特征(feature)联系用户和物品,给用户推荐那些具有用户喜欢的特征的物品。
根据给物品打标签的人的不同,标签应用一般分为两种:一种是让作者或者专家给物品打标签;另一种是让普通用户给物品打标签,也就是UGC(User Generated Content,用户生成的内容)的标签应用。UGC的标签系统是一种表示用户兴趣和物品语义的重要方式。
4.1 UGC 标签系统的代表应用
使用UGC标签系统的代表网站——UGC标签系统的鼻祖Delicious、论文书签网站CiteULike、音乐网站Last.fm、视频网站Hulu、书和电影评论网站豆瓣等。
Delicious,允许用户给互联网上的每个网页打标签,从而通过标签重新组织整个互联网。
CiteULike,允许研究人员提交或者收藏自己感兴趣的论文并且给论文打标签,从而帮助用户更好地发现和自己研究领域相关的优秀论文。
Last.fm,让用户用标签标记音乐和歌手。
豆瓣,允许用户对图书和电影打标签,借此获得图书和电影的内容信息和语义,并用这种信息改善推荐效果。
Hulu,让用户对电视剧和电影进行标记。
标签系统的最大优势在于可以发挥群体的智能,获得对物品内容信息比较准确的关键词描述,而准确的内容信息是提升个性化推荐系统性能的重要资源。
标签系统的不同作用,以及每种作用能够影响多大的人群,如下所示。
(1)表达:标签系统帮助我表达对物品的看法。(30%的用户同意。)
(2)组织:打标签帮助我组织我喜欢的电影。(23%的用户同意。)
(3)学习:打标签帮助我增加对电影的了解。(27%的用户同意。)
(4)发现:标签系统使我更容易发现喜欢的电影。(19%的用户同意。)
(5)决策:标签系统帮助我判定是否看某一部电影。(14%的用户同意。)
4.2 标签系统中的推荐问题
标签系统中的推荐问题主要有以下两个。
(1)如何利用用户打标签的行为为其推荐物品(基于标签的推荐)?
(2)如何在用户给物品打标签时为其推荐适合该物品的标签(标签推荐)?
为了研究上面的两个问题,我们首先需要解答下面3个问题。
用户为什么要打标签?
用户怎么打标签?
用户打什么样的标签?
4.2.1 用户为什么进行标注
首先是社会维度,有些用户标注是给内容上传者使用的(便于上传者组织自己的信息),而有些用户标注是给广大用户使用的(便于帮助其他用户找到信息)。另一个维度是功能维度,有些标注用于更好地组织内容,方便用户将来的查找,而另一些标注用于传达某种信息,比如照片的拍摄时间和地点等。
4.2.2 用户如何打标签
Delicious数据集(参见 http://www.dai-labor.de/en/competence_centers/irml/datasets/),该数据集包含2003年9月到2007年12月Delicious用户4.2亿条标签行为记录。
标签的流行度分布也呈现非常典型的长尾分布,它的双对数曲线几乎是一条直线。
4.2.3 用户打什么样的标签
Delicious上的标签分为如下几类。
(1)表明物品是什么,比如是一只鸟,就会有“鸟”这个词的标签。
(2)表明物品的种类,比如在Delicious的书签中,表示一个网页类别的标签包括 article(文章)、blog(博客)、 book(图书)等。
(3)表明谁拥有物品,比如很多博客的标签中会包括博客的作者等信息。
(4)表达用户的观点,比如用户认为网页很有趣,就会打上标签funny(有趣),认为很无聊,就会打上标签boring(无聊)。
(5)用户相关的标签,比如 my favorite(我最喜欢的)、my comment(我的评论)等。
(6)用户的任务,比如 to read(即将阅读)、job search(找工作)等。
很多不同的网站也设计了自己的标签分类系统,比如Hulu对视频的标签就做了分类。
类型(Genre) 主要表示这个电视剧的类别,比如《豪斯医生》属于医学剧情片(medical drama)。
时间(Time) 主要包括电视剧发布的时间,有时也包括电视剧中事件发生的时间,比如20世纪90年代。
人物(People) 主要包括电视剧的导演、演员和剧中重要人物等。
地点(Place) 剧情发生的地点,或者视频拍摄的地点等。
语言(Language) 这部电视剧使用的语言。
奖项(Awards) 这部电视剧获得的相关奖项。
其他(Details) 包含不能归类到上面各类中的其他所有标签。
4.3 基于标签的推荐系统
一个用户标签行为的数据集一般由一个三元组的集合表示,其中记录(u, i, b) 表示用户u给物品i打上了标签b。
采用两个不同的数据集评测基于标签的物品推荐算法。一个是Delicious数据集,另一个是CiteULike数据集。
4.3.1 实验设置
将数据集随机分成10份。这里分割的键值是用户和物品,不包括标签。也就是说,用户对物品的多个标签记录要么都被分进训练集,要么都被分进测试集,不会一部分在训练集,另一部分在测试集中。然后,我们挑选1份作为测试集,剩下的9份作为训练集,通过学习训练集中的用户标签数据预测测试集上用户会给什么物品打标签。
对于用户u,令R(u)为给用户u的长度为N的推荐列表,里面包含我们认为用户会打标签的物品。令T(u)是测试集中用户u实际上打过标签的物品集合。然后,我们利用准确率(precision)和召回率(recall)评测个性化推荐算法的精度。
覆盖率的计算公式如下:
用物品标签向量的余弦相似度度量物品之间的相似度。
def CosineSim(item_tags, i, j):
ret = 0
for b,wib in item_tags[i].items():
if b in item_tags[j]:
ret += wib * item_tags[j][b]
ni = 0
nj = 0
for b, w in item_tags[i].items():
ni += w * w
for b, w in item_tags[j].items():
nj += w * w
if ret == 0:
return 0
return ret / math.sqrt(ni * nj)
在得到物品之间的相似度度量后,我们通过如下公式计算一个推荐列表的多样性。推荐系统的多样性为所有用户推荐列表多样性的平均值。
def Diversity(item_tags, recommend_items):
ret = 0
n = 0
for i in recommend_items.keys():
for j in recommend_items.keys():
if i == j:
continue
ret += CosineSim(item_tags, i, j)
n += 1
return ret / (n * 1.0)
至于推荐结果的新颖性,我们简单地用推荐结果的平均热门程度(AveragePopularity)度量。对于物品i,定义它的流行度item_pop(i)为给这个物品打过标签的用户数。而对推荐系统,我们定义它的平均热门度如下:
4.3.2 一个最简单的算法
最简单的个性化推荐算法:
(1)统计每个用户最常用的标签。
(2)对于每个标签,统计被打过这个标签次数最多的物品。
(3)对于一个用户,首先找到他常用的标签,然后找到具有这些标签的最热门物品推荐给这个用户。
对于上面的算法,用户u对物品i的兴趣公式如下:
,B(u)是用户u打过的标签集合,B(i)是物品i被打过的标签集合,
是用户u打过标签b的次数,
i是物品i被打过标签b的次数。
4.3.3 算法的改进
1. TF-IDF
前面的算法倾向于给热门标签对应的热门物品很大的权重,因此会造成推荐热门的物品给用户,从而降低推荐结果的新颖性。另外,这个公式利用用户的标签向量对用户兴趣建模,其中每个标签都是用户使用过的标签,而标签的权重是用户使用该标签的次数。这种建模方法的缺点是给热门标签过大的权重,从而不能反应用户个性化的兴趣。这里我们可以借鉴TF-IDF的思想,对这一公式进行改进:
,
记录了标签b被多少个不同的用户使用过。这个算法记为TagBasedTFIDF。
同理,我们也可以借鉴TF-IDF的思想对热门物品进行惩罚,从而得到如下公式:
,
记录了物品i被多少个不同的用户打过标签。这个算法记为TagBasedTFIDF++。
适当惩罚热门标签和热门物品,在增进推荐结果个性化的同时并不会降低推荐结果的离线精度。
2. 数据稀疏性
为了提高推荐的准确率,我们可能要对标签集合做扩展,我们可以将这个标签的相似标签也加入到用户标签集合中。
进行标签扩展有很多方法,其中常用的有话题模型(topic model),不过这里遵循简单的原则介绍一种基于邻域的方法。
标签扩展的本质是对每个标签找到和它相似的标签,也就是计算标签之间的相似度。
如果认为同一个物品上的不同标签具有某种相似度,那么当两个标签同时出现在很多物品的标签集合中时,我们就可以认为这两个标签具有较大的相似度。对于标签b,令N(b)为有标签b的物品的集合,n_{b,i}为给物品i打上标签b的用户数,我们可以通过如下余弦相似度公式计算标签b和标签b'的相似度:
对于曾经打过的标签数少于20的用户,我们找到其所打标签的相关标签,然后将这些标签聚合排序,将排序结果中前20个标签作为用户相关的标签。表4-8展示了考虑标签扩展后的推荐算法性能。
进行标签扩展确实能够提高基于标签的物品推荐的准确率和召回率,但可能会稍微降低推荐结果的覆盖率和新颖度。
3. 标签清理
不是所有标签都能反应用户的兴趣。同时,标签系统里经常出现词形不同、词义相同的标签。
标签清理的另一个重要意义在于将标签作为推荐解释。如果我们要把标签呈现给用户,将其作为给用户推荐某一个物品的解释,对标签的质量要求就很高。
一般来说有如下标签清理方法:
去除词频很高的停止词;
去除因词根不同造成的同义词;
去除因分隔符造成的同义词;
为了控制标签的质量,很多网站也采用了让用户进行反馈的思想,即让用户告诉系统某个标签是否合适。
4.3.4 基于图的推荐算法
首先,我们需要将用户打标签的行为表示到一张图上。在用户标签数据集上,有3种不同的元素,即用户、物品和标签。因此,我们需要定义3种不同的顶点,即用户顶点、物品顶点和标签顶点。然后,如果我们得到一个表示用户u给物品i打了标签b的用户标签行为(u,i,b),那么最自然的想法就是在图中增加3条边,首先需要在用户u对应的顶点v(u)和物品i对应的顶点v(i)之间增加一条边(如果这两个顶点已经有边相连,那么就应该将边的权重加1),同理,在v(u)和v(b)之间需要增加一条边,v(i)和v(b)之间也需要边相连接。
在定义出用户—物品—标签图后,我们可以用第2章提到的PersonalRank算法计算所有物品节点相对于当前用户节点在图上的相关性,然后按照相关性从大到小的排序,给用户推荐排名最高的N个物品。
4.3.5 基于标签的推荐解释
基于标签的推荐其最大好处是可以利用标签做推荐解释,这方面的代表性应用是豆瓣的个性化推荐系统。
豆瓣读书推荐结果包括两部分。上面是一个标签云,表示用户的兴趣分布,标签的尺寸越大,表示用户对这个标签相关的图书越感兴趣。单击标签云中的每一个标签,都可以在标签云下方得到和这个标签相关的图书推荐。
豆瓣这样组织推荐结果页面有很多好处,首先是提高了推荐结果的多样性。同时,标签云也提供了推荐解释功能。
对基于标签的解释进行了深入研究,发现:
用户对标签的兴趣对帮助用户理解为什么给他推荐某个物品更有帮助;
用户对标签的兴趣和物品标签相关度对于帮助用户判定自己是否喜欢被推荐物品具有同
样的作用;
物品标签相关度对于帮助用户判定被推荐物品是否符合他当前的兴趣更有帮助;
客观事实类标签相比主观感受类标签对用户更有作用。
4.4 给用户推荐标签
4.4.1 为什么要给用户推荐标签
一般认为,给用户推荐标签有以下好处。
方便用户输入标签
提高标签质量
4.4.2 如何给用户推荐标签
第0种方法就是给用户u推荐整个系统里最热门的标签(这里将这个算法称为PopularTags)。
第1种方法就是给用户u推荐物品i上最热门的标签(这里将这个算法称为ItemPopularTags)。
第2种方法是给用户u推荐他自己经常使用的标签(这里将这个算法称为UserPopularTags)。
第3种算法是前面两种的融合(这里记为HybridPopularTags),该方法通过一个系数将上面的推荐结果线性加权,然后生成最终的推荐结果。
def RecommendHybridPopularTags(user,item, user_tags, item_tags, alpha, N):
max_user_tag_weight = max(user_tags[user].values())
for tag, weight in user_tags[user].items():
ret[tag] = (1 – alpha) * weight / max_user_tag_weight
max_item_tag_weight = max(item_tags[item].values())
for tag, weight in item_tags[item].items():
if tag not in ret:
ret[tag] = alpha * weight / max_item_tag_weight
else:
ret[tag] += alpha * weight / max_item_tag_weight
return sorted(ret[user].items(), key=itemgetter(1), reverse=True)[0:N]
4.4.3 实验设置
法将数据集按照9∶1分成训练集和测试集,然后通过训练集学习用户标注的模型。
对于测试集中的每一个用户物品对(u,i),我们都会推荐N个标签给用户u作参考。令R(u,i)为我们给用户u推荐的应该在物品i上打的标签集合,令T(u,i)为用户u实际给物品i打的标签的集合,我们可以利用准确率和召回率评测标签推荐的精度:
实验结果
很多应用在给用户推荐标签时会直接给出用户最常用的标签,以及物品最经常被打的标签。
基于统计用户常用标签和物品常用标签的算法有一个缺点,就是对新用户或者不热门的物品很难有推荐结果。解决这一问题有两个思路。
第一个思路是从物品的内容数据中抽取关键词作为标签。
第二个思路是针对有结果,但结果不太多的情况。可以做一些关键词扩展。
4.4.4 基于图的标签推荐算法
图模型同样可以用于标签推荐。在根据用户打标签的行为生成图之后(如图4-11所示),我们可以利用PersonalRank算法进行排名。但这次遇到的问题和之前不同。这次的问题是,当用户u遇到物品i时,会给物品i打什么样的标签。因此,我们可以重新定义顶点的启动概率,如下所示:
也就是说,只有用户u和物品i对应的顶点有非0的启动概率,而其他顶点的启动概率都为0。在上面的定义中,v(u)和v(i)的启动概率并不相同,v(u)的启动概率是a,而v(i)的启动概率是1-a。参数α可以通过离线实验选择。
4.5 扩展阅读
基于标签的推荐系统比赛,比赛介绍见 http://www.kde.cs.uni-kassel.de/ws/rsdc08/program.html。
在这些研究中涌现了很多新的方法,比如张量分解(tensor factorization)(参见Panagiotis Symeonidis、Alexandros Nanopoulos和Yannis Manolopoulos的“Tag recommendations based on tensor dimensionality reduction”(ACM 2008 Article,2008))、基于LDA的算法(参见Ralf Krestel、 Peter Fankhauser和Wolfgang Nejdl的“Latent dirichlet allocation for tag recommendation”(ACM 2009 Article,2009))、基于图的算法(参见Andreas Hotho、 Robert Jäschke、 Christoph Schmitz和Gerd Stumme的“Folkrank: A ranking algorithm for folksonomies”(Proc. FGIR 2006,2006))等。不过这些算法很多具有较高的复杂度,在实际系统中应用起来还有很多实际的困难需要解决。
研究如何利用标签联系用户和物品并给用户进行个性化电影推荐,参见Shilad Wieland Sen、 Jesse Vig和John Riedl的“Tagommenders: Connecting Users to Items through Tags”(ACM 2009 Article,2009)。
研究如何利用标签进行推荐解释,他将用户和物品之间的关系转化为用户对标签的兴趣(tag preference)以及标签和物品的相关度(tag relevance)两种因素。参见Jesse Vig、Shilad Wieland Sen和John Riedl的“Tagsplanations: Explaining Recommendations Using Tags”(ACM 2009 Article,2009)。
研究如何对标签进行清理,以及如何选择合适的标签进行解释。参见Shilad Wieland Sen、F. Maxwell Harper、Adam LaPitz和John Riedl的“The quest for quality tags”(ACM 2007 Article,2007)。