全部產品
Search
文件中心

Artificial Intelligence Recommendation:特徵產生概述和配置

更新時間:Jan 15, 2026

特徵產生(FeatureGenerator,下文簡稱FG)是一套把原始輸入轉換為模型所需輸入(特徵)的資料變換過程,用來保證離線、線上樣本產生結果的一致性。特徵產生也可以理解為特徵變換,對單個特徵或者多個特徵做變換。我們提供了各種類型的FG來完成各種特徵變換操作。

特徵產生只關注同時需要在離線和線上樣本產生過程中的變換操作。如果某個變換操作只需要作用在離線階段,則不需要定義為FG的操作。 FG模組在推薦系統架構中的位置如下圖所示:

image

特徵產生過程由一系列特徵變換運算元(下文簡稱為FG運算元)按照設定檔定義的DAG圖的拓撲順序並存執行。

設定檔樣本

features列表配置特徵運算元,每個特徵運算元必須包含feature_namefeature_type兩項,其餘配置項請參見內建特徵運算元

配置項reserves指定離線任務中透傳出的欄位,這些欄位會原樣輸出,不會做特徵變換。

{
  "features": [
    {
      "feature_name": "goods_id",
      "feature_type": "id_feature",
      "value_type": "string",
      "expression": "item:goods_id",
      "default_value": "-1024",
      "need_prefix": false
    },
    {
      "feature_name": "color_pair",
      "feature_type": "combo_feature",
      "value_type": "string",
      "expression": ["user:query_color", "item:color"],
      "default_value": "",
      "need_prefix": false
    },
    {
      "feature_name": "current_price",
      "feature_type": "raw_feature",
      "value_type": "double",
      "expression": "item:current_price",
      "default_value": "0",
      "need_prefix": false
    }, 
    {
      "feature_name": "usr_cate1_clk_cnt_1d",
      "feature_type": "lookup_feature",
      "map": "user:usr_cate1_clk_cnt_1d",
      "key": "item:cate1",
      "need_discrete": false,
      "need_key": false,
      "default_value": "0",
      "combiner": "max",
      "need_prefix": false,
      "value_type": "double"
    },
    {
      "feature_name": "recommend_match",
      "feature_type": "overlap_feature",
      "method": "is_contain",
      "query": "user:query_recommend",
      "title": "item:recommend",
      "default_value": "0"
    },
    {
      "feature_name": "norm_title",
      "feature_type": "text_normalizer",
      "expression": "item:title",
      "max_length": 512,
      "parameter": 0,
      "remove_space": false,
      "is_gbk_input": false,
      "is_gbk_output": false
    },
    {
      "feature_name": "title_terms",
      "feature_type": "tokenize_feature",
      "expression": "feature:norm_title",
      "default_value": "",
      "vocab_file": "tokenizer.json",
      "output_type": "word_id",
      "output_delim": ","
    },
    {
      "feature_name": "query_title_match_ratio",
      "feature_type": "overlap_feature",
      "method": "query_common_ratio",
      "query": "user:query_terms",
      "title": "feature:title_terms",
      "default_value": "0"
    },
    {
      "feature_name": "title_term_match_ratio",
      "feature_type": "overlap_feature",
      "method": "title_common_ratio",
      "query": "user:query_terms",
      "title": "feature:title_terms",
      "default_value": "0"
    },
    {
      "feature_name": "term_proximity_min_cover",
      "feature_type": "overlap_feature",
      "method": "proximity_min_cover",
      "query": "user:query_terms",
      "title": "feature:title_terms",
      "default_value": "0"
    }
  ],
  "input_alias": {
    "non_exist_field1": "exist_field1",
    "non_exist_field2": "exist_field2"
  },
  "reserves": [
    "request_id",
    "user_id",
    "is_click",
    "is_pay",
    "sample_weight",
    "event_unix_time"
  ]
}

特殊配置項input_alias:配置特徵輸入名映射字典,把一個可能不存在的輸入欄位名映射到一個實際存在的欄位名;(input_alias配置從1.0.0版本才開始支援,通常可跳過該用法)

  • 用途1:為較長的欄位名稱設定更簡短的別名

  • 用途2:當一個自訂特徵運算元使用兩個相同的參數,為第二個參數設定別名。

同一個輸入欄位可以在不同特徵間複用,但不能在單一特徵變換內複用;配置input_alias可繞過這一限制。

  • 例如,某自訂特徵運算元有兩個輸入參數都需要同一個欄位A,此時可以配置AB兩個輸入,同時配置一個input_alias映射"B": "A"。在真正執行的時候會把自訂特徵運算元的參數從(A,B)替換為(A,A)。

輸入欄位

輸入欄位表示當前輸入來自哪個實體,目前支援以下4種類型:

  • user:使用者側特徵,包括user profile、user維度統計特徵等。

  • context:上下文特徵,時間、地點、天氣等隨時變化的特徵。

  • item:物品側特徵,包括靜態內容特徵、item維度統計特徵等。

  • feature:表示當前輸入是另一個特徵變換的輸出。

其中,feature輸入欄位比較特殊,通過該輸入欄位配置特徵運算元之間的依賴關係。從整體來看,所有特徵運算元構成一個有向非循環圖(DAG),架構會按照拓撲順序來並存執行這些特徵變換操作。對應的拓撲結構如下:

image

一般情況下,DAG的中間節點的輸出不會作為FG的輸出。可以用特徵配置項stub_type來改變這一行為。

多實值型別及分隔字元

FG支援複雜類型的輸入,如Array、Map等,與MaxCompute的複雜類型一致。

字串類型的多值特徵可以使用chr(29)分隔字元。

例如v1^]v2^]v3^]表示多值分隔字元,這是⼀個符號,其ASCII編碼是"\x1D",不是兩個符號。該字元在emacs中的輸⼊⽅式是C-q C-5,在vi中的輸⼊⽅式是C-v C-5。

特徵分箱(離散化)

架構支援如下6種類型的分箱操作:

  • hash_bucket_size:對特徵變換結果進行hash和模數。

  • vocab_list:把特徵變換結果轉化為列表的索引。

  • vocab_dict:把特徵變換結果轉化為字典的值(必須可轉化為int64類型)。

  • vocab_file: 從檔案讀入vocab_list或vocab_dict。

  • boundaries:指定分箱邊界,把特徵變換結果轉化為對應的桶號。

  • num_buckets:直接使用特徵變換結果作為分箱桶號。

hash_bucket_size

對特徵變換結果進行hash和模數,適用於任意類型的特徵值。

  • 結果範圍:[0,hash_bucket_size)

  • 空的特徵分箱結果為hash(default_value)%hash_bucket_size

{
  "hash_bucket_size": 128000,
  "default_value": "預設值"
}

vocab_list

根據詞彙表分箱,把輸入映射到詞彙表的索引;分箱結果為特徵值對應的vocab_list數組的索引。

  • vocab_list數組的元素類型需要與value_type的配置相同

  • num_oov_bucket: Non-negative integer, the number of out-of-vocabulary buckets.

    • All out-of-vocabulary inputs will be assigned IDs in the range [vocabulary_size, vocabulary_size+num_oov_buckets) based on a hash of the input value.

    • A positive num_oov_buckets can not be specified withdefault_bucketize_value.

  • default_bucketize_value: The integer ID value to return for out-of-vocabulary feature values.

    • This can not be specified with a positivenum_oov_buckets.

    • 預設值為vocab_list.size()

{
  "vocab_list": [
    "",
    "<OOV>",
    "token1",
    "token2",
    "token3",
    "token4"
  ],
  "num_oov_bucket": 0,
  "default_bucketize_value": 1
}

vocab_dict

分箱結果為特徵值對應的vocab_dict字典的值,支援不同的特徵值對應到相同的分箱結果。

  • vocab_dict字典的鍵的類型需要與value_type的配置相同

  • 要求vocab_dict的值必須能夠轉換為int64類型

  • num_oov_bucket: Non-negative integer, the number of out-of-vocabulary buckets.

    • All out-of-vocabulary inputs will be assigned IDs in the range [vocabulary_size, vocabulary_size+num_oov_buckets) based on a hash of the input value.

    • A positive num_oov_buckets can not be specified withdefault_bucketize_value.

  • default_bucketize_value: The integer ID value to return for out-of-vocabulary feature values.

    • This can not be specified with a positivenum_oov_buckets.

    • 預設值為vocab_dict.size()

{
  "vocab_dict": {
    "token1": 1,
    "token2": 2,
    "token3": 3,
    "token4": 1
  },
  "num_oov_bucket": 0,
  "default_bucketize_value": 4
}

vocab_file

從檔案讀入vocab_list或vocab_dict

{
  "vocab_file": "vocab.txt",
  "num_oov_bucket": 0,
  "default_bucketize_value": 4
}
  • vocab_file: 檔案路徑,檔案內容是詞彙表,每行一個詞彙,支援指定映射值(可選);

    • 支援相對路徑;部署線服務時,需要與fg.json放置在同一個目錄下

    • 只有token時,映射為行號(從0開始);有value時,token-value之間用空白符(空格或Tab)分割;value必須為int64類型

  • num_oov_bucket 與 default_bucketize_value 的含義同上文

boundaries

對數值型特徵安裝指定的分箱邊界分箱。 Represents discretized dense input bucketed by boundaries.

  • boundaries數組的元素類型需要與value_type的配置相同。

  • Buckets include the left boundary, and exclude the right boundary.

  • Namely, boundaries=[0., 1., 2.] generates buckets (-inf, 0.), [0., 1.), [1., 2.), and [2., +inf).

{
  "boundaries": [0.0, 1.0, 2.0],
  "default_value": -1
}

num_buckets

直接使用特徵變換結果作為分箱桶號,適用於特徵值可以轉換為整數的情況。

  • 結果範圍:[0,num_buckets)

  • 如果特徵值超出配置的範圍,則賦值為default_bucketize_value

{
  "num_buckets": 128000,
  "default_bucketize_value": 127999
}

內建特徵運算元

每個特徵運算元的配置方法不同,所有能夠作為DAG葉子節點的特徵運算元都支援配置特徵分箱。

更多資訊,請參見內建特徵運算元

特徵類型

說明

id_feature

類型特徵

raw_feature

數值型特徵

expr_feature

運算式特徵

combo_feature

組合特徵

lookup_feature

字典查詢特徵

match_feature

主從鍵字典查詢特徵

overlap_feature

交疊特徵

sequence_feature

序列特徵

text_normalizer

文本歸一化

tokenize_feature

文本分詞特徵

bm25_feature

BM25文本相關性特徵

kv_dot_product

kv向量內積

str_replace_feature

字串替換

regex_replace_feature

Regex替換

slice_feature

數組切片

運算元組合使用

通過配置DAG圖的方式,組合使用各種內建運算元可以發揮強大的特徵變換能力。

案例1:求一個序列前4個元素的平均值

{
  "features": [
    {
      "feature_name": "top_n_prices",
      "feature_type": "sequence_raw_feature",
      "expression": "user:clk_prices",
      "separator": ",",
      "sequence_length": 4,
      "stub_type": true
    },
    {
      "feature_name": "top_n_avg_price",
      "feature_type": "expr_feature",
      "expression":"reduce_mean(top_n_prices)",
      "default_value": "-1",
      "variables":["feature:top_n_prices"]
    }
  ]
}

案例2:求一個序列中滿足條件的元素的平均值

{
  "features": [
    {
      "feature_name": "valid_list",
      "feature_type": "expr_feature",
      "expression":"clk_times < 10",
      "variables":["user:clk_times"],
      "value_dimension": 5
    },
    {
      "feature_name": "top_n_prices",
      "feature_type": "bool_mask_feature",
      "expression": ["user:clk_prices", "feature:valid_list"],
      "value_type": "float",
      "separator": ","
    },
    {
      "feature_name": "top_n_avg_price",
      "feature_type": "expr_feature",
      "expression":"reduce_mean(top_n_prices)",
      "default_value": "-1",
      "variables":["feature:top_n_prices"]
    }
  ]
}

備忘:上述案例中,clk_pricesclk_times是兩個平行序列。

自訂特徵運算元

自訂特徵運算元能夠以外掛程式的形式被架構動態載入並執行。

更多資訊,請參見自訂特徵運算元

效能最佳化經驗

FG模組的效能跟FG的配置有很大的關係,總的原則是盡量減少“不必要的”資料(特徵)變換

如果能在離線、近線階段做好的資料加工、變換就不要放在FG階段(線上服務)中做

遵循以下注意事項可獲得更佳的效能。

  • 輸入的結構化資料優先使用MaxCompute表的複雜類型(e.g. Map、Array等),而不是STRING類型。減少字串解析的開銷。

    • 線上服務(EasyRec Processor/TorchEasyRec Processor)中使用FeatureStore,並使用特徵資料庫FeatureDB作為線上儲存,以便開啟對複雜類型的支援

    • lookup_feature 的 map 欄位強烈推薦使用 Map 類型;

    • sequence_feature、overlap_feature、bm25_feature 強烈推薦使用 Array 類型的輸入;

    • 盡量避免使用 match_feature(不支援複雜類型),使用 lookup_feature 來代替(組合 pkey & skey);

  • 避免資料類型轉換的開銷

    • raw_feature 的 value_type 沒有特殊原因不要設定為 float 以外的類型

    • lookup_feature 的輸入保證 Map<Key, Value> 的 Key 的類型 與查詢欄位(Query)的類型一致

    • 如果需要配置num_buckets類型的特徵分箱,value_type 一定設定為 int64

    • 如果某列資料的最優類型在不同情景下是不一樣時,考慮添加一個不同類型的副本。

      • 比如,作為lookup_feature的查詢欄位時需要是BIGINT類型,作為combo_feature的一部分時需要是STRING類型;

      • 這種情況下,推薦為該列資料添加一個相應類型的副本,一個BIGINT類型,另一個STRING類型。樣本的SQL代碼如下:

        • SELECT int_data, int_data as str_data FROM ....

  • 盡量使用特徵依賴(DAG模式)複用能夠複用的部分

全域配置

配置項

類型

預設值

說明

USE_CITY_HASH_TO_BUCKETIZE

string

'false'

是否使用CityHash作為特徵分箱的hash函數

USE_MULTIPLICATIVE_HASH

string

'false'

是否使用乘法hash替代特徵hash的取餘操作,建議開啟

DISABLE_FG_PRECISION

string

'true'

是否禁用浮點型特徵精度約束; 如不禁用,浮點型的特徵FG只保留6位精度

DISABLE_STRING_TRIM

string

'false'

是否禁用多值字串特徵split後去除前後空格

MONITOR_CUSTOM_OP_EVERY_N_SECONDS

string

'0'

是否需要監控自訂OP的效能,列印效能資料的時間間隔(單位:秒)

IGNORE_CUSTOM_OP_EXCEPTION

string

'false'

是否忽略自訂OP內部拋出的異常

注意:上述配置需要在各種執行環境保持一致:離線與線上一致;訓練與推理一致;否則會出現離線上打分不一致的問題。

Hash衝突率

在某資料集上,共計26個不同基數的特徵,每個特徵都設定hash_bucket_size為特徵基數的10倍,測試結果如下:

hash類型

特徵基數總和

分箱數總和

hash衝突率

std::hash

882774549

840065238

4.8381%

cityhash

882774549

840072446

4.8373%

std+cityhash

882774549

840075948

4.8369%

cityhash+multiplicative

882774549

840072195

4.8373%

std+multiplicative

882774549

840077306

4.8367%

綜上,推薦使用std::hash + MultiplicativeHash 相結合的方式來最佳化模型效果,其中std::hash已預設開啟;MultiplicativeHash因為需要向下相容的原因,預設關閉,需要使用者按照以下方法手動開啟。

另外,CityHash是一種理論上均勻性更好的方法,但在該資料集上並未體現出明顯的優勢,使用者可在自己的資料集上進一步測試。

線上打分服務端配置

通過服務端的環境變數來配置;具體可以通過EasyRec Processor或者TorchEasyRec Processor的服務配置來設定。

{
  "processor_envs": [
    {
      "name": "USE_MULTIPLICATIVE_HASH",
      "value": "true"
    }
  ]
}

離線作業的配置

MaxCompute環境執行FG的離線任務,具體可參考在離線任務中使用FG

具體地,參考如下代碼:

from pyfg100 import run_on_odps

fg_task = run_on_odps.FgTask(...)
fg_task.add_fg_setting('USE_CITY_HASH_TO_BUCKETIZE', 'false')
fg_task.add_fg_setting('USE_MULTIPLICATIVE_HASH', 'true')
fg_task.run(o)

使用pyfg API時的配置

在使用pyfg API時,比如,一邊訓練一邊做FG,可以通過如下方法來配置。

import pyfg
pyfg.set_env('USE_MULTIPLICATIVE_HASH', 'true')
pyfg.set_env('USE_CITY_HASH_TO_BUCKETIZE', 'false')