加载user或者item特征的配置介绍。
特征的配置对应配置总览中的 FeatureConfs,FeatureConfs 是一个 Map[string]object 结构,其中 key 为场景名,可以根据不同场景配置不同的特征
特征加载
在精排之前,需要从特征存储源里获取到 user 或者 item 的特征数据。
在某些情况下,获取到的特征数据还需要进一步处理,比如根据已有的特征生成新的特征,根据现有特征进行组合等,都是支持的。
特征的加载支持多个数据源 hologres、redis、ots(tablestore)、PAI-FeatureStore 。
Hologres
配置示例
{
"FeatureConfs": {
"scene_name": {
"AsynLoadFeature": true,
"FeatureLoadConfs": [
{
"FeatureDaoConf": {
"AdapterType": "hologres",
"HologresName": "holo-pai",
"FeatureKey": "user:uid",
"UserFeatureKeyName": "user_id",
"HologresTableName": "recom_user_features_processed_holo_online",
"UserSelectFields": "rids_count,sex,alladdfriendnum,allpayrosenum",
"FeatureStore": "user"
},
"Features": []
},
{
"FeatureDaoConf": {
"AdapterType": "hologres",
"HologresName": "holo-pai",
"ItemFeatureKeyName": "item_id",
"FeatureKey": "item:id",
"HologresTableName": "recom_user_features_processed_holo_online",
"ItemSelectFields": "rids_count as rids2_count,sex as guestsex,alladdfriendnum as alladdfriendnum2",
"FeatureStore": "item"
},
"Features": []
}
]
}
}
}AsynLoadFeature: 是否异步的加载特征,当有多个 FeatureLoadConfs 时,可以异步并发的进行加载
FeatureLoadConfs/FeatureDaoConf
字段名 | 类型 | 是否必填 | 描述 |
AdapterType | string | 是 | 数据源的类型,取值为 hologres |
HologresName | string | 是 | 在数据源配置(HologresConfs)中配置好的 holo 的自定义名称,如数据源配置中的 holo_info |
FeatureKey | string | 是 | 根据引擎中哪个特征,去特征表里进行查询。 FeatureKey 标明查找的值来自于 user 或者 item 的哪个字段。比如,user:uid 获取 user 的 uid 属性值,item:id 获取 item 的 id 的属性值。 |
UserFeatureKeyName | string | 是 | user 特征表的主键字段 |
ItemFeatureKeyName | string | 是 | item 特征表的主键字段 |
HologresTableName | string | 是 | holo 中特征表的表名 |
UserSelectFields | string | 否 | 需要获取的 user 特征,支持"*",表明获取所有,也可以 "feature1,feature2" |
ItemSelectFields | string | 否 | 需要获取的 item 特征,支持"*",表明获取所有,也可以 "feature1,feature2" |
FeatureStore | string | 是 | 枚举值:user/item。表示特征获取到之后,存储到哪里 |
CacheSize | integer | 否 | 本地缓存特征条目的数量,默认为0,说明不会缓存数据。 |
CacheTime | integer | 否 | 本地缓存特征条目的过期时间,单位为秒。只有 CacheSize > 0 开启cache时才会有效。默认值为3600。 |
PAI-FeatureStore
PAI-FeatureStore 平台的使用配置参考FeatureStore概述。
配置示例
{
"FeatureConfs": {
"scene_name": {
"AsynLoadFeature": true,
"FeatureLoadConfs": [
{
"FeatureDaoConf": {
"AdapterType": "featurestore",
"FeatureStoreName": "pairec-fs",
"FeatureKey": "user:uid",
"FeatureStoreModelName": "rank_v1",
"FeatureStoreEntityName": "user",
"FeatureStore": "user"
}
}
]
}
}
}FeatureLoadConfs/FeatureDaoConf
字段名 | 类型 | 是否必填 | 描述 |
AdapterType | string | 是 | 数据源的类型,取值为 featurestore |
FeatureStoreName | string | 是 | 在数据源配置(FeatureStoreConfs)中配置好的 featurestore 的自定义名称,如数据源配置中的 pairec-fs |
FeatureKey | string | 是 | 根据引擎中哪个特征,去特征表里进行查询。 FeatureKey 标明查找的值来自于 user 或者 item 的哪个字段。比如,user:uid 获取 user 的 uid 属性值,item:id 获取 item 的 id 的属性值。 |
FeatureStoreModelName | string | 是 | 特征平台(feature store)中的 modelfeature name |
FeatureStoreEntityName | string | 是 | 特征平台(feature store)中的 entity name |
FeatureStore | string | 是 | 枚举值:user/item。表示特征获取到之后,存储到哪里 |
CacheSize | integer | 否 | 本地缓存特征条目的数量,默认为0,说明不会缓存数据。 |
CacheTime | integer | 否 | 本地缓存特征条目的过期时间,单位为秒。只有 CacheSize > 0 开启cache时才会有效。默认值为3600。 |
上述配置是从模型特征 rank_v1 获取 user entity 的全部特征。如果要获取 item entity 的特征,可以配置如下:
{
"FeatureConfs" :{
"scene_name": {
"AsynLoadFeature": true,
"FeatureLoadConfs": [{
"FeatureDaoConf": {
"AdapterType": "featurestore",
"FeatureStoreName": "pairec-fs",
"FeatureKey": "item:id",
"FeatureStoreModelName": "rank_v1",
"FeatureStoreEntityName": "item",
"FeatureStore": "item"
}
}]
}
}
}但很多时候,我们只是需要获取某个 featureview 下的部分特征。比如获取 featureview 名为 user_table_preprocess_all_feature_v1 下的所有特征,放入 user 属性里。可以如下配置:
{
"FeatureConfs" :{
"scene_name": {
"AsynLoadFeature": true,
"FeatureLoadConfs": [{
"FeatureDaoConf": {
"AdapterType": "featurestore",
"FeatureStoreName": "pairec-fs",
"FeatureKey": "user:uid",
"FeatureStoreViewName": "user_table_preprocess_all_feature_v1",
"UserSelectFields": "*",
"FeatureStore": "user"
}
},
{
"FeatureDaoConf": {
"AdapterType": "featurestore",
"FeatureStoreName": "pairec-fs",
"FeatureKey": "item:id",
"FeatureStoreViewName": "item_table_preprocess_all_feature_v1",
"ItemSelectFields": "author,duration,category",
"FeatureStore": "item"
}
}]
}
}
}字段名 | 类型 | 是否必填 | 描述 |
FeatureStoreViewName | string | 是 | featureview 名称 |
UserSelectFields | string | 否 | 需要获取的 user 特征,支持"*",表明获取所有,也可以 "feature1,feature2" |
ItemSelectFields | string | 否 | 需要获取的 item 特征,支持"*",表明获取所有,也可以 "feature1,feature2" |
TableStore(OTS)
配置示例
{
"FeatureConfs": {
"scene_name": {
"AsynLoadFeature": true,
"FeatureLoadConfs": [
{
"FeatureDaoConf": {
"AdapterType": "tablestore",
"TableStoreName": "tablestore_info",
"FeatureKey": "user:uid",
"UserFeatureKeyName": "uid",
"TableStoreTableName": "",
"UserSelectFields": "*",
"FeatureStore": "user"
},
"Features": []
},
{
"FeatureDaoConf": {
"AdapterType": "tablestore",
"TableStoreName": "tablestore_info",
"FeatureKey": "item:id",
"ItemFeatureKeyName": "item_id",
"TableStoreTableName": "",
"ItemSelectFields": "*",
"FeatureStore": "item"
},
"Features": []
}
]
}
}
}FeatureLoadConfs/FeatureDaoConf
字段名 | 类型 | 是否必填 | 描述 |
AdapterType | string | 是 | 数据源的类型,取值为 tablestore |
TableStoreName | string | 是 | 在数据源配置(TableStoreConfs)中配置好的 tablestore 的自定义名称,如数据源配置中的 tablestore_info |
FeatureKey | string | 是 | 根据引擎中哪个特征,去特征表里进行查询。 FeatureKey 标明查找的值来自于 user 或者 item 的哪个字段。比如,user:uid 获取 user 的 uid 属性值,item:pair_id 获取 item 的 pair_id 的属性值。 |
UserFeatureKeyName | string | 否 | user 特征表的主键字段 |
ItemFeatureKeyName | string | 否 | item 特征表的主键字段 |
TableStoreTableName | string | 是 | tablestore 中特征表的表名 |
UserSelectFields | string | 否 | 需要获取的 user 特征,支持"*",表明获取所有,也可以 "feature1,feature2" |
ItemSelectFields | string | 否 | 需要获取的 item 特征,支持"*",表明获取所有,也可以 "feature1,feature2" |
FeatureStore | string | 是 | 枚举值:user/item。表示特征获取到之后,存储到哪里 |
CacheSize | integer | 否 | 本地缓存特征条目的数量,默认为0,说明不会缓存数据。 |
CacheTime | integer | 否 | 本地缓存特征条目的过期时间,单位为秒。只有 CacheSize > 0 开启cache时才会有效。默认值为3600。 |
Redis
在Redis中存储数据比较灵活,可以通过KV形式的存储,V 可以是CSV格式,也可以是JSON格式。也可以通过HASH的方式存储,可以通过指定字段名称获取全部或者部分数据。
配置示例
{
"FeatureConfs": {
"scene_name": {
"AsynLoadFeature": true,
"FeatureLoadConfs": [
{
"FeatureDaoConf": {
"AdapterType": "redis",
"RedisName": "user_redis",
"RedisPrefix": "UF_V2_",
"FeatureKey": "user:uid",
"FeatureStore": "user",
"RedisDataType": "string",
"RedisFieldType": "csv",
"RedisValueDelimeter": ","
},
"Features": []
},
{
"FeatureDaoConf": {
"AdapterType": "redis",
"RedisName": "item_redis",
"RedisPrefix": "IF_V2_FM_",
"FeatureKey": "item:id",
"FeatureStore": "item",
"RedisDataType": "string",
"RedisFieldType": "json"
},
"Features": [ ]
}
]
}
}
}上面的例子中,user特征是通过KV的形式获取,并且使用csv的方式进行存储,存储用的分隔符是由RedisValueDelimeter指定的。item的特征也是KV的形式,不过是使用json方式进行存储的。
再来看下如何用HASH的方式获取特征数据。
{
"FeatureConfs": {
"scene_name": {
"AsynLoadFeature": true,
"FeatureLoadConfs": [
{
"FeatureDaoConf": {
"AdapterType": "redis",
"RedisName": "user_redis",
"RedisPrefix": "UF_V2_",
"FeatureKey": "user:uid",
"FeatureStore": "user",
"RedisDataType": "hash",
"UserSelectFields": "*"
},
"Features": []
},
{
"FeatureDaoConf": {
"AdapterType": "redis",
"RedisName": "item_redis",
"RedisPrefix": "IF_V2_FM_",
"FeatureKey": "item:id",
"FeatureStore": "item",
"RedisDataType": "hash",
"ItemSelectFields": "city,author,duration"
},
"Features": []
}
]
}
}
}FeatureLoadConfs/FeatureDaoConf
字段名 | 类型 | 是否必填 | 描述 |
AdapterType | string | 是 | 数据源的类型,取值为 redis |
RedisName | string | 是 | 在数据源配置(RedisConfs)中配置好的 redis 的自定义名称,如数据源配置中的 redis_info |
RedisPrefix | string | 是 | key 前缀 |
FeatureKey | string | 是 | 根据引擎中哪个特征,去特征表里进行查询。 FeatureKey 标明查找的值来自于 user 或者 item 的哪个字段。比如,user:uid 获取 user 的 uid 属性值,item:pair_id 获取 item 的 pair_id 的属性值。 |
UserSelectFields | string | 否 | 需要获取的 user 特征,支持"*",表明获取所有,也可以 "feature1,feature2"。当RedisDataType=hash时有效。 |
ItemSelectFields | string | 否 | 需要获取的 item 特征,支持"*",表明获取所有,也可以 "feature1,feature2"。当RedisDataType=hash时有效。 |
FeatureStore | string | 是 | 枚举值:user/item。表示特征获取到之后,存储到哪里 |
RedisDataType | string | 是 | 数据的存储形式,1. string 代表KV 2. hash 代表 HASH |
RedisFieldType | string | 否 | 有效值为csv或者json。当RedisDataType=string时有效。 |
RedisValueDelimeter | string | 否 | 数据的分隔符,当RedisFieldType=csv时有效。 |
CacheSize | integer | 否 | 本地缓存特征条目的数量,默认为0,说明不会缓存数据。 |
CacheTime | integer | 否 | 本地缓存特征条目的过期时间,单位为秒。只有 CacheSize > 0 开启cache时才会有效。默认值为3600。 |
特征转化
加载特征后,有些情况下还需要进一步处理特征,进行特征的变换或者生成新特征。引擎已经内置了几种特征变换类型。下面介绍说明下。
FeatureType(特征变化类型) | 说明 |
new_feature | 生成全新的特征 |
raw_feature | 根据已有的特征,生成一个新的特征名称。 |
compose_feature | 组合特征,通过已有多个特征,组合在一起生成新的特征 |
new_feature
user侧特征经常会用到 day_h,week_day 两个特征, 这两个特征是实时生成的。
{
"FeatureType": "new_feature",
"FeatureName": "day_h",
"Normalizer": "hour_in_day",
"FeatureStore": "user"
}{
"FeatureType": "new_feature",
"FeatureName": "week_day",
"Normalizer": "weekday",
"FeatureStore": "user"
}FeatureName 生成的特征名称
FeatureStore 表示特征存放到user侧,还是item侧,可选值为 user/item
生成随机数, 有些时候会用到随机数进行概率判断。 下面会生成 rand_int_v 特征,区间在 [0 - 100)
{
"FeatureType": "new_feature",
"FeatureName": "rand_int_v",
"Normalizer": "random",
"FeatureStore": "user"
}生成固定值, 生成 alg 特征名称,值为 ALRC
{
"FeatureType": "new_feature",
"FeatureStore": "user",
"Normalizer": "const_value",
"FeatureValue": "ALRC",
"FeatureName": "alg"
}根据表达式生成特征,使用 https://github.com/Knetic/govaluate 库解释执行表达式。
下面生成了 bool 的特征, is_retarget, 通过判断 recall_name 是否在数组中。 bool 的特征的值,实际用 1 或 0 表示。
{
"FeatureType": "new_feature",
"FeatureStore": "item",
"FeatureSource": "item:recall_name",
"Normalizer": "expression",
"Expression": "recall_name in ('retarget_u2i','realtime_retarget_click')",
"FeatureName": "is_retarget"
}Expression 表达式, 表达式规则,可以参考 https://github.com/Knetic/govaluate/blob/master/MANUAL.md。
FeatureSource 表示特征值来源于哪里, item:recall_name, 说明来源于 item 的 recall_name 特征。如果 Expression 中有多个 item 的属性值,FeatureSource 可以不设置,会把 item 的所有属性值传入到 Expression 进行计算。
可以使用currentTime指当前的系统Unix时间戳,单位秒。
根据表达式生成特征的V2版本,语法更灵活,性能更好。使用 https://github.com/expr-lang/expr 库解释执行表达式。使用表达式的话,更推荐用这种方式。
上面的表达式可以改写成
{
"FeatureType": "new_feature",
"FeatureStore": "item",
"Normalizer": "expr",
"Expression": "item.recall_name in ['retarget_u2i','realtime_retarget_click']",
"FeatureName": "is_retarget"
}Expression 表达式, 表达式规则,可以参考 https://expr-lang.org/docs/language-definition 。
如果是item侧特征,可以加item前缀,如果是user侧特征,可以加user前缀。item.recall_name 指的是item侧的recall_name特征。当FeatureStore=item时,表达式里也可以引用user侧特征。
可以使用currentTime指当前的系统Unix时间戳,单位秒。
如果同时使用user侧特征和item侧特征,可以参考如下
{
"FeatureType": "new_feature",
"FeatureStore": "item",
"Normalizer": "expr",
"Expression": "user.user_index - item.index",
"FeatureName": "index_delta"
}raw_feature
根据已有特征进行转化
{
"FeatureType": "raw_feature",
"FeatureStore": "user",
"FeatureSource": "user:age",
"RemoveFeatureSource": true,
"FeatureName": "age_v2"
}这里代表根据 user 中的 age 特征,生成一个 age_v2 的特征,把 age 特征值赋予给 age_v2,RemoveFeatureSource 参数决定要不要将原特征(age)删除掉
user:age 使用的是user侧的特征,如果是item:city,则说明是item侧的特征。
compose_feature
生成组合特征
{
"FeatureType": "compose_feature",
"FeatureStore": "item",
"FeatureSource": "user:category,item:author",
"FeatureName": "item_author"
}FeatureSource 里可以引用多个特征,如果是user侧的,加上
user:前缀,如果是item侧的,加上item:前缀。会生成新特征item_author,多个特征之间用
_连接起来。比如上面的user:category值是category1,item:author的值是author1,那么生成的item_author是 category1_author1。像这种组合特征,可以用上面的new_feature的第5种方式,更灵活地实现。
内置表达式函数
在上文的new_feature的介绍中,第4、5种方法都是以表达式的形式来生成新特征。引擎也内置了下面的自定义函数可以在表达式中直接使用。
函数名称 | 函数签名 | 说明 |
getString | getString(a, b) | 如果a 不是空值,返回a,否则返回b |
trim | trim(str, cutset) | 如果str的前后缀里包含cutset字符,全部移除 |
trimPrefix | trimPrefix(str, cutset) | 移除str的前缀包含cutset字符 |
replace | replace(str, old, new) | 把str中的old的字符串替换为new字符串 |
round | round(number) round(number, places) |
|
hash32 | hash32(str) | hash算法,使用murmur3.Sum32 |
log | log(number) | 计算一个数的自然对数 (以 e 为底 |
log10 | log10(number) | 计算一个数的常用对数(以 10 为底) |
log2 | log2(number) | 计算一个数的二进制对数(以 2 为底) |
pow | pow(base, exponent) | 计算一个数的幂 |
s2CellID | s2CellID(lat,lng) s2CellID(lat, lng, level) |
|
s2CellNeighbors | s2CellNeighbors(lat,lng) s2CellNeighbors(lat,lng, level) |
|
geoHash | geoHash(lat, lng) geoHash(lat, lng, precision) |
|
geoHashWithNeighbors | geoHashWithNeighbors(lat,lng) geoHashWithNeighbors(lat, lng, precision) |
|
haversine | haversine(lng1, lat1, lng2, lat2) |
|
sphereDistance | sphereDistance(lng1, lat1, lng2, lat2) |
|