第二章 推荐系统中的特征工程
算法工程师的工作是将各种来源、各种形式(比如数值、文本、声音、图像)的原始数据,利用恰当的模型(或简单如逻辑斯谛回归[LR]、梯度提升决策树[GBDT],或复杂如含有几亿个参数的超大深度神经网络[DNN],使输入的数据充分交叉融合,挖掘出有意义的模型,制作出有用的模型,服务用户。
本章将从一下4个方面详细讨论推荐系统中的特征工程。
- 2.1节要强调特征工程对于推荐系统的重要性
- 2.2节梳理出一个提取特征的框架,使提取特征的过程有章可循,提取出的特征不重复、不遗漏
- 2.3节介绍针对数值特征进行清洗、加工的一些方法
- 2.4节讨论推荐系统中的类别特征。
2.1 批判“特征工程过时”的错误论调
目前有一种非常流行的观点“深度学习式特征工程过时”。这种观点的依据是,深度神经网络(Deep Neural Network,DNN)的功能超级强大,是一个“万能函数模拟器”,只要层数足够多,DNN就能够模拟模型的输入与输出之间的的任何复杂的函数关系。
但是这不对,DNN功能没那么牛,有时候连二阶、三阶特征交叉都模拟不好。等等问题。。。
2.2 特征提取
特征工程的第一步是提取特征。前面讲过,提取特征不能随心所欲,否则难免重复或遗漏。本章将梳理出一套特征提取的框架,使我们的特征提取过程有章可循,提取出的特征不重不漏。
在正式开始之前,先用举例的方式介绍两个接下来要遇到的概念:Field(特征域)和Feature(特征)。Field是同一类Feature的集合。例如,“手机品牌”是一个Field,而具体品牌,如苹果、华为、小米等都是这个Field中的Feature。
2.2.1 物料画像
不同场景下需要推荐不同的物品,我们接下来将物品统称为物料(Item)。
1. 物料属性
物料属性是最简单、直接的信息,在物料入库的时候就能够获取到。比如视频推荐场景下,视频的作者、作者等级、作者关注量、投稿栏目、视频标题与间接、上传时间、市场、清晰度等信息都属于物料属性。
值得注意的是,在大型推荐系统中,物料的唯一标识(Item ID)也是重要的特征。Item ID有啥信息呢?举个例子,⽐如, 模型通过学习历史数据, 发现对于⼀个数码爱好者, 只要⼀推“iPhone 13 (A2634) 5G⼿机午夜⾊128GB”这个商品, 点击率和购买率就⾮常⾼。 因此, 那些销量好的商品的Item ID本⾝就是⾮常有⽤的信息, 模型只要把它牢牢记住, 就能取得不错的效果。 其次, Item ID作为⼀个类别特征, 的确是⾼维、 稀疏的, 如果⾮要⽤独热编码(One Hot Encoding)来描述的话, ⼀个长度为⼏⼗万的向量中只有⼀个位置是1, 其他位置都是0。 如果训练数据⽐较少, 的确没必要拿来当特征, 反正也学不出来。 但是对于互联⽹⼤⼚来讲, 最不缺的就是训练数据,这时将Item ID当成特征还是⾮常有必要的,能够在物料侧提供最具个性化的信息。
2. 物料的类别与标签
物料的类别与标签回答的是“物料是什么”的问题,其优点在于,不依赖用户反馈,只通过分析物料内容就能得到。
内容分析的专业性非常强,所使用的算法也与推荐算法有很大不同,因此一般由专门技术、人工团队来负责。在这⾥只做简单的概述, 感兴趣的读者可以找专门资料来了解。 我们可以⽤⾃然语⾔处理算法(⽐如BERT)分析物料的标题、摘要、评论等。 如果是⽂章还可以分析正⽂, 如果是视频还可以分析字幕。我们可以⽤计算机视觉算法(⽐如CNN模型)分析物料的封⾯或者视频的关键帧。
内容分析的结果就构成了物料的静态画像, ⼀般包括以下⼏个⽅⾯。
■⼀级分类:是⼀个Field, ⽐如“体育”“电影”“⾳乐”“历史”等是其中的Feature。
■⼆级分类: ⽐如“体育”又可以细分为“⾜球”“篮球”等⼦类别; “电影”又可以细分为“喜剧⽚”“爱情
⽚”“动作⽚”“动画⽚”等⼦类别。
■标签: 更细粒度地刻画物料的某个⽅⾯。 ⽐如“篮球”类别下又可以包含“NBA”“乔丹”等标签; “动
画⽚”类别下又可以包含“柯南”“哆啦A梦”等标签。 标签没必要从属于某⼀具体类别, ⽐如某个明星的名
字作为标签,既可能打在“电影”类别的⽂章上,也可能打在“⾳乐”类别的⽂章上。
静态画像可以表⽰成⼀个列表(List)。 ⽐如⼀篇娱乐报道可能既属于“电影”类别, 同时也属于“⾳
乐”类别,所以它的⼆级分类Field可以表⽰成[“电影”,“⾳乐”]这样的List。
3. 基于内容的Embedding
⾯说的打标算法往往是利⽤CNN或BERT之类的模型, 从⼀篇⽂章、 ⼀个视频中提炼出⼏个标签,其结果是超级稀疏的。 试想⼀下, 整个标签空间可能有⼏万个标签, ⽽⼀篇⽂章往往只含有其中的两三个。
随着深度学习的发展, 另⼀种从物料内容中提取信息的思路是, 同样还是⽤CNN或BERT模型, 但是拿模型的某⼀层的输出作为物料特征, 喂⼊上层模型。 尽管这个特征向量不如原来那⼏个标签好理解,但是它有32位或64位的长度,其中蕴含的信息要⽐⼏个标签丰富⼀些。
4. 物料的动态画像
物料的动态画像是指物料的后验统计数据,反映了物料的受欢迎程度,是物料侧最重要的特征。
物料的动态画像可以从一下两个维度来进行刻画:
- 时间粒度:全生命周期、过去一周、过去一天、过去1小时。。。
- 统计对象:CTR、平均播放进度、平均消费时长、排名。。。
通过以上两个维度的组合,我们可以构造出一批统计指标作为物料的动态画像,比如:
- 文章A在过去6小时的CTR
- 视频B在过去1天的平均播放时长
- 商品C在过去1个月的销售额
但是:
- 我们需要辩证的看待这些后验统计数据。一方面,它们肯定是有偏差的,一个物料的后验指标好,只能说推荐系统把它推荐给了合适的人,并不意味着把它推荐给任何人都能取得这么好的效果,这里面存在着幸存者偏差。另一方面,如果这些后验指标参与精排,幸存者偏差的影响不会很大,毕竟交给精排模型的物料都已经经过了召回、粗排两个环节的筛选、,或多或少是和当前用户相关的,这些物料的后验指标还是有参考意义的。
- 利⽤这些后验统计数据作为特征,多少有些纵容马太效应,不利于新物料的冷启。后验指标好的物料会被排得更靠前,获得更多曝光与点击的机会,后验指标会更好,形成正向循环;⽽新物料的后验指标不好甚⾄没有,排名靠后⽽较少获得曝光机会,后验指标迟迟得不到改善,形成负向循环。
5. 用户给物料反向打标签
推荐系统构造特征的一般过程是先有物料画像,再将用户消费过的物料的标签累积在用户身上,这样就形成了用户画像。反向打标签则是把以上过程逆转过来,将消费过某个物料的用户身上的标签传递并起累到物料身上,以丰富物料画像。
2.2.2 用户画像
用户画像可以分为静态画像与动态画像两大类。
1. 用户的静态画像
静态画像就是人口属性,比如性别、年龄、职业、籍贯,用户安装的APP列表等比较稳定的数据信息。获得这些信息的难点主要体现在产品设计层面,即如何在守法合规的前提下使用户心甘情愿的分享个人信息。
2. 用户的动态画像
用户的动态画像就是从用户的历史行为中提取出的该用户的兴趣爱好。
最简单直接的动态画像就是将⽤户⼀段时间内交互过的物料的Item ID按时间顺序组成的集合。 将这个集合喂进模型, 让模型⾃动从中提取出⽤户兴趣。 最简单的提取⽅式是将每个Item先映射成Embedding, 再把多个Embedding聚合(也称“池化”, 即Pooling, ⽐如采⽤加和或求平均) 成⼀个向量,这个向量就是⽤ 户兴趣的抽象表达。 更复杂⼀点, 可以像DIN或SIM那样在Pooling时引⼊注意⼒(Attention)机制,根据候选物料的不同, 模型从相同的⾏为序列中提取出相应的⽤户兴趣向量, 实现“千物千⾯”(具体细节将在4.3.3节详细介绍),整个过程如图2-1所⽰。
图2-1 将用户行为序列喂入模型
这种将用户行为序列直接喂给进模型的做法,优点是直接简单,无须进行过多的特征处理;缺点是提取用户兴趣与CTR建模合为一体,都必须在线上完成。另外,这种做法i 提取出来的用户兴趣是抽象的向量,可解释性很弱。
为了克服以上缺点,我们可以将“提取用户兴趣”与“CTR建模”解耦,将提取兴趣的工作从线上转移到线下。通过Hadoop、Spark这样的⼤数据平台,从⽤户⾏为历史中提取各类统计指标来描述⽤户兴趣,并且灌到数据库中。在线预测与训练时,根据User ID从数据库中查询相应指标即可,耗时极短。由于计算主要发⽣在时间充裕的离线环境, 我们在统计⽤户兴趣的时候可以使⽤更复杂的算法,回溯更长的历史,关联更多的数据源。
这种“离线提取、在线查询”的提取方法,其优缺点与在线提取正好相反。
■优点: 线上提取⽤户兴趣只需要⼀个查询操作, 耗时短, ⾮常适⽤于召回、 粗排这种候选集庞⼤的任务。 另外, ⽤户兴趣⽤各种统计指标来表⽰, 相⽐于抽象的向量, 更为简单直⽩, 易于理解, ⽽且也能够为运营、 ⽤户增长等⾮算法团队提供帮助。
■缺点: 提取出的兴趣不会随候选物料的不同⽽改变, 因此针对性不强, ⽆法做到“千物千⾯”。 另外,兴趣提取主要靠离线定时进⾏,不能像在线模式那样及时捕捉到⽤户的兴趣迁移。
至于可以统计哪些指标来反应用户兴趣,我们可以从以下6个维度展开,做到不重不漏。
■⽤户粒度: 可以是单个⽤户, 也可以是⼀群⽤户。 针对⼀个⽤户群体的统计有利于新⽤户的冷启动。
■时间粒度: ⽐如最近的100次曝光,再⽐如过去1⼩时、 1周、 1⽉ 。
■物料属性: ⽐如视频的⼀⼆级类别、标签、作者,再⽐如商品的分类、品牌、店铺、价位。
■动作类型:可以是正向的, ⽐如点击、点赞、转发等,也可以是负向的, ⽐如忽略、点踩。
■统计对象: ⽐如次数、时长、 ⾦额等。
■统计⽅法: ⽐如加和、求平均、计算各种⽐例等。
举个例子:
表2-1 基于6个维度构造用户动态画像的示例
2.2.3 交叉特征
构建交叉特征是提升推荐模型性能的非常重要的手段。近年来,有⼀种说法是,既然DNN能够⾃ 动完成特征交叉,就没必要劳神费⼒地进⾏⼈⼯特征交叉了。 这种说法是⾮常⽚⾯的, ⼀⽅⾯,DNN并⾮万能,其交叉能⼒也有限;另⼀⽅⾯,⼿动交叉的特征犹如加⼯好的⾷材,个中信息更容易被模型吸纳。因此,在推荐模型的深度学习时代,交叉特征依然⼤有可为,值得重视。
在具体交叉方式上,又有笛卡尔积和内积两种方式。
1. 笛卡尔积交叉
笛卡尔积交叉就是将两个Field内的Feature两两组合,组成一个新的Field。比如用户感兴趣的电影类别有{“动作片”,“科幻片”},而当前候选物料的标签是{“施瓦辛格”,“终结者”,“机器人”},这两个Field作笛卡尔积交叉就是{“动作⽚+施⽡⾟格”,“动作⽚+终结者”,“动作⽚+机器⼈”,“科幻⽚+施⽡⾟格”,“科幻⽚+终结者”,“科幻⽚+机器⼈”},显然“动作⽚+施⽡⾟格”“科幻⽚+机器⼈”都是⾮常有⽤的信息, 有助于模型判断⽤户与物料的匹配程度。
2. 内积交叉
选定一个画像维度(比如标签、分类),将用户在这个维度上的兴趣和物料在这个维度上想象成两个系数向量,这两个向量做内积的结果反映出用户和物料在这个画像维度上的匹配程度。内积结果越大,说明用户与候选物料在这个维度上越匹配。
比如用户感兴趣的标签是={“柯南”:0.8,“足球”:0.4,“福尔摩斯”:0.6,“台球”:-0.3},每个标签后面的数字表示用户对这个标签的喜爱程度,可以拿用户在这个标签上的后验指标来表示,具体计算方法可以参考表2-1.而当前候选物料的标签是
=“柯南”:1,“福尔摩斯”:0.5,“狄仁杰”:0.8},将
和
做内积,也就是将共同标签对应的数字相乘再相加,结果是1.1(0.8*1+0.6*0.5),表示用户与当前候选物料在“标签”这个维度上的匹配程度。
【2024/07/30更新】
2.2.4 偏差特征
推荐模型是根据用户的曝光点击记录训练出来的。其中蕴含的假设是,我们认为点击与否反映了用户真实的兴趣爱好,但是严格来讲,以上假设并不成立。具体实践中,我们无法做到让所有候选物料在一个绝对公平的环境中供用户挑选,这也就意味着用户的选择并非完全出于他的兴趣爱好,用户点击的未必是他喜欢的,未点击的也不代表用户就一定不喜欢。这种不可避免引入的不公平因素叫作偏差(Bias)。
推荐系统中最常见的是位置偏差(Position Bias),如图2-2所示:
图2-2 位置偏差示意
图2-2中视频1和视频2都是用户喜欢的,并且占据了靠前的醒目位置。用户注意到了他们,并通过点击给出了正想反馈。视频4是一个体育新闻,其实也是用户喜欢的,如果用户看到了,也一定会点击的。但是由于视频4的曝光位置太偏,落在了用户的视野范围之外,所以未被点击,训练时会被当成负样本,显示用户不喜欢视频4。这就是由位置偏差引发的用户兴趣与反馈的脱节。这种偏差会误导模型,因为模型遇到视频4这个负样本是,并不知道是由于位置太偏造成的,反而会猜测这名用户可能不喜欢“体育”这个类别,未来减少给他推荐“体育”类视频,从而削弱了用户体验。
至于如何解决位置偏差,一种方法是从数据入手,比如更加严格的定义正负样本。有一种Above Click规则规定,只有位于被点击物料上方的未点击物料,才能被纳入训练数据当成负样本,如图2-3所示。
图2-3 Above Click规则⽰意
这里面视频2和4没有被点击,视频3是最下面一条被点击的视频,所以视频2被认为是用户看到了但是没有点击,也就是说明用户确实不喜欢视频2,视频2应该作为一个负样本。而视频4则不然,在最下面一条被点击的视频下面,说明视频4未点击有可能是因为用户没看到,所以就不当作它是一个负样本,不参与模型训练。
另一种解决方法是从模型入手。前面讲到,模型之所以被误导,是因为它不知道这个负样本是由于偏差造成的还是由于其他原因。纠正的方法就是将偏差因素当成特征也喂进模型,使得模型有足够多的信息来给用户反馈找出合理解释。但是这里的问题是,曝光位置在训练时能够得到,但是在线预测时,曝光位置时模型预测的“果”,怎么可能作为“因”喂入模型呢?
这种问题可以称为因果倒置,解决方案是:在预测时,将所有候选物料的曝光位置一律填充为0,也就是假设所欲候选物料都展示在最醒目的位置上,让模型根据其他因素给候选物料打分,并根据得分形成最终真实的展示顺序。像“0号展示位置”这种因为预测时不可得而同意填充的特征值,我们称为伪特征值。
"""
举个例子:假设我们有一个广告推荐系统,在这个系统中,
我们需要预测用户是否会点击推荐的广告。为了提高预测的准确性,
我们在训练阶段使用了广告的曝光位置作为一个特征,因为广告在
页面上的位置会影响用户的点击行为。
用户ID 广告ID 曝光位置 点击 特征1 特征2 ...
1 A 顶部 是 ... ... ...
2 B 底部 否 ... ... ...
3 C 中部 是 ... ... ...
... ... ... ... ... ... ...
在上面这个数据集中,“曝光位置”是一个重要的特征,帮助模型
理解为什么某些广告被点击,而另一些则没有。
"""
在预测阶段,我们需要预测用户是否会点击某个新推荐的广告,
此时,广告的曝光位置上位确定,因此无法直接使用这个特征,
为了应对这个问题,我们引入伪特征值的概念。
预测数据示例
用户ID 广告ID 曝光位置(伪特征值) 特征1 特征2 ...
4 D 0 ... ... ...
4 E 0 ... ... ...
4 F 0 ... ... ...
... ... ... ... ... ...
在这个例子中,所有广告的“曝光位置”都被填充为0,这表示所有广告
都假设展示在最醒目的位置上。
假设我们有DEF三个广告,模型会根据这些广告的特征和伪特征值进行评分。
假设模型得出的分数如下:
广告D:0.8
广告E:0.6
广告F:0.9
根据这些得分,模型会预测用户最可能点击广告F,其次是广告D,
最后是广告E。最终,这些广告的展示顺序会是F、D、E。
到这⾥, 细⼼的读者可能会提出疑问: 为什么在预测时要将所有展⽰位置填成0, 填成1或2不⾏吗?如果不⾏的话, 岂不是选择不同的伪特征值就会使排序结果发⽣变化吗? 那就说明排序过程深受⼀个未知因素的影响。
这就涉及另⼀个重要问题, 就是这个偏差特征应该加在模型的什么位置上? 答案是: 偏差特征只能通过⼀个线性层接⼊模型, ⽽绝不能和其他正常特征⼀起喂⼊DNN, 如图2-4所⽰。 只有这样接⼊,才能保证预测时⽆论伪特征值的取值如何,都不会改变排序结果,这就回答了上述问题。
图2-4 偏差特征智能通过线性层接入模型
简单分析一下原因,按照图2-4所示,最终打分结果由logit模型如公式(2-1)所示
公式(2-1)
该公式中各关键参数:
- DNN是推荐模型的深层网络
- u和t分别表示来自用户与候选物料的真实特征
- w是负责接入偏差特征的线性层的权重向量
- b表示偏差特征向量,在这个例子中只有“展示位置”一个值。训练的时候,b取真实的展示位置。预测的时候,b统一填成某个伪特征值。
如果按照图2-4那样接入偏差特征,排序结果能够满足公式(2-2),即无论“伪特征值”取多少都不影响我们得到真实排序。
公式(2-2)
这里面关键参数:
- DNN是推荐模型的深层网路,w是负责接入偏差特征的线性层的权重向量
- u代表用户的真实特征,t1和t2代表两个候选物料的真实特征
- b1和b2 表示给偏差特征先后使用两个不同的伪特征值
- sort表示排序hanshu
反之,如果将偏差特征和其他真实特征一同喂入DNN,则排序结果:
公式(2-3)
这是因为DNN的高度非线形使得伪特征值与真实特征值产生深度交叉,预测时采用不同的伪特征值将产生完全不同的排序结果。这就使排序结果严重依赖于一个在预测时的未知因素,因此是绝对不可以用的。
除了位置偏差, YouTube还发现视频年龄(当前时间减去上传时间) 也会造成偏差。 推荐模型会⽤视频的各种后验消费指标(⽐如点击率、⼈均观看时长等)来衡量物料的受欢迎程度。 上传早的视频有⾜够长的时间来积累⼈⽓,所以后验指标更好,模型排名更靠前;反之,晚上传的视频还没有积累起⾜够好的后验数据,模型排名靠后,不利于新视频的冷启动。为了纠正这⼀偏差, YouTube在训练时将视频年龄作为偏差特征喂⼊模型, ⽽在预测时统⼀设置成0。
2.3 数值特征的处理
直接把原始数据特征扔进模型,极有可能导致训练不收敛。所以在将数值特征装入模型前必须经过一系列的预处理。常见的预处理包括如下几个方面。
2.3.1 处理缺失值
如果某条样本x中某个实数特征F的取值缺失,最常规的做法就是拿所有样本的在特征F的均值(mean)或中位数(meidan)代替。
2.3.1 标准化
标准化的⽬ 的是将不同量纲、 不同取值范围的数值特征都压缩到同⼀个数值范围内, 使它们具有可⽐性。最常⽤的标准化是z-score标准化,如公式(2-4)所⽰。
(2-4)
参数解释:
- x是某条样本在特征F的原始取值
和
分别是特征F在训练数据集上的均值和标准差。
是某条样本在特征F的标准化结果,称为z-score。
推荐系统中经常会遇到一些长尾分布,比如观看次数,大多数用户一天管看不到100个视频,但是也有个别用户一天要刷1000个视频。这种情况下,直接统计出的和
都会被长尾数据带偏,从而根据公式2-4计算出的z-score区分度下降。
解决方法就是对原始数据进行开放、取对数等非线形变换,先将长尾分布压缩成接机正态分布,再对变换后的数据进行z-score标准化,这样就能取得更好的效果,如图2-5。
图2-5 对长尾分布的数据先压缩成接近正态分布
2.3.3 数据平滑与消偏
推荐系统中经常要计算各种⽐率作为特征, ⽐如点击率、 点赞率、 购买率、 复购率等。 计算这些⽐率时, 我们经常遇到的⼀个问题就是样本太少, 导致计算结果不可信。 ⽐如对于⼀件商品, 只被曝光了⼀次并被购买, 由此我们计算它的购买率是100%, 从⽽认定它是爆款, 应该⼤⼒推荐, 这显然是站不住脚的。 为了克服⼩样本的负⾯影响, 提⾼计算结果的置信⽔平, 我们可以采⽤威尔逊区间平滑, 如公式(2-5)所⽰。
公式(2-5)
该公式中各关键参数的含义如下。
■z是⼀个超参, 代表对应某个置信⽔平的z-score。 ⽐如当我们希望计算结果有95%的置信⽔平时, z应该等于1.96。
■p是⽤简单⽅法计算出的⽐率。 ⽐如当p代表点击率时,就是⽤点击样本数除以曝光样本数。
■ 是平滑后的⽐率。
■n是样本数量。
这里,当n非常大时,趋近于p,这符合统计学中的大数定理和我们的直觉。其他的暂时不写了。
2.3.4 分桶离散化
在推荐模型中,使用类别特征具有能够更好反映非线形关系、便于存储与计算等,因此在实践中,我们倾向于将实数特征离散成类别特征。离散的方法就是分桶,即将实数特征的值域划分为若干区间,这些区间称为桶,看实数特征落进哪个桶,就以那个桶的桶号作为类别特征值。比如,某用户在最近一小时看了5个视频,如果用实数特征描述,特征就是“最近一小时看的视频数”,特征值是5。如果离散成类别特征给你,整个特征可以表示成last1hour_0_10这个字符串,表示该用户在最近一小时看的视频数在0-10之间。至于如何将这个字符串传入模型,等下说。
分桶的方式有3种方式。
- 等宽分桶:将特征值域平均划分为N等分,每份作为一个桶
- 等频分桶:将整个值域的N个分位数(percentile)作为各桶的边界,以保证落入各个桶的样本数大致相等
- 模型分桶:对实数特征F分桶,分为两个阶段。第一阶段,单独拿特征F与目标值拟合出一棵简单的决策树。第二阶段进行分桶,将某个特征中F的实数取值f喂进决策树,f最终落入的那个叶子结点的编号就是f的离散化结果。
2.4 类别特征的处理
推荐算法作为一类特殊的机器学习算法,特点之一就是它的特征空间主要由高维、稀疏的类别特征构成,类别特征是推荐算法的“一等公民”,享受VIP待遇。
2.4.1 类别特征优点
首先,推荐系统系统的基础是用户画像、物料画像。画像中的一二级分类、标签都是类别特征,并且高维(比如一个推荐系统中有几万个标签是常态)、稀疏(比如一篇文章至多包含几万个标签中的几十个)。而且,为了增加推荐结果的个性化成分,互联网大厂都喜欢将User ID、Item ID这种最细粒度的特征加入模型,显然这些特征都是类别特征,并且将特征空间和稀疏性都提高了许多。
其次,推荐模型的输入特征与要拟合的目标之间鲜有线性关系,更多的是量变引起质变。
举例来说, 在电商场景下, 我们希望对⽤户年龄与其购买意愿、 兴趣之间的关系进⾏建模。 我们可以⽤数值特征来描述, 特征是“⽤户年龄”, A⽤户的特征值是20, B⽤户的特征值是40。 “⽤户年龄”在模型中对应⼀个Embedding, 代表它对⽬标的贡献。 使⽤时,将特征值当成权重与特征Embedding相乘, 表⽰对特征的贡献进⾏缩放。 那么在此例中, 年龄对B⽤户购买意愿的影响是对A⽤户的两倍。 这个结论肯定是不成⽴的。
显然, 不同年龄段(少年、青年、中年、⽼年)对购买意愿、兴趣的影响绝⾮呈线性关系, ⽽是拥有各⾃不同的内涵。 所以正确的⽅式应该是将每个年龄段视为独⽴的类别特征, 学习出其⾃⼰的权重或Embedding。 ⽐如A⽤户使⽤的“青年”Embedding在向量空间中可能与⼀些价格适中、 时尚爆款的商品接近, ⽽B⽤户使⽤的“中年”Embedding可能与⼀些经典、 单价⾼的商品接近, 因此⼆者绝⾮向量长度相差⼀倍那样简单。
线上⼯程实现时更偏爱类别特征, 因为推荐系统中的类别特征空间超级稀疏, 可以实现⾮零存储、排零计算, 减少线上开销, 提升在线预测与训练的实时性。 以Logistic Regression(LR)模型为例, 如公式(2-7)所⽰。
使用实数特征: (a)
使用类别特征: (b) (2-7)
参数含义:
- x是一条样本的特征向量,w是LR模型学习出的权重向量,b是偏置项。
- 如果使用实数特征,如公式2-7 a所示,需要进行很多乘法运算
- 如果使用类别特征,如公式2-7 b所示,只需要将非零特征对应的权重相加,省却了乘法运算。而且由于特征空间非常稀疏,一条样本中的非零特征并不多,运算速度更快。
2.4.2 类别特征享受VIP服务
说高维、稀疏的类别特征是一等公民,还因为推荐系统中的很多技术都是为了更好地服务它们而专门设计的,表现在:
第一,单个类别特征的表达能力弱,为了增强其表达能力,业界想出了两个方法。
■通过Embedding⾃动扩展其内涵。⽐如“⽤户年龄在20~ 30岁之间”这个类别特征,既可能反映出⽤户经济实⼒有限, 又可能反映出⽤户审美风格年轻、 时尚。 这⼀系列的潜台词, 术语叫作“隐语义”, 都可以借助Embedding⾃ 动学习出来,扩展了单个特征的内涵。
■ 多特征交叉。 ⽐如单凭“⽤户年龄在20~ 30岁之间”这个特征, 推荐模型可能还猜不透⽤户的喜好。 再与“⼯作”特征交叉, ⽐如“⽤户年龄在20~ 30岁之间、 ⼯作是程序员”, 推荐模型⽴刻就会明⽩,“格⼦衬衫”对该⽤户或许是⼀个不错的选择。
第二,类别特征的维度特别高,几万个标签是常态,再加上实数特征分桶、多维特征交叉,特征空间很容易上亿,如果再把User ID、Item ID也用作特征,特征空间上十亿都不止。解决-- Parameter Server架构 3.3详解。
第三,类别特征空间本来就是稀疏的,实数特征离散化和多特征交叉又进一步提高了特征空间的稀疏程度,从而降低了罕见特征的受训机会,导致模型训练不充分。为了解决这一问题,业界想出了以下办法。
■FTRL这样的优化算法为每维特征⾃ 适应地调节学习率。 常见特征受训机会多, 步长⼩⼀些, 以防⽌因为某个异常样本的梯度⼀下⼦冲过头。 罕见特征受训机会少, 步长可以⼤⼀些, 允许利⽤有限的受训机会快速收敛。
■阿⾥巴巴的DIN为每个特征⾃ 适应地调节正则系数。
■对于第i个特征与第j个特征
的交叉特征的权重
, LR模型只能拿
与
都不为0的样本来训练, 在推荐系统这种特征超级稀疏的环境下, 这样的样本少之又少, 导致交叉特征的权重不能充分训练。 FM解决了这⼀问题, 使只要满⾜
或
的样本都能参与训练 , ⼤⼤提升了训练效率。关于FM的技术细节,我们将在4.2.2节加以详细介绍。
2.4.3 映射
前面列举了推荐系统中的很多类别特征,它们可以是:
- User ID、Item ID、Shop ID、Author ID
- 画像中的类别、标签
- 实数分桶离散化后的结果,比如“用户观看了3~10个视频”
- 交叉结果,比如“用户喜欢军事,候选物料带坦克标签”。
为了便于讲解,以上类别特征的值都是字符串。但是,大家都知道文字是无法作为特征直接喂进模型的,我们必须先将它们数字化。
【2024/07/31更新】
最简单的方法是建立一张字符串道数字的映射表,如图2-6所示。
图2-6 映射类别特征示意图
我们收集常见标签,通过映射表将标签映射成一个整数。映射成的整数对应Embedding矩阵中的行号。通过这种形式,我们为每个标签查询以得到它对应的Embedding向量。接下来就是常规操作了,这些标签的Embedding向量Pooling成一个向量,喂入上层的DNN。
这种方法的最大缺点就是要额外维护一张映射表,但是维护映射表非常难。所以映射表模型用在小型推荐模型中尚可,在大型推荐系统中则需要被下面介绍的特征哈希模式取代。
2.4.4 特征哈希
特征哈希(Feature Hashing,又称Hash Trick [哈希技巧])的方法来映射类别特征,如图2-7所示。
Feature Hashing 负责将输入的字符串映射成一个 [0,N)的整数,N是Embedding矩阵的总行数,映射得到的整数代表该类别特征的Embedding在Embedding矩阵中的行号。 Feature Hashing 可以简单理解为:先计算输入的字符串的哈希值,再拿哈希值对Embedding矩阵行数N取余数。
注意在图2-7中,只要Embedding的长度相同,若干Field可以共享一个特征哈希模块与其背后的Embedding矩阵。相比于让各个Field拥有独立的Embedding矩阵,这种共享方式对空间的利用率更高,是大型推荐模型的主流做法。
在这里有一个哈希冲突的问题,也就是特征哈希将两个不同的特征映射到Embedding矩阵的统一行,从而在训练与预测时被混淆,相互干扰。这种情况不可避免,但是问题也不大。