Paoの技術力を磨くブログ

機械学習やブロックチェーン等の技術を身に付けていくブログです。

【Kaggle】初コンペで上位1.5%に入るまでの道のりと振り返り【HomeCredit】

8月に、初めてKaggleのコンペに参加したので、その内容を振り返る。(もう1ヶ月たってしまった。。)

取り組んだ期間は8月上旬からの約3週間で参加した。

結果は7189チーム中97位。 目標が上位5%(銀メダル獲得)なのに対し、結果が上位1.5%以内だったので、初めて参加した結果としては十分だったと思う。

そもそもKaggleとは・・・

世界中の機械学習やデータサイエンスに携わっている人が、機械学習によるデータの予測・分析力を競い合うコンペとそのプラットフォームのこと。
上位入賞者は賞金がもらえたり、kaggleでの実績や称号が企業から評価され採用に有利になったりすることもあるらしい。

参加した背景

今回、Kaggleのコンペに参加しようと思ったのは、基本的には「勉強のため」。 前から機械学習とかやってはいたけど、自分の武器というには弱いところだったので、もっと極めたいと思った。

また、客観的に自分の実力測定ができるのも理由としてある。

もともと機械学習の勉強をしたり、自分でモデルを作ったときに、 「良いモデルを作れているのか、きちんと予測できていたのかわからない」という思いがあった。
例えば、麻雀のAIを作っているといっても、それが限界に近い精度なのか、実力不足なのかよく分からない。

Kaggleを通じて機械学習の勉強をしながら、実力をつけていき、そのうち自分の実力を証明できればと思った。

参加したコンペ

参加したコンペは「HomeCreditDefaultRisk」。

Home Credit Default Risk | Kaggle

ローンを申し込んだ人が返済が可能かどうかを推測するコンペであり、Kaggle史上、参加者が過去最大のコンペだった。

ちなみに成績上位者の手法については、下記にまとめている。

pao2.hatenablog.com

コンペの特徴

関連するテーブルが多数存在し、とにかく情報量が多い。
何を意味しているのか分かりにくいデータ列もかなりあり、さらには欠損データも多い。
そのためどう特徴量を作って、選んでいくかがカギとなる。

コンペの詳細については下記の記事が分かりやすかった。

kurupical.hatenablog.com

取り組んだ流れ

データ内容の理解

とにかく謎の変数が多かったので調べまくった。 変数の意味が分かっても、数字や文字列の解釈が難しいものもけっこうあった。
ローン関連の知識があると理解しやすいのだと思う。 最後まで理解できなかった変数もあった。

Kaggle内のdiscussionに「この変数何?」みたいなトピックがけっこうあったのが助かった。

特徴量の作成、選択

ここにほとんどの時間を使った。
公開されていたカーネルにあった基本的な特徴量以外としては、

  • カテゴリ変数のtarget encoding(kagglerの中では普通かも)
  • 該当する職業や年齢別の平均収入・平均借入金、それらのその人の収入の比率
  • 過去のローンでまだ支払が終わってないものがどれくらいあるか
  • 支払い終わってないローンと今回申し込んだローンの額の比率、それらの合計と収入との比率や差分

などなど。。(書ききれない)

特にこの特徴量が大きく効いた!みたいなのは少なく、地道な作業の積み重ねで少しずつ精度があがった。

上位の人は同じような特徴量を少なくとも作っていたと思う。

モデルの選択・チューニング

LightGBMをメインで使った。
今までXGBoostとかを使ってたけど、LightGBMのほうが学習時間が明らかに速かった。

ちなみに、XGBoostも今回のコンペで試したが、LightGBMの方が少し精度がよかった。
(基本的には似たような勾配ブースティングのアルゴリズムのため、精度は似たようなものになる)

Kaggleでは何度も試行錯誤で学習を繰り返すので、この学習時間が短いことは非常に大事であり、Kaggle内で使われまくっているだけある。

ハイパーパラメータの調整はBayesianOptimizationという手法を使った。 こちらも初めて使ったが、GridSearchやRandomSearchより時間効率もよく、精度もけっこうあがった。
今後も使っていきたい。

モデル同士のアンサンブル

アンサンブル周りに関しては大したことが出来なかった。
やったのは、複数の乱数シードでの学習の平均処理(seed averaging)と、 いくつかのモデルの重み付け平均くらい。

重み付け平均については、LightGBMのboosting_typeの「goss」と「dart」、XGBoostの3つで行ったが、 最終はLightGBMの「goss」単体が一番精度が良い結果となった。

詳しくは後述するが、そもそも利用する特徴量とかを工夫しないと、モデル同士の多様性が生まれず、アンサンブルしてもあまり効果がない。
特にLightGBMもXGBoostもBoosting木の基本は同じなので、似たような結果になりやすい。

うまくいったこと

特徴量の作成、選択に力を入れられたこと

データの種類が多く複雑なため、人によって特徴量の作成に差が出ると予想し、ここにかなりの時間を要した。 ここまでFeatureEngineeringを細かくやったことなかったので時間はかかったが、結果が良かったのはここがほぼ全てだと思う。

最終提出の選択が良かった

kaggleでは、今まで自分が提出した予測結果の中から、最終提出として2つ選ぶ。
仮に1位になれる予測結果を持っていたとしても、それを選ばなければ1位にはなれない。

ここの選択を正しく行えたことも良かった。
(実際あとで確認すると、一番精度のよいものを最終提出として選んでいた。)

このコンペは全体的にCV(1)よりもPublicLB(2)が高くなる傾向にあり、 最後提出をCVが高いものを選ぶべきかPublicLBが高いものを選ぶべきかというところも話題になっていた。

自分の場合、CVを信じたものを選び、最終順位がPubilicLBの700位から97位へと大幅に上昇した。

おそらくOpenSolution(Kagglerの誰かがソースコードごと公開している手法)としてPublicLBがかなり良く、CVがその割には低いものが公開されており、 それを利用した人たちが一気に順位が落ちたのだと思われる。

1:CrossValidationの略。学習用データの一部を順番にテストデータとして使って精度を確認する。
2:評価用データの予測結果をKaggle内にアップロードすることで出てくるスコア。  評価用データの結果はPublicLBとPrivateLBに分かれており、PublicLBはコンペ中にスコアが公開される。  最終順位はPrivateLBで決まるが、こちらはコンペ終了まで結果がわからない。

気づき

上位に入るには相関の低いモデルをいかにたくさん作るかが重要

相関が低くて精度がよいモデルがたくさんあると最後のアンサンブルでスコアが上昇しやすい。
感覚的には、一人の予想よりも同レベルの複数人で予想した結果を集めたほうが精度が良くなるといった感じ。

相関性の低いモデルを複数用意するためには

といったことが重要になる。

チームを組み、それぞれのメンバーが作ったモデルを集めるのも有効な手段。

そして、実際上位の手法の多くは、チームを組みながら、さらに学習アルゴリズムや特徴量セットをたくさん用意することを行っていた。

私の場合は、一つの特徴量セット・LightGBMでの学習で精一杯でそれらが出来なかった。 (ソロ参加だったというのもある)

自分の狙う順位によって取り組む部分の優先度を変えたほうがいい

時間が無限にあれば出来ること全てやったらいいが、そうもいかないので、目標すべきラインによって、どこに注力すべきかを考えたほうがいいと思った。

銅メダル・銀メダル圏内くらいであれば、アンサンブルをすることより、基本は一つのモデルの精度を高めていくことをまず考えたほうがいいと思う。
実際、上位のチームでも、アンサンブル前の一つ一つのモデルが金メダル圏内に入れるくらいの精度を持っている。

金メダルや上位入賞を狙うのであれば、一つ一つのモデルを極めながらも、相関性の低いモデルを用意することが必須で、 さらに他の参加者と差別化出来るアイデアまであったほうがいい。

基本的なコーディング力の重要性

いいモデルさえ作れたら、ソースコードはいくら汚くても問題はないが、ソースコードの質はかなり大事だと感じた。

特に、何度も試行錯誤を繰り返す上での速度が変わるので、コーディング力により限られた時間で出来ることが大きく変わる。

チームを組むわけでないなら、可読性はそこまで重要ではないが、

  • 特徴量の追加や削除、交差検証の変更、学習方法の変更などへの拡張性の高さ
  • プログラム実行時間を短縮する工夫

などが大事だと思う。

例えば、学習のたびにcsvを読み込み、特徴量を作り直すと無駄に時間がかかるため、一度作ったものをPickleなどで保存しておいて再利用することは時間短縮になる。
自分もまだまだなのでもっと効率的な方法を追求していきたい。

discussionとkernelの重要性

Kaggle内にはKernelとDisucussionというコンテンツがあり、これが宝の宝庫である。

Kernel

kernelはjupyter notebookのようなもので、kagglerたちがソースコードを公開している。
kernelのいいとことしては、以下のようなものがある - それなりの精度(上位10~20%くらい)のモデルがどう作られているか理解できる - Kagglerたちの特徴量の作り方やコードの書き方が学べる - 学習以外の手法(パラメータチューニングや特徴量選択、データの前処理手法)も学べる

Discussion

Discussionは掲示板のようなもので、Kagglerたちがコンペの課題や手法について議論している。 Discussionを読むことで、そのコンペの難しいところや注意すべき点などが理解できる。

まとめ

今回は初めてのKaggle参加についてまとめた。
はじめての割には良い結果だったが、今後はもっと上位を目指していきたい。

今も新しいコンペに取り組んでいるので、いい結果報告できるようにします!