读书笔记--项亮《推荐系统实践》第四章

                                                                        第四章 利用用户标签数据

背景:
推荐系统的目的是联系用户的兴趣和物品,这种联系需要依赖不同的媒介。目前流行的推荐系统基本上通过3种方式联系用户兴趣和物品。

  • 基于物品的算法;
  • 基于用户的算法;
  • 通过一些特征(feature)联系用户和物品,给用户推荐那些具有用户喜欢的特征的物品。这里的特征有**不同的表现方式,**比如可以表现为物品的属性集合(比如对于图书,属性集合包括作者、出版社、主题和关键词等),也可以表现为隐语义向量(latent factor vector);本章将讨论一种重要的特征表现方式——标签。
    在这里插入图片描述
    根据给物品打标签的人的不同,标签应用一般分为两种:
  • 一种是让作者或者专家给物品打标签;
  • 另一种是让普通用户给物品打标签,也就是UGC(User Generated Content,用户生成的内容)的标签应用。

UGC的标签系统是一种表示用户兴趣和物品语义的重要方式。当一个用户对一个物品打上一个标签,这个标签一方面描述了用户的兴趣,另一方面则表示了物品的语义,从而将用户和物品联系了起来
因此本章主要讨论UGC的标签应用,研究用户给物品打标签的行为,探讨如何通过分析这种行为给用户进行个性化推荐。

4.1 UGC 标签系统的代表应用

UGC标签系统的代表应用有UGC标签系统的鼻祖Delicious、论文书签网站CiteULike、音乐网站Last.fm、视频网站Hulu、书和电影评论网站豆瓣等。

下面以Delicious为例展开讲解。
Delicous允许用户给互联网上的每个网页打标签,从而通过标签重新组织整个互联网。
下图所示是Delicious中“豆瓣电台”这个网页被用户打的最多的标签,可以看到这些标签确实从各个角度准确地描述了“豆瓣电台”这个物品。
在这里插入图片描述

4.2 标签系统中的推荐问题

标签系统中的推荐问题主要有以下两个。

  • 如何利用用户打标签的行为为其推荐物品(基于标签的推荐)?
  • 如何在用户给物品打标签时为其推荐适合该物品的标签(标签推荐)?(可以参考CSDN博客的文章的标签推荐方式)

为了研究上面的两个问题,我们首先需要解答下面3个问题。

  • 用户为什么要打标签?
  • 用户怎么打标签?
  • 用户打什么样的标签?

4.2.1 用户为什么进行标注

在设计基于标签的个性化推荐系统之前的准备工作:
我们需要深入了解用户的标注行为(即打标签的行为),知道用户为什么要标注,用户怎么标注,要深入了解用户的行为。

用户标注的动机问题

  • 社会维度:有些用户标注是给内容上传者使用的(便于上传者组织自己的信息) ,而有些用户标注是给广大用户使用的(便于帮助其他用户找到信息);
  • 功能维度:有些标注用于更好地组织内容,方便用户将来的查找,而另一些标注用于传达某种信息,比如照片的拍摄时间和地点等。

4.2.2 用户如何打标签

这一节将通过研究Delicious数据集总结用户标注行为中的一些统计规律。

我们定义的一个标签被一个用户使用在一个物品上,它的流行度就加一。

前面我们提到:
用户行为数据集中用户活跃度和物品流行度的分布都遵循长尾分布。
如下图所示,横坐标是流行度k,纵坐标是数据集中流行度为k的标签总数 n ( k ) 。标签的流行度分布也呈现非常典型的长尾分布。
在这里插入图片描述

4.2.3 用户打什么样的标签

在用户看到一个物品时,我们希望他打的标签是能够准确描述物品内容属性的关键词。当然事实上很多用户打出的标签并不能很好的表示出物品的特征,会产生一些奇怪而又无效的标签。
以Delicious数据集为例,该数据集中的标签按照功能可以分为以下几类:

  • 表明物品是什么:比如是一只鸟,就会有 “ 鸟”这个词的标签;是豆瓣的首页,就有一个
    标签叫“豆瓣”;是乔布斯的首页,就会有个标签叫“乔布斯”。
  • 表明物品的种类:比如在 Delicious 的书签中,表示一个网页类别的标签包括 article (文章) 、blog (博客)、
    book (图书)等。
  • 表明谁拥有物品:比如很多博客的标签中会包括博客的作者等信息。
  • 表达用户的观点 比如用户认为网页很有趣,就会打上标签 funny (有趣),认为很无聊,就会打上标签 boring (无聊)。
  • 用户相关的标签:比如 my favorite (我最喜欢的)、 my comment (我的评论)等。
  • 用户的任务:比如 to read (即将阅读)、 job search (找工作)等。

4.3 基于标签的推荐系统

如何利用用户的标签数据提高个性化推荐结果的质量是推荐系统研究的重要课题。

用户标签行为数据集:
一个用户标签行为的数据集一般由一个三元组的集合表示,其中记录 (u, i, b) 表示用户 u 给物品 i 打上了标签 b 。
本章为了集中讨论标签数据,只考虑上面定义的三元组形式的数据,即用户的每一次打标签行为都用一个三元组(用户、物品、标签)表示。

4.3.1 实验设置

我们设计了一个实验来验证基于标签的推荐系统的性能。

4.3.2 一个最简单的算法

使用用户标签行为数据我们可以设计一个简单的基于用户标签行为的个性化推荐系统。算法的基本思想如下:

  • 统计每个用户最常用的标签
  • 对于每个标签,统计被打过这个标签次数最多的物品
  • 对于一个用户,首先找到他常用的标签,然后找到具有这些标签的最热门物品推荐给这 个用户。
    对于上面的算法,用户 u 对物品 i 的兴趣公式如下:
    在这里插入图片描述
    这里, B(u) 是用户 u 打过的标签集合, B(i) 是物品 i 被打过的标签集合, n u,b 是用户 u 打过标签 b的次数, n b,i 是物品 i 被打过标签 b 的次数。

下面简单介绍一下SimpleTagBased 标记这个算法。
在 Python 中,我们遵循如下约定:

  • 用 records 存储标签数据的三元组,其中 records[i] = [user, item, tag] ;
  • 用 user_tags 存储 n u,b ,其中 user_tags[u][b] = n u,b ;
  • 用 tag_items 存储 n b,i ,其中 tag_items[b][i] = n b,i 。

下面是程序:
从 records 中统计出 user_tags 和 tag_items。

def InitStat(records):
	user_tags = dict()
	tag_items = dict()
	user_items = dict()
	for user, item, tag in records.items():
		addValueToMat(user_tags, user, tag, 1)
		addValueToMat(tag_items, tag, item, 1)
		addValueToMat(user_items, user, item, 1)

统计出 user_tags 和 tag_items 之后,我们可以通过如下程序对用户进行个性化推荐。

def Recommend(user):
	recommend_items = dict()
	tagged_items = user_items[user]
	for tag, wut in user_tags[user].items():
		for item, wti in tag_items[tag].items():
			#if items have been tagged, do not recommend them
			if item in tagged_items:
				continue
			if item not in recommend_items:
				recommend_items[item] = wut * wti
			else:
				recommend_items[item] += wut * wti
	return recommend_items

4.3.3 算法的改进

上面计算用户对物品兴趣的公式存在很多问题,下面针对这些缺点对上面的算法进行改进。在这里插入图片描述
1.TF-IDF
上述公式的缺点:

  • 上述公式倾向于给热门标签对应的热门物品很大的权重,因此会造成推荐热门的物品给用户,从而降低推荐结果的新颖性。
  • 上述公式利用用户的标签向量对用户兴趣建模,其中每个标签都是用户使用过的标签,而标签的权重是用户使用该标签的次数。这种建模方法的缺点是给热门标签过大的权重,从而不能反应用户个性化的兴趣。
    解决方法1:
    此处借鉴 TF-IDF 的思想,对这一公式进行改进:
    在这里插入图片描述

这里, n b ( u ) 记录了标签 b 被多少个不同的用户使用过。这个算法记为 TagBasedTFIDF
解决方法2:
借鉴 TF-IDF 的思想对热门物品进行惩罚,从而得到如下公式:
在这里插入图片描述

其中, n i ( u ) 记录了物品 i 被多少个不同的用户打过标签。这个算法记为 TagBasedTFIDF++

2.数据稀疏性
前面算法的缺点:
在前面的算法中,用户兴趣和物品的联系是通过 B ( u )  B ( i ) 中的标签建立的。但是,对于新用户或者新物品,这个集合( B ( u )  B ( i ) )中的标签数量会很少。
解决方法:
为了提高推荐的准确率,我们可能要对标签集合做扩展,比如若用户曾经用过“推荐系统”这个标签,我们可以将这个标签的相似标签也加入到用户标签集合中,比如“个性化”、“协同过滤”等标签。
下面介绍一种基于邻域的方法。

标签扩展的本质是对每个标签找到和它相似的标签,也就是计算标签之间的相似度。

  • 最简单的相似度可以是同义词。如果有一个同义词词典,就可以根据这个词典进行标签扩展。
  • 如果没有这个词典,我们可以从数据中统计出标签的相似度

如果认为同一个物品上的不同标签具有某种相似度,那么当两个标签同时出现在很多物品的标签集合中时,我们就可以认为这两个标签具有较大的相似度。
通过如下余弦相似度公式计算标签b和标签b’的相似度:
在这里插入图片描述
在上述公式中,对于标签b,令N(b)为有标签b的物品的集合,n_{b,i}为给物品i打上标签b的用户数。

3.标签清理
前面算法的缺点:
不是所有标签都能反应用户的兴趣。比如:

  • 在一个视频网站中,用户可能对一个视频打了一个表示情绪的标签,比如“不好笑”,但我们不能因此认为用户对“不好笑”有兴趣,并且给用户推荐其他具有“不好笑”这个标签的视频。相反,如果用户对视频打过“成龙”这个标签,我们可以据此认为用户对成龙的电影感兴趣,从而给用户推荐成龙其他的电影。
  • 标签系统里经常出现词形不同、词义相同的标签,比如 recommender system 和recommendation engine就是两个同义词。
  • 标签清理的另一个重要意义在于将标签作为推荐解释。如果我们要把标签呈现给用户,将其作为给用户推荐某一个物品的解释,对标签的质量要求就很高。首先,这些标签不能包含没有意义的停止词或者表示情绪的词,其次这些推荐解释里不能包含很多意义相同的词语。

一般来说有如下标签清理方法:

  • 去除词频很高的停止词;
  • 去除因词根不同造成的同义词,比如 recommender system 和 recommendation system ;
  • 去除因分隔符造成的同义词,比如 collaborative_filtering 和 collaborative-filtering 。

为了控制标签的质量,很多网站也采用了让用户进行反馈的思想,即让用户告诉系统某个标签是否合适。或者融合专家和广大用户的知识。

4.4 给用户推荐标签

当用户浏览某个物品时,标签系统非常希望用户能够给这个物品打上高质量的标签,这样才能促进标签系统的良性循环。因此,很多标签系统都设计了标签推荐模块给用户推荐标签。目的:为了实现高质量的标签。
如下所示为CSDN博客的标签推荐模块。
在这里插入图片描述

4.4.1 为什么要给用户推荐标签

一般认为,给用户推荐标签有以下好处:

  • 方便用户输入标签:让用户从键盘输入标签无疑会增加用户打标签的难度,这样很多用户不愿意给物品打标签,因此我们需要一个辅助工具来减小用户打标签的难度,从而提高用户打标签的参与度
  • 提高标签质量:同一个语义不同的用户可能用不同的词语来表示。这些同义词会使标签的词表变得很庞大,而且会使计算相似度不太准确。而使用推荐标签时,我们可以对词表进行选择,首先保证词表不出现太多的同义词,同时保证出现的词都是一些比较热门的、有代表性的词。

4.4.2 如何给用户推荐标签

比较简单的方法有 4 种。

  1. 给用户 u 推荐整个系统里最热门的标签(该算法称为 PopularTags )。 令 tags[b]为标签 b
    的热门程度,该算法的实现如下:

    sorted(tags.items(), key=itemgetter(1), reverse=True)[0:N] ```
    
  2. 给用户 u 推荐物品 i 上最热门的标签(该算法称为 ItemPopularTags )。 令 item_tags[i][b] 为物品
    i 被打上标签 b 的次数,具体如下所示:

    		return sorted(item_tags[item].items(), key=itemgetter(1),
    reverse=True)[0:N] ```
    
  3. 给用户 u 推荐他自己经常使用的标签(该算法称为 UserPopularTags )。 令 user_tags[u][b] 为用户 u
    使用标签 b 的次数,算法的实现如下所示:

    		return sorted(user_tags[user].items(), key=itemgetter(1),
    reverse=True)[0:N] ```
    
  4. 将前面两种算法进行融合(这里记为 HybridPopularTags ),该方法通过一个系数将上面的
    推荐结果线性加权,然后生成最终的推荐结果。这个算法的实现代码如下:

    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 实验设置

略。

4.4.4 基于图的标签推荐算法

图模型同样可以用于标签推荐。

4.5 扩展阅读

标签在推荐系统中的应用主要集中在两个问题上,一个是如何利用用户打标签的行为给用户推荐物品,另一个是如何给用户推荐标签

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值