kaggle初参戦コンペで銅メダルを獲得できたのでその感想戦(1)-test中のfakeデータ抽出
TL;DR
- kaggle初参戦コンペで銅メダル獲れた
- 自分がコンペ開催中に気付けなかった&実装できなかった重要ポイント(test中のfakeデータ抽出)について、コンペ終了後に感想戦してみた
はじめに
もう3週間以上経っちゃいましたが、kaggleの初参戦コンペ*1で銅メダルを獲得することができました!
参加コンペは以下、
Santander Customer Transaction Prediction | Kaggle
で、本コンペで鍵となった要素について振り返ってみる。
まずはtest中のfakeデータ抽出について。
結論から言うと、このtips(fakeデータ抽出と抽出後のデータ再形成)だけで60/8300位(上位1%以内)くらいは行けたっぽい。
参考kernel
広まるきっかけになったkernelは以下、
List of Fake Samples and Public/Private LB split | Kaggle
testデータ中に含まれてる半分が元データから生成された偽データで、その選別が重要だった。
このkernelはデータの抽出を扱っているだけなので、これでどれだけスコアが上昇するのか見るのに以下kernelを参照。
simple magic VAR 0.922 | Kaggle
上記2つのkernelが主な引用元だが、コンペ中盤頃にベースとして使ってた以下kernalからの引用も少しあるのでご紹介。
このkernelの重要テーマであるdata augmentationは本記事では割愛。
LGB 2 leaves + augment | Kaggle
検証用jupyter notebook
検証に使用したjupyter notebookは以下、
santander_late2
解説
それぞれポイントとなる部分について適宜解説
真テストデータの抽出(セル4)
真テストデータのインデックスを抽出する。
偽データは他データのコピーなので、unique_countを定義した上で他にコピーがなければ真データ、ダブってれば偽データへ分類している。
# GET INDICIES OF REAL TEST DATA ####################### # TAKE FROM YAG320'S KERNEL # https://www.kaggle.com/yag320/list-of-fake-samples-and-public-private-lb-split df_test = pd.read_csv('input/test_santander.csv') df_test.drop(['ID_code'], axis=1, inplace=True) df_test = df_test.values unique_samples = [] unique_count = np.zeros_like(df_test) for feature in range(df_test.shape[1]): _, index_, count_ = np.unique(df_test[:, feature], return_counts=True, return_index=True) unique_count[index_[count_ == 1], feature] += 1 # Samples which have unique values are real the others are fake real_samples_indexes = np.argwhere(np.sum(unique_count, axis=1) > 0)[:, 0] synthetic_samples_indexes = np.argwhere(np.sum(unique_count, axis=1) == 0)[:, 0] print('Found',len(real_samples_indexes),'real test') print('Found',len(synthetic_samples_indexes),'fake test') #######################
特徴量生成とデータの再形成(セル10-17)
特徴量をtrainデータの各列から持ってきてfeaturesを定義
features = [col for col in df_train.columns if col not in ['ID_code', 'target']]
trainデータと真テストデータを結合し、featuresを加えた新しいデータ群(=df)を生成
#concatenate train data and real test data with new features df = pd.concat([df_train,real_test], axis = 0) for feat in tqdm_notebook(features): df[feat+'_var'] = df.groupby([feat])[feat].transform('var') for feat in tqdm_notebook(features): df[feat+'plus_'] = df[feat] + df[feat+'_var'] drop_features = [c for c in df.columns if '_var' in c] df.drop(drop_features, axis=1, inplace=True)
dfを元のデータ比(train/test = 200000/100000)になるように再分割
#divide into new train and test sets df_train = df.iloc[:df_train.shape[0]] df_test2 = df.iloc[df_train.shape[0]:]
featuresの再定義
#新trainデータのtargetを使用してfeaturesを再定義 features = [col for col in df_train.columns if col not in ['ID_code', 'target']] target = df_train['target']
以上の特徴量生成+データ処理で、各データについて新たに200個特徴量が追加されたことがわかる(セル15-17)
学習(セル19-22)
新たに生成したtrainデータとtestデータを5foldのlightGBMに入れる。
パラメータ等各種設定値はほぼsimple-magic-var-0-922 kernelのまま。
結果
augmentaion等、他のトリックなしでも今回のデータ処理だけで上位1%に入れる!