KaggleのHome Credit Default Risk体験(他人のKernelパクリ編)

過去の「Featured」として、まずはタイタニック同様の「分類」コンテストで有名な次の問題を解いてみます。

Home Credit Default Risk

このコンペは与えられた個人のクレジットの情報や以前の応募情報などから、各データが債務不履行になるかどうかを予測する問題です。

 

[参考] 過去の機械学習関係の記事
 

Kaggleで勝つには次の書籍がおすすめです。

Kaggleで勝つデータ分析の技術

Kaggleで勝つデータ分析の技術

門脇 大輔, 阪田 隆司, 保坂 桂佑, 平松 雄司
3,536円(12/19 02:06時点)
発売日: 2019/10/09
Amazonの情報を掲載しています

 

この書籍によると、分析コンペで銅メダルに入賞するためには、Kernel(Notebooks)をしっかりとおいかけて基本フローをしっかりと押さえていくことで取れることがあるらしいです。

※ 2019年8月からKernelはNotebooksと名称が変わりましたが、多くのサイトや書籍では引き続きKernelと呼ばれています。

前回の記事でサブミットを行い、現在「スコア 0.70639(順位6119/7175 = Top 85%)」です。

Kernel(Notebooks)って何?

Kaggleには各コンペごとにフォーラムがあり、コンペ参加者がコードを公開する場(Kernel)、議論する場(Discussion)があります。

Kernelはクラウド上で計算や可視化のコードを実行できる環境です。

Kernelは分析のコードを共有場所にもなっており、公開されたものは他の人も見ることができます。

Kaggleにおいてはコンペに関する知見をプライベートにチーム外に共有することが禁止されており、コンペ参加者が平等にその知見に触れられるように、知見を共有しなければならないルールがあります。

そのため、参加しているコンペに関して、他の参加者が公開した知見を知りたい場合には、基本的にKernelおよびDiscussionを見ておけばよいようです。

なお、Kernelには、計算時間やメモリに制限があります。

  • 9時間の実行時間
  • 20GBのディスク容量
  • 16GBの一時的なディスク容量

特に容量は気をつける必要があります。

20GB max private datasets (if you exceed this, either make your datasets public or delete unused datasets)

[引用] https://www.kaggle.com/docs/datasets#technical-specifications

どのKernelを見ていくか?

Voteの順序に並べてみました。

最初の3つはイントロダクションやEDAに関する記載ですが「LightGBM with Simple Features」は明らかに戦略が記載されてそうなタイトルです。

ページを開いてみると「スコア 0.79070」と書いてあります。

 

多くの参加者のスコアが「0.8~0.79の間」だという事を考えると、明らかにこちらのKernelを参照しており、これをベースにスクリプトを改造しているようです。

[引用] <実践>はじめてのKaggle体験記

私の場合は、写経するだけでスコアが一気にアップします。

ちなみに、各レベルに対するスコアとランキングを一つ一つ確認しながら並べてみました。

レベル スコア ランキング
賞金獲得 0.80511 3/7175 (上位 3名)
金メダル 0.80110 24/7175 (top 0.3%)
銀メダル 0.79602 359/7175 (top 5%)
銅メダル 0.79449 719/7175 (top 10%)
サンプル 0.79070 2870/7175 (top 40%)

このコンペは「0.001」の世界を争っていたようです。

「LightGBM with Simple Features」は何をやっているのか?

358行という長さの中で、一体何をしているのでしょうか?Pythonの書き方もよく分かってないので他人のコードは勉強になります。

実行時間を計測する

Kaggleで実行時間に制限のあるコンペがあるので、withとcontextmanagerで実行時間を計測しているようです。

コンテキストマネージャ(context manager) とは、 with 文の実行時にランタイムコンテキストを定義するオブジェクトです。

今までTime関数呼んで差分を求めて時間を測定していましたしたが、Kaggleではこちらが一般的とのことです。

各種CSVを読み込む

このコンペは複数のCSVが用意されていました。

それらを一つ一つ読み込み、前処理を行い結合しています。

前処理は何をしているか?

グルーピングし統計量を算出する

このコンペでは、複数のデータが提供されています。

複数のデータは「SK_ID_CURR」というキーを使って、接続されています。

各データを合わせて一つの表を作ろうとしています。

また、重複するIDのカラムは集計して計算処理を行ったあとに合成しているようです。

サンプルを使って説明します。次のようなテーブルが存在するとします。

これに対して、AのIDをユニークにして残りのデータを min、 max、 sum で集計して出力してみます。

Pandasのデータをさまざまなかたちで集計する関数.agg()を使います。

これと同じ処理を行っている部分が次のコードです。

ほとんどの機械学習アルゴリズムを使うとき、特徴量の数は固定でないといけません。

ユーザー1は購買履歴が3行、ユーザー2は購買履歴が10行・・・のように、各ユーザーごとにデータの特徴量が違うと都合が悪いので、集計を全部の数値項目に対して行っています。

新しく特徴量を生成する

元の特徴量をもとに新しく特徴量を生成しているようです。

このような特徴量を作成するには、その業界特有の知識(=ドメイン知識)が必要です。

なので、これはそのまま拝借します。

カテゴリカル変数を数値に変える

「pd.factorize」を利用すると、カテゴリ変数をユニークな数値に変換してくれます。

引数にはシーケンス(list、Series)を渡します。

すると、カテゴリ変数を数値に変換したndarrayが返ってくるのでそれを元のデータフレームに戻します。

「uniques」にはユニークなラベルが入っています。

これをget_indexerを使うことで別のデータフレームのカテゴリ変数を同じ数値で変換することができます。

カテゴリデータを one-hot 表現に変換する

「pd.factorize」を利用すると、例えば「A 型から O 型への距離は A 型から B 型への距離の 3 倍である」というような関係だと勘違いすることがあります。、

このため、カテゴリ変数(カテゴリカルデータ、質的データ)をダミー変数(one-hot 表現)に変換するために「get_dummies」も利用されています。

学習モデル構築では何をしているか?

K-分割交差検証 (k-fold cross-validation)を利用する

「# LightGBM GBDT with KFold or Stratified KFold」と書いてあります。

今まで何度か「trai_test_split」関数で訓練セットとテストセットを分割する処理をしてきました。

「train_test_split」関数はデータをランダムに分割するので、クラス分類が難しいデータが訓練データに入り、簡単なデータがテストデータに入った場合評価精度はとても高くなってしまいます。

交差検証(Cross validation)はより正確な評価精度を得るために利用されます。

このサンプルでは、2つの交差検証手法である「k分割交差検証(k-fold cross-validation)」と「層化k分割交差検証(stratified-fold cross-validation)」を切り替えるような実装となっています。

  • 【メリット】train_test_split関数を活用した場合に比べて、汎化性のある評価精度を得ることができる
  • 【デメリット】分割したk個のモデルを訓練するため、単純な分割よりも計算コストがかかる

ちなみに「k分割交差検証」と「層化k分割交差検証」の活用用途は以下の通りです。

  • k分割交差検証(KFold):予測問題
  • 層化k分割交差検証(StratifiedKFold):分類問題

ベイズ最適化によるハイパーパラメータ探索をする

LightGBMのパラメータが細かく指定されており、コメントに「Bayesian optimization」で発見したパラメータと書いてあります。

従来、ハイパーパラメータの探索は、grid searchなどで行うことが常套手段でしたが、時間がかかりすぎるという問題がありました。

そこで、もう少し効率良くベストなハイパーパラメータを探索する方法として「ベイズで最適化する手法」が提案されています。

KaggleのKernelでは、「parameters found by Bayesian optimization」というフレーズがよく出てくるそうなので、覚えておいて損はありません。

また今度、自分でも実装してみます。

AUC (Area Under the ROC Curve)で指標の評価

今までは、機械学習の分類問題などの評価指標として混同行列 (Confusion matrix)を使っていました。

このサンプルでは「ROC-AUC」が使われています。

ただ、正例が極端に少ないデータだと、混同行列では正しく判定できないことがあります。

AUCとは、ROC曲線が描いた線を元に計算される評価指標です。

ROC曲線とは、スコアが「0.999999」以上のみを陽性と見なすようなという厳しい条件においても、陽性を正しく分類できます。

・・・・こちらもよく分かりません。

 

Scikit-learnでAUCを計算するには、roc_auc_score()に、正解ラベルと予測スコアを渡すとAUCを計算してくれます。

必要箇所をコピーして実行してみる

LightGBMで実行エラー

LightGBMで実行エラーが発生しました。

理由は分かりませんがググって次のように修正しました。

その結果、実行できました。

CatBoostで実行エラー&実行

CatBoostはErrorが発生しました。因みに、LightGBMではErrorは発生しません。

“FONDKAPREMONT_MODE_not specified” という文字列を”FONDKAPREMONT_MODE_not_specified”にしろというエラーです。

分かっているなら、自動的に変換してくれたらよいのに・・・。

修正すると、次から次へとエラーが表示されました。

変換は次のようにやります。

サブミットする

丸写しを避けるために、せめてもの意地で自分なりに幾つかやってみました。

  • [Step1] LightGBM(前処理+ベイズ最適化)
  • [Step2] CatBoost(前処理)
  • [Step3] CatBoost(前処理+AUCで評価で評価&K-分割交差検証)
  • [Step4] LightGBM(サンプル丸写し)

LightGBM(前処理+ベイズ最適化)で解いた結果

計算時間は約1時間です。

サブミットして得られたスコアは「0.77812」です。

順位は想定で4088/7175(top 57%)です。

CatBoost(前処理)で解いた結果

実行結果が得られました。

実行時間は7分程度です。

サブミットして得られたスコアは「0.78639」です。

順位は想定で3559/7175(Top 50%)です。

CatBoost(前処理+AUCで評価で評価&K-分割交差検証)で解いた結果

よく分からないまま、次のように差し替えました。

計算時間は1.5時間です。

サブミットして得られたスコアは「0.78767」となりました。

順位は想定で3406/7175(top 47%)です。

サンプル丸写しで解いた結果

計算時間は2時間です。

サブミットして得られたスコアは「0.79036」となりました。

順位は想定で3059/7175(top 43%)です。

・・・ってあれ???

サンプルと比べて正解率が低いな・・・。

まとめ

「馬鹿の一つ覚え」で「train_test_split」関数や「混合行列(confusion_matrix)」を使っていました。
 

例えると、サザンアイズの八雲が「土爪(トウチャオ)」だけで戦う・・・という感じです。

もっと、精度が高いアルゴリズムがあるのですね・・・・。目からウロコです。

 

まだまだ知識は足りませんが、実践の中で少しずつ覚えていきたいです。

で、スコア表です。

レベル スコア ランキング
賞金獲得 0.80511 3/7175 (上位 3名)
金メダル 0.80110 24/7175 (top 0.3%)
銀メダル 0.79602 359/7175 (top 5%)
銅メダル 0.79449 719/7175 (top 10%)
サンプル 0.79070 2870/7175 (top 40%)
私(サンプル利用) 0.79036 3059/7175(top 43%)
私(全部利用+前処理+Castboost+AUC+k-分割交差検証) 0.78767 3406/7175(Top 47%)
私(全部利用+前処理+Castboost) 0.78639 3559/7175(Top 50%)
私(全部利用+前処理+LightGBM+ベイズ最適化) 0.77812 4088/7175(Top 57%)
私(application_trainのみ利用+実数+Catboost) 0.70639 6119/7175(Top 85%)
私(application_trainのみ利用+0/1の2値+Keras or PyTorch) ?/7175(Top ?%)
私(application_trainのみ利用+0/1の2値+Catboost) 0.53662 6812/7175(Top 95%)

 

私の技術力でサンプルを超えることって出来るのかな・・・・。

ソースコード

最終的にはサンプルそのままとなってしまいましたので省略します。

タイトルとURLをコピーしました