6th Place Solution
はじめに
こんにちは、なぽなぽと申します。
一年ほど前から機械学習の勉強を始め、最近データ分析コンペを始めました。
説明が至らない部分があるかもしれませんが、大目に見ていただけると幸いです。
スプラトゥーンに関しては1のほうはかなりやりこんでましたが、2はあまりプレイしてません。
追加した外部データ
以下のトピックに記載されているデータを使用させて頂きました。
モデル
LightGBMのみ。
10分割のCVでそれぞれ予測し、平均した結果を1, 0で割り振るようにしました。
(NNなどを含めて、Stackingなどもやりたかったですが、時間の都合で間に合わず...)
特徴量
自分で新たに作成した特徴量としてはないです。
カテゴリ変数は以下のようにしました。
- weapon, specialは使用頻度の高い順に数値を割り振る。
- rank, category2はそのままカテゴリとして扱う。
- 欠損値は-999で置換。
それ以外で、一部の特徴量(mode, stageなど)は削除しました。
データ拡張
A1~A4とB1~B4を入れ替えて、ラベルを反転させたデータを追加しました。
上記のデータをtrainとvalidに分けて、trainだけデータを水増しました。
水増しには以下のような関数で実装しました。(N=17で実行)
import pandas as pd
import itertools
import random
def expand_dataset(N: int, df: pd.DataFrame, random_state=42):
"""データを拡張する"""
if N == 0:
return df
# 実際には列名のリストが格納されている
a1 = ['A1-weapon', 'A1-rank', 'A1-level', …]
a2 = []
a3 = []
a4 = []
b1 = []
b2 = []
b3 = []
b4 = []
train = df.copy(deep=True)
train_temp = df.copy(deep=True)
all_train = df.copy(deep=True)
a_team_list = [a1, a2, a3, a4]
b_team_list = [b1, b2, b3, b4]
a_team_combination = list(itertools.permutations(a_team_list))
b_team_combination = list(itertools.permutations(b_team_list))
a_and_b_combination = list(itertools.product(a_team_combination, b_team_combination))
if N > len(a_and_b_combination):
pattern_list = a_and_b_combination
else:
random.seed(random_state)
pattern_list = random.sample(a_and_b_combination, N)
for pattern in pattern_list:
train[pattern[0][0]] = train_temp[a1]
train[pattern[0][1]] = train_temp[a2]
train[pattern[0][2]] = train_temp[a3]
train[pattern[0][3]] = train_temp[a4]
train[pattern[1][0]] = train_temp[b1]
train[pattern[1][1]] = train_temp[b2]
train[pattern[1][2]] = train_temp[b3]
train[pattern[1][3]] = train_temp[b4]
all_train = pd.concat([all_train, train], axis=0)
return all_train
ハイパーパラメータチューニング
optunaを使ってみましたが、実行するたびにパラメータの数値が右往左往するので、最終的には自分で調整しました。
以下が一番良かったLightGBMのモデルのハイパーパラメータです。
# LightGBMのハイパーパラメータ
params = {
'objective': 'binary',
'metric': 'binary_logloss',
'early_stopping_rounds': 100,
'num_iterations': 50000,
'lambda_l1': 0.004,
'lambda_l2': 0.0000006,
'num_leaves': 24,
'feature_fraction': 0.5,
'bagging_fraction': 0.724624897380167,
'bagging_freq': 2,
'min_child_samples': 5,
'learning_rate': 0.1
}
スコア
- CV : 0.560052
- Private : 0.560339
- Public : 0.566549
まとめ
ほかにチームの統計量などを追加してみましたが、見事に過学習してしまいました。
統計量でなく個人の特徴量を増やしていけば、スコア向上が見込めたかな~とか思っています。
あとはStackingなど、他のモデルを合わせてのアンサンブル学習なども試したかったですね...