1. 程式人生 > >點選率預估

點選率預估

kaggle-2014-criteo-3 Idiots

資料集有13維數值型特徵和26維hash編碼的類別型特徵。評價指標是logloss,取得了0.444的成績。主要使用了GBDT和FFM。

步驟:

  1. 為GBDT準備特徵。包括13維數值型特徵,以及對26維類別型特徵做特徵編碼後出現次數超過4百萬次的稀疏特徵。
  2. 使用GBDT進行訓練,30棵深度為7的樹。獲取30維類別型特徵——特徵名:特徵值=treeNum:LeafNum。
  3. 為FFM準備特徵。
    • 13維數值型特徵中,大於2的特徵值變為 (log(x))2
      ;小於2的特徵值變為’SP’+str(value),其中SP代表special value,value是特徵的取值。然後將這13維數值型特徵當做類別型特徵處理,進行one-hot編碼
    • 26維類別型特徵中,出現次數小於10的特徵值變成’less’。例如對於類別型特徵C1,第1~3個樣本的取值是78c64a1d,第4~7個樣本的取值為65a24a1d。做onehot編碼後,特徵C1-78c64a1d有3個樣本取值為1,特徵C1-65a24a1d有4個樣本取值為1。那麼在處理第1~3個樣本時,把C1:78c64a1d編碼為C1less:1;在處理第4~7個樣本時,把C1:65a24a1d編碼成C1less:1。
    • 30維GBDT特徵直接被包含進來
    • 對上述三組特徵做hash編碼,轉換成 106 維特徵
  4. 使用FFM進行訓練,k=4。對於只在訓練集中出現的特徵值,對應的權重為0。
  5. 平均CTR在訓練集中是0.263,在提交的測試集中是0.266,因此對每一個預測值-0.003

為什麼可以使用GBDT作為高維特徵?

為了增強線性模型的表達能力,可以在特徵工程上多下功夫。比如把連續特徵(如年齡)離散化,20~25編碼成類別1,26~40編碼成類別2,然後做onehot編碼,送入分類器訓練,等價於為每一個類別訓練了一個線性分類器,這樣原本的線性模型就變成了分段線性的模型,即非線性模型。又比如把兩個類別型的特徵組合起來,性別+商品類別=新特徵,在點選率預估的應用中,為女性+化妝品訓練一個權重,肯定比單獨為女性訓練一個權重,為化妝品訓練一個權重的擬合效果更好。因為如果化妝品的權重高了,那麼男性+化妝品的點選率肯定也高,這就不大合適了。

GBDT特徵可以看作是上述兩種特徵變換的實現。就一棵樹來說,從根節點到葉子節點代表了一條建立在多個特徵上的規則,也許是26

為什麼可以用hash編碼來處理特徵?

來源:http://blog.csdn.net/dm_ustc/article/details/45771757

特徵維數太高,使用hash trick可以降維。原本n維的特徵向量通過hash變成d維,此時肯定有多個原始維度衝突的情形,但實驗表明這對問題求解影響不大(參考連結1)。

  1. Simple and scalable response prediction for display advertising 。
  2. Feature Hashing for large scale multitask learning。經典。
  3. Hashing algorithm for large scale learning。介紹最小雜湊在特徵雜湊的作用。
  4. http://www.cnblogs.com/kemaswill/p/3903099.html
  5. http://hunch.net/~jl/projects/hash_reps/。有微博大牛轉發過這條連結。是hash trick應用在機器學習中論文總結。
  6. https://breezedeus.github.io/2014/11/20/breezedeus-feature-hashing.html。結合實際專案談在multi-task中的應用,總結的挺好。

kaggle-2015-avazu-owenzhang

利用2014年10月21日00時~2014年10月30日23時的資料做訓練,預測2014年10月31日的點選率

特徵工程

  1. 對組合 site/app based features進行平均數編碼,構建exp_features特徵,特徵取app_or_web, app_site_id, as_domain等。

    exp_feature=_sum+credkmean_cnt+credk
    其中 _sum_cnt 是在給定特徵值下的點選率, mean 是所有樣本的點選率, credk 是先驗概率的權重。第21天的樣本的exp_feature是0,第23天的exp_feature中的 _sum_cnt mean 根據21、22兩天的資料計算。程式碼裡提供了last_day_only選項,即只考慮第22天的資料,但是預設是FALSE,可能效果不如考慮全部歷史資料好。除此之外,app_id=ecad2386佔了絕大多數樣本,因此設計特徵app_or_web=app_id==’ecad2386’?1:0,先對app_or_web做meanEncode,獲得的exp_app_or_web作為mean傳入其它特徵的平均數編碼的計算。

  2. 構建exp2_feature特徵,其中特徵取app_or_web, device_ip, app_site_id等。對於第23天的樣本,根據21、22天的樣本,對每一個特徵計算

    diff=(_sum+credk_mean_mean(_cnt+credk))power
    即後驗概率與先驗概率之比。程式碼中power=0.25。然後更新先驗概率
    _mean=_meandiff
    直至迴圈完成。對第23天的樣本,exp2_feature=diff_feature。feature_diff是根據21、22天計算的。而根據21、22天,預測第23天的樣本被點選的概率,可根據公式


    pred=_mean0featuresdiff_featurepred=pred_mean0mean(pred)
    其中 _mean0 是21,22天的總點選率。預測的logloss在0.4左右。

  3. 將時間特徵轉換成距離2014年10月21日00時,已過多少小時。 根據當前小時的對該device_ip的推薦次數,前一小時的推薦次數、後一小時的推薦次數、今天的推薦次數、昨天的推薦次數、今天的推薦次數-昨天的推薦次數、昨天的點選率構建7個特徵。

  4. FM特徵。用第21天的資料訓練FM,獲取第22天各樣本被點選的概率;用第21、22天的資料訓練FM,獲取第23天各樣本被點選的概率,以此類推。

  5. GBDT特徵。n_trees = 30, max_depth=6, eta=0.3, min_child_weight=50, colsample_bytree=0.5。

分類器

  1. 8個RandomForest分類器,取8個分類器輸出的均值。n_estimators=32, max_depth=40, min_samples_split=100, min_samples_leaf=10, max_features=8。每次隨機抽取30%的樣本做訓練。

  2. 4個xgboost分類器,取4個分類器輸出的均值。xgb_n_trees = 300, max_depth=15, eta=0.02, objective=binary:logistic, eval_metric=logloss, min_child_weight=50, subsample=1.0, colsample_bytree=0.5。將樣本隨機分成4份,每一小份樣本訓練一個分類器。

  3. 4個LogisticRegression分類器,取均值。

  4. 4個FM分類器,取均值。

  5. 模型融合。y={‘rf’: 0.075, ‘xgb’: 0.175, ‘vw’: 0.225, ‘fm’: 0.525}

  6. 微調

    pred[site_id=='17d1b03f'] *= 0.13 / pred[site_id=='17d1b03f'].mean()
    pred *= 0.161 / pred.mean()