載入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) |
|