Santander Customer Transaction Prediction Kaggle比賽 小結


 

之前參加了kaggle的一個Santander Customer Transaction Prediction比賽,共有達9038支隊伍參賽,一個號稱尋找magic的比賽。參加比賽的的忘不了被magic這個詞所支配的恐懼...

比賽鏈接 https://www.kaggle.com/c/santander-customer-transaction-prediction/overview

也算是第一次kaggle正式的做比賽吧,之前做了一個kaggle的Quora的文本分類的一個比賽,但是隻做了幾天,最後還沒選成 Final Score,所以最後也不算成績,也不知道排了多少名。

我是前期做了幾天,後來就沒做了,直到最後四天才又開始每天做10個小時大概...

然後自己的成績是 top4% for 9038 teams 。 300/9038

很可惜最後一天模型融合沒跑完比賽時間就截止了,跑完的話能再升100名.....

對自己的成績還算滿意吧。

最後感謝某位大佬的指點和帶飛。

下面來總結一下這個比賽自己的收穫。

<!--more-->

這個比賽訓練集給了20w條數據,共200個特徵,都是數值型特徵,都是匿名特徵,並沒有具體的每個特徵的含義。測試集也是20w條數據。

根據這200個特徵預測每個用戶是否會發生交易。一個2分類問題,最後評估是ROC_AUC。

Magic

這個比賽最最重要的兩個magic其實在討論區和kernel區已經有hint了。

1、其中最重要的就是區分測試集中合成樣本和真樣本。下邊的kernel是某大神提出區分合成樣本和真樣本的方法,通過判斷特徵的唯一值,如果一條樣本中200個特徵值中有一個特徵值在這20w樣本中是unique的,則該樣本是真樣本。通過這個方法劃分出來了10w條真樣本,和10w條合成樣本。具體代碼見下面的kernel。

https://www.kaggle.com/yag320/list-of-fake-samples-and-public-private-lb-split

2、第二個magic就是,frequency encoding 和 count encoding。當然是除去合成樣本,即將train+test_true合起來做特徵。

當然還有一個magic更神奇,只需要短短几行代碼就能到150名。下面再說。

下面貼一下top解決方案

1 Solution

https://www.kaggle.com/c/santander-customer-transaction-prediction/discussion/89003#latest-515385

2nd place solution

 

可以看到這位大神用了NN和LGB的模型來融合。其實我看很多大神都用了NN模型,NN模型在這個比賽效果還不錯,用的好的話,說不定能拿個金牌呢。

9 Solution

https://www.kaggle.com/c/santander-customer-transaction-prediction/discussion/88913#latest-515121

 

這位大神,首先將train+test_true合併,然後將unique的特徵用NaN代替,他說能到0.917,後來我自己嘗試分數能直接飆到0.919,什麼概念呢,在100名左右。

然後他繼續拿初始的200個特徵,將count>1的用NaN替代,然後將這400個特徵拼接起來,分數就能達到0.922,然後自己在改改參數,數據增強採樣一下,模型融合我估計能到top50。

賽後總結

當然現在開源的都能達到0.925+了,可以直接去看開源kernel。我只是總結一下自己當時比賽的一些情況。

我也是基於train+test_true做的frenquence encoding特徵,用lgb 十折LB在0.903,這個時候需要調調參數,把num_leaves調小點,結果會更好些。但是我當時沒調..當時時間確實很倉促,很多實驗都沒來得及做,比如沒有用XGB跑一下,用xgb跑的話,參數不改能直接提交達到0.91020.能在200名左右。。

然後最後也沒用上數據採樣增強..其實還是有用的。

最後我跑了lgb+ xgb + nn做stack可惜時間不夠了,第二天5.30定了鬧鐘起來看結果...因爲大概早上八點比賽就截止了,可惜kaggle的kernel只能跑9h,然後時間超了...遂fail...以後還是用服務器跑吧...血的教訓。

 

比賽結束後,自己將模型融合的結果提交了一波,發現lgb+ xgb + nn做stack,stack第二層 採用十折的Ridge效果最好。可惜當時時間不夠沒能提交。但是我當時NN的效果不好,只有0.89754的score。所以結果也不是太好,如下圖。

自己也嘗試了stack第二層採用邏輯迴歸,效果差一點..嘗試了xgb×0.7+lgb×0.3也只有0.909。

 

最好放一下stack的代碼

from sklearn.ensemble import RandomForestClassifier, ExtraTreesClassifier, GradientBoostingClassifier
from sklearn.linear_model import BayesianRidge
from sklearn.model_selection import StratifiedKFold
from sklearn.linear_model import LogisticRegression
import numpy as np
stack_train = np.vstack([sub_oof['lgboof'], sub_oof['xgboof'],sub_oof['nnoof']]).transpose()
stack_test = np.vstack([sub_pred['lgb_target'],sub_pred['xgb_target'],sub_pred['nn_target']]).transpose()
folds = StratifiedKFold(n_splits=10, shuffle=False, random_state=42)
oof_stack = np.zeros(len(sub_oof))
pred_ = np.zeros(len(test))
target = sub_oof['target']
## LR
for fold_, (trn_idx, val_idx) in enumerate(folds.split(stack_train, target.values)):
    print("Fold :{}".format(fold_ + 1))
    clf = LogisticRegression(random_state=42, n_jobs=8).fit(stack_train[trn_idx], target.iloc[trn_idx])
    oof_stack[val_idx] = np.array(clf.predict_proba(stack_train[val_idx]))[:, 1]
    pred_ += np.array(clf.predict_proba(stack_test))[:, 1] / folds.n_splits
print("Stackinglr_CV score: {:<8.5f}".format(roc_auc_score(target, oof_stack)))
​
## Ridge
oof_stack2 = np.zeros(len(sub_oof))
pred_2 = np.zeros(len(test))
for fold_, (trn_idx, val_idx) in enumerate(folds.split(stack_train, target.values)):
    print("Fold :{}".format(fold_ + 1))
    clf = BayesianRidge().fit(stack_train[trn_idx],target.iloc[trn_idx])
    oof_stack2[val_idx] = clf.predict(stack_train[val_idx])
    pred_2 += (clf.predict(stack_test)) / folds.n_splits
print("StackingBayes_CV score: {:<8.5f}".format(roc_auc_score(target, oof_stack2)))

收穫

之前自己一直處於眼高手低...比如xgb、lgb只僅限看了看別人的總結原理看了看官方文檔,並沒有去深究原理論文,各有什麼優點,但是參加了這個比賽,我去詳細讀了xgb、lgb的論文,哈哈主要是因爲當時在討論區大家都在討論爲什麼這些特徵有用,lgb能學到什麼不能學到什麼,懷着這樣的好奇心去讀了讀論文。其實本來還想寫一下GBDT、XGB、LGB各自的原理優缺點的,但是看了看網上這類文章很多...所以便沒有去寫了。。打算等之後空閒了可以在重複造個輪子寫一寫,也算是在複習一遍了。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章