Otto Group Product Classification Challenge
コンペ概要
Otto Group主催の自社製品のカテゴリを予測するコンペ。
200,000以上の製品と94種類の匿名化された特徴から9種類のカテゴリを予測する。
概要だけ読むとカラム名が匿名化されているという情報以外は結構シンプルな問題な気がする
table:概要
賞金 期間 参加チーム数 参加者数
$10,000 2015/3/15/ - 2015/5/19 3,511 3,845
LightGBMやCatBoostがまだリリースされてないため、scikit-learnのrandomforestやxgboostなどいろいろ試行錯誤されている状況がディスカッションやカーネルを読むと察することができる。
データの種類とタスク
テーブルデータを用いた分類タスク
train <<< test テストデータが訓練データの約2倍のレコード数
データサイズは小さいので高スペックマシンを用意しなくても分析はできそう
EDAしましたカーネルがなかったのでとりあえず作成
欠損値はないようだ
targetは不均衡の模様
https://gyazo.com/fdc40e000b242c59224288dfab3937ba
93種類のカラムは全て匿名でnumerical featuresとのこと
Each row corresponds to a single product. There are a total of 93 numerical features, which represent counts of different events. All features have been obfuscated and will not be defined any further.
予測対象のtargetは9種類のottoにおける代表的な製品の模様、またtarget、9種は訓練・テストデータそれぞれにランダムに混ぜたとのことで
There are nine categories for all products. Each target category represents one of our most important product categories (like fashion, electronics, etc.). The products for the training and testing sets are selected randomly.
table:ファイル概要
ファイル名 データサイズ レコード数 カラム数
trainData.csv 11MB 61,878 95
testData.csv 26MB 144,368 94
評価方法
評価指標はLogLoss
クリッピングしたほうがKaggleのスコアは上がるかも、またCaribrationの必要性(Kaggle本に掲載されてた覚えが)
提出方法
商品id毎のclass1-9までの予測確率を出力する。
table:sample.csv
id class1 ... class9
1 0.0 ... 1.0
2 0.2 ... 0.8
勉強になる Kernel と Discussion
t-SNEを二次元まで次元圧縮してプロットしたもの、カテゴリ毎に分離されているように見える
https://gyazo.com/7b39ed0145cb01e4cba81bbcaaa88760
可視化だけでなく、これらを特徴量として加えることで精度向上に貢献するとのこと
Kaggleで勝つデータ分析の技術(P.193)にて言及されている
各カラムが匿名化されているかつ非負の値であったため、値の出現頻度をそのまま特徴量として扱う解法が紹介されていた
おそらくotto - dataのこの一文、各様々なイベントの回数を表す、よりtfidfを利用したのだと思われる Each row corresponds to a single product. There are a total of 93 numerical features, which represent counts of different events. All features have been obfuscated and will not be defined any further.
添付されているソースコードよりtfidfの処理部分を抽出したもの記載
code:benchmark.py
# transform counts to TFIDF features
tfidf = feature_extraction.text.TfidfTransformer()
train = tfidf.fit_transform(train).toarray()
test = tfidf.transform(test).toarray()
Kaggleで勝つデータ分析の技術(P.204)にて言及されている
アンサンブル時の各モデルの推論結果に対するWeightのかけ方をどう最適化するかを説明している
NotebookではRandomForest *2(random_state違い) / ロジスティック回帰の3つのWeightを決定している
今回の場合データセットの規模がtrain <<< testのような関係のため、loglossを最小化するよう学習した場合trainに依存した各クラスの確率を出力するため矯正、調整する必要がある
Kaggleで勝つデータ分析の技術(P.96)にて言及されている
t-SNE結果が精度向上に貢献するとのこと
0.41599 public via T-SNE and meta bagging
Kerasの開発者であるfcholletが投稿したディスカッション Kerasの認知度向上もかねてか、starter_codeを公開
ただ当時のコードはkerasのexampleが削除されたようなのでおそらく当時のコードを保存したリポジトリを紹介
当時のコードを参考に再現コードを作成
Public/Private Score共に0.49とまぁ再現できてるのかなと
次どうすればよいか、アドバイスも併記されていたのでも紹介します
code:advice.md
Try it:
- with/without BatchNormalization (BatchNormalization helps!)
- with ReLU or with PReLU (PReLU helps!)
- with smaller layers, largers layers
- with more layers, less layers
- with different optimizers (SGD+momentum+decay is probably better than Adam!)
new以下のコードを実行することで9位のスコアが出せるとのこと
Public LB score: 0.39756, Private LB score: 0.39869 でした。
RとPythonが介在している
Stackingの構成図の各モデルはソースコードを読むと単一のモデルになっているわけではなく訓練時のパラメータやFoldの分け方を変更したりと複数存在する
https://gyazo.com/60b72ad0c486c3a64fa2a5832d7ca405
Stackingの有効性を試すために実験
上記コードのように大量のモデルを学習させるためには結構な時間がかかるのと管理の手間がかかるので、構成は簡単にすます
それぞれの処理はモデル毎にNoteBookで分けており、出力結果を入力データとして使うようにしています
上位解法概要
1位、2位、4位のSolutionでStackingがとても効いたとのこと
匿名カラムのためドメイン知識を生かした特徴量生成もできないので、全体的にモデルの性能・多様性でゴリ押ししたという印象
Kaggleで勝つデータ分析の技術(P.375 - P.377)にて1位、2位の解法を簡単に説明している
https://gyazo.com/dbacef203eea63e33930340beebfa07b
Kaggle blogのMedium移行に伴い解法を説明したブログ記事が消失
Stackingしているということはわかる
参考
おまけ
Ben Hammerがデータ可視化のスクリプトを公開していることに驚きました