EasyRec算法框架中包含数据字段、特征,还包含FG特征的概念。这三个概念很容易搞混,因此我们重点介绍一下这些概念和差异。
FG在PAI-Rec、PAI-FeatureStore、EasyRec Processor中的总览
说明:
用户特征(user侧):可以利用FeatureStore(FS)从 PAI-Rec内部得到。
物品特征(item侧):可以利用FeatureStore从EasyRec Processor 服务内部得到。
assemble input:根据请求里面的用户特征和缓存里面的物品特征,装配成fg之前的特征。经过fg 操作之后才对feed给tf 模型打分。
整个链路详解:
在FS内部利用UserView(user侧的FeatureView)和 ItemView(item侧的FeatureView)形成ModelFeature(模型特征),交由Feature Generate(FG)根据fg.json文件形成rank_sample_fg_encoded,再根据easyrec.conf 配置文件到EasyRecProcessor中做模型训练,然后存储model到OSS上,最终feed给tf 模型打分。
注:不利用FS获取特征数据也可以直接去数据源实例上获取。
eg:直连,直接从hologres上获取。
1. EasyRec配置文件中的数据字段和特征字段
1.1. 数据字段配置:data_config
EasyRec中的数据字段说明原始特征的名称和类型,以及缺失值填充方式。类型包括int、double、string等。数据可以是CSV文件,MaxCompute表,Kafka数据流等。
举例:KV tag数据
缺失值填充:默认值填充成一个KV值
离线训练和在线预测:在Tensorflow模型中对缺失值做填充
input_fields: {
input_name: "prop_kv"
input_type: STRING
default_val:"-1024:0"
}
1.2. 特征字段配置:feature_config
在data config中主要是数据和label的定义。而在feature_config中,说明了模型如何解析使用这些数据字段。例如一个字段x作为STRING类型的特征,但是在feature_config中可以按照IdFeature、TagFeature、SequenceFeature、TextCNN来解释。
举例:ID特征
离线训练和在线预测的处理逻辑:在tf模型中把ID特征转化为embedding。
举例:RawFeature
features {
input_names: "ctr"
feature_type: RawFeature
boundaries: [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
embedding_dim: 8
}
预处理:通过离散化得到boundaries,配置到feature_config的features中
离线训练和在线预测:根据boundaries分桶,然后根据桶号hash得到embedding
举例:TagFeature
features : {
input_names: 'tags'
feature_type: TagFeature
separator: '|'
hash_bucket_size: 100000
embedding_dim: 24
}
如文章标签特征tags的值可能是“娱乐|搞笑|热门”,其中|为分隔符。
离线训练和在线预测的处理逻辑:在tf模型中把标签特征分别hash embedding,然后再做average pooling转化为embedding。
2. FG在EasyRec中离线训练和在线预测中相关名词介绍
2.1. 什么是FG
FG是Feature Generate(特征生成)的简称,FG的提出是为了解决离线、在线特征处理的一致性问题的。具体的FG特征包括id_feature、raw_feature、combo_feature、lookup_feature、match_feature、sequence_feature、overlap_feature。我们用的比较多的是lookup_feature和sequence_feature,详情见RTP FG的Feature配置说明。
2.2. FG配置文件
FG包含了多种特征组合和变换方式,以下用LookUp特征为例:
{
"map": "user:tag_brand_list",
"key":"item:brand",
"feature_name": "combo_brand",
"feature_type":"lookup_feature",
"needDiscrete":true,
"hash_bucket_size":100000,
"group":"combo"
}
离线数据处理:需要jar包fg_on_odps-1.3.59-jar-with-dependencies.jar,把物品侧特征brand作为查询key,去用户侧特征tag_brand_list(map结构)查询得到value值,把value作为新特征combo_brand的值。
在线预测处理:
在EasyRec Processor(推荐打分服务)中,内部先执行离线处理过程,然后把combo_brand特征和值 feed到模型中做预测。
3. 常见问题:
3.1. 如何注册天级别离线特征?
我们在建表的时候,会多出来一个分区特征,按天注册离线特征,需在创建表是添加一个字段,这个字段是按照日期来进行分区的,此时日期的最小单位是按天来区分的,在插入数据时也设置该字段为执行操作的当天日期,如此即可实现按天级别注册离线数据特征。
下面这个user表即在创建表时建立了字符串类型的dt分区
CRATE TABLE IF NOT EXITS user
(
user_id BIGINT,
name STRING,
age BIGINT
)
comment '用户' //给当前表加注释
//分区
partitioned by
(
dt STRING
)
LIFECYCLE 90;
3.2. 如何对特征做离散化和分桶?
3.2.1. 离散化训练在哪里执行?
在EasyRec中配置相关的配置类的boundaries参数来进行离散化处理。
例如,在配置FeatureConfig时设置boundaries连续离散化区间如下:
feature_configs: {
input_names: "xxx"
feature_type: XXX
boundaries: [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
embedding_dim: 8
}
即做离散化处理时,其对应的离散化区间是(-inf, 0.1), [0.1, 0.2), [0.2, 0.3), [0.3, 0.4),[0.4, 0.5), [0.5, 0.6), [0.6, 0.7), [0.7, 0.8), [0.8, 0.9), [0.9, 1.0)。
一般情况下,配置了boundaries,一般也要配置embedding_dim(设置高维系数特征映射为低维稠密向量的维度)。
我们可以使用阿里云PAI的binning组件来做分箱。
3.2.2. 线上怎么执行?怎么保证离线和在线的一致性?
对线上特征进行离散化处理也是在EasyRec预测模型内部处理的(即训练的时候把boundaries记录到模型中),参考RawFeature。
3.2.3. 离散化之后特征分桶
对特征分桶即在ID类特征中,user_id,item_id取值数较多,通过hash处理,将id值映射到相对较小的桶中。通过hash_bucket_size参数设置hash_bucket桶的大小。
3.3. 如何对特征做缺失值填充?特征填充在哪里执行?
特征的缺失值填充,在EasyRec的配置template.config文件时,通过给data_config每一个特征字段设置default_value参数来进行缺失值的填充。
具体可见更新EasyRec配置文件文档。
3.4. 如何注册lookup特征?
3.4.1. 什么是lookup特征?
同一个用户user,可能对应多个商品item侧的特征数据,此时我们会统计当前用户在该商品的一个类目特征(按照某个方向分类划分,比对得到当前用户侧对应商品侧的一个具体的类目特征),当前用户的所有商品统计完后,会得到关于一组<K,V>特征,即<类目特征:统计次数>。然后根据当前用户对应某一个具体的item侧的类目去查找对应的V的过程就是lookup,得到的类目特征以及统计次数就是lookup特征。
举个例子:
对于1001用户,统计category类目下的点击次数,得到最终统计得到:[A1:17,B2:13,G1:3,D3:9]。
user_id | item_id | category |
1001 | 2006 | B2 |
现在要计算item_id=2006,Query等于“B2”的时候,lookup的特征值的计算方法如下:对于当前用户1001来说,对item=2006,用category=B2作为Query,去KV= [A1:17,B2:13,G1:3,D3:9],查询得到的特征值是13。
3.5. 如何注册实时特征?
3.5.1. 实时特征如何记录并训练?
注册实时特征,即根据原始数据表通过数据处理得到对应的实时特征,并将当前实时特征存储到线上数据源中。实时特征又可以细分为实时统计特征和实时序列特征。原始数据,我们可以交由Flink实时计算得到实时统计特征,或者利用PAI-Rec处理得到实时序列特征。
实时特征的训练,在实际导入模型之前通过FG对当前的数据做最终的符合模型(FG即可生成当前模型需要的列的信息)的操作,然后导入模型进行训练。
3.6. 什么是离线模拟的实时序列特征?如何注册离线模拟的实时序列特征?
因为在离线情况下,是不可能存在实时性的,这无疑是相互矛盾的。所以离线模拟的实时序列特征,就是在离线情况下,根据当前数据做一定处理(比如:根据某种特征排序),取当前时间节点之前的一组数据即为离线模拟的实时序列特征。
注册离线模拟的实时序列特征,即根据当前的离线特征新建一张离线的表(强调利用partitioned by来新建分区:即按照时间节点来区分),将当前经过某些处理后的离线模拟的实时序列特征数据添加进去就完成注册了。
注:本质上在取当前时间节点之前的一组数据作为离线模拟的实时序列特征,这个一组是有限度的,所以可以理解为随着当前时间节点的不断向前,取到的离线模拟的实时序列特征数据是不断滑动的,形成了一个不断向前滑动的窗口。
3.7. 如何注册实时序列特征?
注册实时序列特征,可利用PAI-Rec引擎处理原始数据表得到相对应的实时序列特征。