<実践>はじめてのKaggle体験記

機械学習を勉強し始めて1年が経ちました。
そろぞろ何か一つ目に見える実績を上げたいと思いたち、
5月から8月までHomeCreditというKaggleのコンペをやっていました。

Home Credit Default Risk | Kaggle

f:id:kurupical:20180902183535p:plain

最終的に、7198人中62位で終わることができました!

Kaggleをやってみようかなと思っている人向けに、自分の体験記を残しておこうと思います。

わからない用語は、Kaggle Words For Beginnerを参考にしてください。

もくじ

  1. スペックと前準備
  2. コンペ内容の確認
  3. コンペ参加
  4. 感想

0. スペックと前準備

スペック

前準備

コンペを始める前に(一部は始めてから)、Kaggleのノウハウを探りました。
いろいろな記事を読み*1、以下が大事なのかなと思いました。

  • 一番時間を費やすべきなのは特徴量*2作成。(特徴作成8:チューニング2くらい)
  • Discussion/Kernelはvoteが最低限沢山付いているものだけでも読む。
  • ドメイン知識(データ自身に対する専門知識)を入れる。
  • 最後まであきらめない。

1. コンペ内容と基本的な内容の確認

Kaggleの公式ページ

詳しいコンペの内容は割愛しますが、データから「ユーザーが契約したローンを、遅延なく返せるかどうか」を当てるコンペでした。
すごくざっくり説明すると下の図のような感じです。赤枠を当てるコンペです。
f:id:kurupical:20180908102220p:plain:w500

Titanicのように1ファイルではなく、複数ファイル(テーブル)でデータが与えられています。
また、実際には、たくさんの特徴量があります。
1ユーザーに対して複数行の情報があるため、機械学習にかける前にデータの集計が必要でした。

EDA

Kaggleには各コンペごとにフォーラムがあり、コンペ参加者がコードを公開する場(Kernel)、議論する場(Discussion)があります。
その中でもまず見るべきなのがEDA(Exploratory Data Analysis)です。
EDAのKernelでは、投稿者が行ったデータ分析の内容を投稿してくれています。
いろいろな投稿者がEDAを投稿しており、人によってデータの分析の角度や可視化のやり方が違います。
これらの記事を見ることで、HomeCreditに留まらずデータ分析のハウツーや可視化の引き出しを増やすことができました(デキる人からすれば常識的なスキルかもしれませんが)

今回は幸運なことに、人気のEDAの日本語訳が投稿されており、この記事*3にはお世話になりました。

ただ、公開されているEDA以外にも、自分自身でEDAをやる必要があったなと反省しています。

2. コンペ参加

コンペの活動履歴を綴っていきます。
()内は、その時点のだいたいの最終順位です。

とにかく1サブミット - 3特徴量だけを使う (6600位 / 7200)

Kaggleに限らず新しいことを始めるにあたって一番しんどいのは、最初の一歩を踏むことだと思います。
完璧主義を目指して挫折するよりも、まずはどんな手法でもいいから、「1サブミット」をすることを目標にしました。

Kernelをざっと見ると、明らかに大事そうな特徴「EXT_SOURCE_1,2,3」があることに気づきました。
この3特徴量を抽出して、RandomForest(自分が最近よく使ってた手法)で分類するモデルを作りました。

1ファイル全部使う+LightGBMにチャレンジ (6100位 / 7200)

f:id:kurupical:20180908102329p:plain:w500

次は、

  • 図の赤枠部分を使って予測すること
  • LightGBMを使うこと にチャレンジしました。

LightGBMは使ったことがなく理論もわからなかったのですが、Kernelを見ながらプログラムを書いていきました。
パラメータもKernelのものを使いました。
LightGBMの場合、欠損値はそのまま処理してくれますし、カテゴリ変数も指定してあげればonehotencodeしなくてもそのまま処理してくれるので、とても便利です。

特徴量作成

特徴量作成は、思いついたものは片っ端から作って、最後に絞り込む方針でやりました。

特徴量作成① 全ファイルを機械的に集計 (1500位 / 7200)

f:id:kurupical:20180908112138p:plain

次は、使っている全ファイルを機械的に集計することにしました。
LightGBM(に限らずほとんどの機械学習アルゴリズム)を使うとき、特徴量の数は固定でないといけません。
ユーザー1は購買履歴が3行、ユーザー2は購買履歴が10行・・・のように、各ユーザーごとにデータの特徴量が違うと都合が悪いので、図のような集計を全部の数値項目に対して行いました。

この発想は独自のものではなく、Kernelの丸パクリ*4です。

特徴量作成② 項目同士の突き合わせー数値編 ( - )

f:id:kurupical:20180908110337p:plain

次は、項目同士の突き合わせです。
木のアルゴリズムはif文の集まりであるため、項目同士の関係を捉えにくいようです。
なので、元の特徴量をもとに新しく特徴量を生成しました。
例えば図にあるように、年収と子供の数の比を見れば、その家族が支払える金額の指標になりえます。

項目の意味を考えて、様々な特徴量を作成しました。
特徴量を作成するには、その業界特有の知識(=ドメイン知識)が必要とされます。

私はドメイン知識がなかったので、特徴量の重要度(LightGBMが出力してくれる)を参照し、重要な特徴量同士を四則演算して特徴量を作成しました。

これも、基本的な発想はKernelの丸パクリ*5で、そこから自分のアイデアを肉付けしていく形にしました。

特徴量作成③ 項目同士の突き合わせーカテゴリ編 ( - )

項目同士の突き合わせですが、カテゴリ変数は割り算ができません。
ので、以下2つのアプローチで行いました。

TargetEncodingとは、カテゴリ変数をTargetの平均で埋めることです。(今回であれば支払遅延有無:1を「あり」とする)
f:id:kurupical:20180908112824p:plain

また、ドメイン(もしくは常識的な)知識によりカテゴリ変数を数値に変換しました。
f:id:kurupical:20180908111911p:plain

これらの処理を行うことで、数値特徴量とカテゴリ特徴量の四則演算が可能になります。

特徴量作成④ 時系列アプローチ ( - )

f:id:kurupical:20180910200457p:plain

また、時系列的な考え方も取り入れました。
普通に考えると、直近3ヶ月の履歴はそれより前の履歴よりその人の特性を表すと思ったからです。
例として、図のような特徴量を取り入れました。

また、過去30日金額÷過去90日金額など、直近の金額が過去と比べてどうであるか、のような特徴量も作りました。

このアプローチはこのdiscussion*6から自分で考えました。

特徴量選択 (600位 / 7200)

ここまでで作成した特徴量は、およそ1800個となりました。
「LightGBMは冗長な特徴量があっても大丈夫」という意見もありましたが、特徴量が多いとメモリが足りないという都合と、やっぱり特徴量絞ったほうがいい結果が出る実感があったので*7、特徴量を絞りました。

特徴量選択は、Kernelでも様々な手法が紹介されていましたが*8、自分が試したのは以下です。

  1. 相関が高い特徴量を削除
  2. LightGBMのfeature importance(gain/split)
  3. Null Importances*9
  4. SHAP*10

結局、1で相関係数>0.95のものは片方削除→4で重要度ベスト400,500,600をそれぞれ選び、モデルに学習させました。

パラメタチューニング① hyperopt/BayesianOptimization ( - )

LightGBMのパラメータの意味がわからなくとも自動的にパラメータチューニングしてくれるすごいライブラリの使い方がKernelに公開されていたので、試しました。

  1. hyperopt *11
  2. Bayesian Optimization *12

ただ、これらを使うには調整するパラメータの範囲や種類を指定しなければなりません。

  • 範囲や種類が多いほど時間がかかる。
  • 特徴量の数によっても、最適なパラメタは違う(らしい)。

しばらく試していたのですが、上記のような理由もあり、やっぱりある程度LightGBM、GBDTの簡単な理屈を知ったうえで手でチューニングしたほうがいいかなと思い、使うのをやめました。

実際、過去の似たようなコンペの上位解法を見ると、「パラメタチューニングは勘で決めました」であったり、「我々が時間を割くべきはパラメタチューニングではない」といった記述もありました。

パラメタチューニング② LightGBMの勉強 (150位 / 7200)

パラメタの意味を知るため、簡単にLightGBMの勉強をしました。
LightGBMを知るためにはxgboostを知ってる必要があり、xgboostを知るには勾配ブースティング木(GBDT)を知る必要があり、GBDTを知るには決定木を知る必要があるということがわかりました。

参考になった資料のリンクを貼っておきます。(自分が読んだ順)

概要

NIPS2017読み会 LightGBM: A Highly Efficient Gradient Boosting Decision T…
Overview of tree algorithms from decision tree to xgboost

大事なパラメタとその意味を調査

Complete Guide to Parameter Tuning in Gradient Boosting (GBM) in Python
XGBoostやパラメータチューニングの仕方に関する調査 | かものはしの分析ブログ
Santander Product RecommendationのアプローチとXGBoostの小ネタ - Speaker Deck
XGBoostにDart boosterを追加しました - お勉強メモ
Laurae++: xgboost / LightGBM - Parameters
LightGBM/Parameters.rst at master · Microsoft/LightGBM · GitHub

論文

xgboost http://www.kdd.org/kdd2016/papers/files/rfp0697-chenAemb.pdf
lightgbm https://papers.nips.cc/paper/6907-lightgbm-a-highly-efficient-gradient-boosting-decision-tree.pdf
dart https://arxiv.org/pdf/1505.01866.pdf

論文全然わかんなかったので参照

Gradient Boosting と XGBoost | ZABURO app

過去コンペのパラメタ参照

Kaggle Past Competitions
Porto Seguroとか見ました。

結局

いろいろ見て、(結局半分も理解できませんでしたが)以下の方針を立てました。

  • モデルをロバストにする
    • colsample_bytree 0.05-0.2くらい -> 0.05がよかった
    • lamdba_l1とl2をそれぞれ0.1,1,5,10,20で組み合わせて試す -> l1=1, l2=20がよかった
    • subsample 0.9で決め打ち
  • 木の形はわからんからとりあえずいろいろ試す
    • max_depthは-1とsqrt(max_leaves) * 2、max_leavesは30〜130くらいを試した -> max_depth=-1, max_leaves=30がよかった
  • gbdt, dart, gossはわからんからそれぞれ試した -> dartメイン、gbdtもちょっと使った
    • 精度; dart>gbdt>goss
    • 計算時間: dart>gbdt>goss
  • learning_rateは0.0025〜0.05まで試した -> アンサンブル考えると(後述)、以下がよかった。
    • gbdt: 0.0025
    • dart: 0.01

※この方針はあまりよくなかった気もしています。実際、2位のikiri_DSのonoderaさんのgithub見てみると*13、colsample_bytree 0.9くらいなので・・・

アンサンブル/スタッキング① アンサンブル ( 62位 / 7200 )

最後にアンサンブルをしました。
「◯×クイズに60%正解する人が3人。3人の答えがそれぞれ独立だとすると、3人のうち多数決を取ったときのクイズの正解率は?」
答え:
3人とも正解:0.6 * 3 = 0.216、2人が正解: 3 * 0.6 ^ 2 * 0.4 = 0.432なので、0.216 + 0.432 = 0.648
正解率は一人の時より上がります!!

つまり、いろんなモデルを作って多数決をさせることで、それぞれのモデルよりよい性能が出る可能性があります。
ただし重要なのは、「モデル同士の予想の相関が低いこと」です。

モデル同士の予想の相関を低くするために、以下を行いました。

  • 異なるアルゴリズムを使う(Neural Network) -> 精度が全く出ず断念
  • 異なるパラメータを使う -> LightGBMのdart,gbdtを組み合わせることで精度が良くなった。
  • 異なるseedを使ってK-Foldする -> 単一モデルより精度が良くなった
  • 低すぎるlearning_rateを使わない(単一モデルの精度はよいが、異なるseedを使っても多様性がなく、アンサンブルの効果が薄くなった)

    相関と精度を見て、最終的に、dart(500特徴量)・dart(400特徴量)・gbdt(500特徴量)のアンサンブルを組みました。(これが最終順位62位のサブミットでした)

アンサンブル/スタッキング② スタッキング ( - )

「スタッキング」とは、「複数のモデルが出した予想値」を入力にしてもう一度学習させ、最終的な予想を行うことです。
スタッキングもやったのですが、アンサンブル以上に精度が出なかったので断念しました。

結果

LB: 498位→PB:62位
LBの順位は低かったですが、公開されているソースよりもCVが高かったので、Trust Your CV*14の精神で耐えました。
CV0.794->LB0.804のようなLBにOverfitしてると思われるものもありましたが、自分はCV0.8018 -> LB0.802でした。

3. 感想

とても勉強になりましたし、楽しかったです。
データの分析の仕方もLightGBMもわからない状態でスタートしましたが、ほとんどKernelに助けられながら、最後までできました。
実際、Kernelを全く見ないでやったら、半分より上にも行けなかったと思います。
scikit-learnあたりの使い方が少しわかってきたけど次何すればよいか・・・という人には、Kaggleを強くおすすめします!

また、コンペ参加中は、データ分析をみんなで一緒にやってる気持ちでした。
discussionを読みながら、時々参加したり。
リーダーボード(ランキング)をみて、「自分はこのスコアが限界だと思ってたけど、もっと伸びるのか」と、分析を投げずに最後までがんばれたり。
中だるみもありましたが、充実した3ヶ月でした。

自分自身が、Kaggleに参加する前とした後で変わったことは以下かなと思っています。

  • 特徴量作成が超大事だと分かった。(データを入れたら答えが帰ってくるわけじゃない)
  • 「テーブルデータの分類モデルの構築をどこから始めたらよいか」が分かった。
  • 特徴量作成の定石を少し覚えた。
  • LightGBMの分類が使えるようになった。(ある程度パラメータも理解できた)
  • GCPの使い方がわかった*15

泥臭い部分も含めたノウハウを、少しだけ、Kaggleを通じて習得できたかなと思います!

超長くなってしまいましたが、最後まで読んで頂きありがとうございましたm(_ _)m

<メモ>tensorflowのimport時のエラー(libcublas.so.9.0が見つからない)

tensorflowのimport時にlibcublas.so.9.0: cannot open shared object file: No such file or directoryと出る時の対処法メモ

環境

  • CUDA 9.0
  • tensorflow 1.8.0
  • Pycharm community 2018.1

状況

解決方法

Pycharmを開き、[Run] => [Edit Configurations] => Python-[自分が動かしてるプログラム]を選択
Environment variablesに、LD_LIBRARY_PATH: /usr/local/cuda-9.0/lib64:$LD_LIBRARY_PATHを追加

f:id:kurupical:20180817101146p:plain

defaults→python→Environment variablesにLD_LIBRARY_PATHをセットしても動かなかったので、自分のプログラムにパスを通しました。

CUDAの環境まわりなどちゃんと入れてるのに何故かちゃんと動いてくれない・・・というときは、開発環境を疑ってみるとよいと思います。

参考記事:
github.com

<実践>HomeCredit作業記録(6) - 進捗とメモ

f:id:kurupical:20180615203929p:plain:w500

いいところまで来ました。
淡々と、定石通りにやってるだけのつもりなんですが・・・

ただ、手法のPrivate shareが禁止ということで、規約にひっかかりそうなので過去の記事を非公開にしました。

いま使っているLightGBMがブラックボックスすぎるので、そこの勉強をしたいです。

ここまで作業時間40時間くらい、思ったことややったことメモ

Kaggleだと限界がわかる

自分が1位じゃないかぎり、スコアの伸びしろがわかるっていうのは大きいですね。
実務だと一人でやるので、どこまでできるのかが不透明です。

しばらく誰も100m10秒切れなかったのに切ったとたん、他の人も10秒切れるようになった、みたいな感じですね
1位じゃないからまだまだやれるんだなというのがわかるのは大きいです。

Discussionが参考になる

今私は特徴量作成をやっているのですが、それすらも自動化する「Featuretools」というツールが出てるみたいですね。
Kaggleのディスカッションは以下です。
https://www.kaggle.com/willkoehrsen/intro-to-tuning-automated-feature-engineering

まだ使っていないのですが、いつかは使ってみたいです。

仕事でもプライベートでも作れるEDAツールにする

多分次の分析でもやるだろうな〜と思ったデータ加工のプログラムは、再利用可能+テストを書いて多少の品質を確保しています。

データサイエンティストの人を片っ端からフォローした

議論を追ったりするとめっちゃ勉強になります!

<調査>Kaggle過去コンペ上位入賞者のSolutionから学ぶ(1)

blog.kaggle.com
この記事に、「コンペに優勝するためには過去のコンペから学ぶことが大事だ」と書いてあったので、過去のコンペを調べることにしました。
過去のコンペのDiscussionを見ると、上位入賞者が解法を公開してくれています。

HomeCreditと同じ「分類」タスクのコンペを探しました。

以下、自分のメモ書きです。

Porto Seguro’s Safe Driver Prediction 1st solution

Porto Seguro’s Safe Driver Prediction | Kaggle

1ファイルのコンペ(主キー1に対して、レコードがN行みたいなことがない)

手法

  • Representation learning
    • DAE(Deep Auto Encoder)による特徴抽出。
    • Feature Engineeringが嫌い!それを自動化してこそAIだ!ということだそうです。
  • Normalizationには"RankGauss"を使った
  • inputSwapNoize

    • 0.15 means 15% of features replaced by values from another row.
    • これって以下の認識であってるんでしょうか?
      • DAEはノイズ除去の役割を果たす
      • 人工的にノイズを作るため、各特徴の15%は別の行とスワップする
        f:id:kurupical:20180605205648p:plain:w500
  • GANはやってみたけど失敗

    • 連続値とカテゴリ変数が混在する場合のGANは難しい
    • 疑問:GANを何に使おうとしたのでしょうか?
  • NN5個とLGBM1個をstacking(重みはすべて同じ)

感想

  • DAEによる特徴抽出が強い!今のコンペでもやってみたいです。ただ、主キー1に対してN行データがある場合は入力が動的になるから難しいですね。この問題が解決できたら、いよいよFeature Engineeringが要らなくなる?
  • inputSwapNoiseの考え方が個人的にとても面白かったです。

<実践>HomeCredit作業記録(5) - FeatureEngineering続き

Kaggle挑戦中です!
債務不履行になる人を予想するタスクです。
Home Credit Default Risk | Kaggle

やったこと

  • FeatureEngineering

FeatureEngineering

前回の記事では、一つ一つの特徴量をじっくり見ていました
kurupical.hatenablog.com

ですが、やっぱりキリがないので、機械的に全部のデータをいろいろな形で集計しました。
参考にしたKernelは以下などです。
Good_fun_with_LigthGBM | Kaggle
LightGBM - all tables included [0.778] | Kaggle

結果

score: 0.735 -> 0.782
順位: 214位/1642 (上位15%)

今後やっていきたいこと

いったんFeatureEngineeringはやめて他のタスクを。

  • パラメタチューニング
    RandomisedSearch, GridSearch以外もいろいろ試したいです。

  • 別のアルゴリズムも使う
    今はLightGBMを使っているのですが、XGBoostやDeepLearningも試してみたいです。

  • アンサンブル学習
    複数の学習器でStackingをやりたいです。

その他

参考になったDiscussion


  1. この特徴量生成は正直引きました。え、そこまでやるの?みたいな
    Hybrid Jeepy and LGB | Kaggle
    いろんな特徴量を足したり引いたりミニマム取ったりtanh取ったり・・・
    そこまでやるならDeepLearningでやればよいのでは?なんて思ったり。
    でも、こういうアプローチもあるのかと勉強になりました。


  2. Home Credit Default Risk | Kaggle
    書き込んでみました。笑 質問した後、自分の凡ミスに気づくという・・・

<実践>HomeCredit作業記録(4) - FeatureEngineeringのためのツール作成

Kaggle挑戦中です!
債務不履行になる人を予想するタスクです。
Home Credit Default Risk | Kaggle

やったこと

FeatureEngineeringのつづき

  • 可視化ツールの作成
  • 特徴量の作成

可視化ツールの作成

f:id:kurupical:20180601223524j:plain:w500

def visualize_bar(df,
                  target_name="TARGET",
                  output_path=None):
    """
    分析対象のcolumnとTARGETの関係を棒グラフにする

    :param df:
        columns=[分析対象column, TARGET]
    :return:
    """

    column = list(df.drop([target_name], axis=1).columns)
    df_count = df.groupby(column).count().sort_index()
    print("columns_unique_num:{}".format(len(df_count.values)))

    if len(df_count.values) > 200:
        print("columns is too big to output bar")
        return

    yticks = []
    for index, count in zip(df_count.index, df_count.values):
        tmp = "{} (N={})".format(index, count[0])
        yticks.append(tmp)

    plt.figure(figsize=(8, len(df_count)*0.6))
    sns.barplot(x=target_name, y=column[0], data=df, orient="h")

    plt.axvline(df[target_name].mean(), ls=":", label="all_mean")
    for i in range(len(df_count.values)):
        plt.text(0, i, "N={}".format(df_count.values[i]))
    plt.legend()
    plt.savefig(output_path)
    plt.close()

このツールを作ったことで、自分が作った特徴量の評価がしやすくなりました。

特徴量の作成

データから、「顧客IDごとの、現在返済中借金の件数」という特徴量を作りました。
棒グラフがカラフルなのはデフォルト設定で、僕のセンスじゃないです。

f:id:kurupical:20180601223822j:plain:w500

現在返済中借金の件数が多いほど、債務不履行になる確率が高くなるのがわかります!

以下は学習器が出力する「分類に使った大事な特徴ランキング」なのですが、僕が作った項目(*ACTIVE_COUNT)が上位にランクインしています。(全部で200項目くらいあるうちの30位) f:id:kurupical:20180601224432p:plain:w500

まとめ

  • 特徴量作成が捗るツールを作った。
  • いい特徴量が1個つくれた。

こんな感じで、全体データを眺めては特徴量を作成する、というのをしばらくはもくもくと続けることになりそうです。

<実践>HomeCredit作業記録(3) - FeatureEngineeringのアプローチ

Kaggle挑戦中です!
債務不履行になる人を予想するタスクです。
Home Credit Default Risk | Kaggle

最近は特徴量エンジニアリング(FeatureEngineering)をやっています。

やっている中で気づいたことがあるのでブログにします

特徴量エンジニアリングのアプローチ

特徴量エンジニアリングを、ボトムアップでやっていたのですが、どうやら最初は「トップダウン」でやるほうがよさそうです。

※業務経験2ヶ月の新米データサイエンティストのいち考察として読んでいただければ幸いです。。

ボトムアップ

https://www.kaggle.com/c/home-credit-default-risk/data データの特徴量(=項目)を1つずつ吟味して、特徴量を生成する
以下は、「クレジットカードの返済期限を過ぎてしまった回数」という特徴量を作成しました。
(返済期限を過ぎた人が多いほど債務不履行になるのでは?という私の推測から)

def count_credit_day_overdue(df):
    """
    credit_day_overdue>0の件数を、ユーザーIDごとに数える
    :param df:
    :return:
    """
    def _count_over_zero(array):
        count = 0
        for val in array["CREDIT_DAY_OVERDUE"].values.flatten():
            if val > 0:
                count += 1
        return count

    df_tmp = df[["SK_ID_CURR", "CREDIT_DAY_OVERDUE"]]

    series_count_by_id = df_tmp.groupby("SK_ID_CURR").apply(_count_over_zero)
    series_count_by_id.name = "*DAY_OVERDUE_COUNT"

    df_count_by_id = pd.DataFrame(series_count_by_id).reset_index()
    return df_count_by_id

・・・こんな感じで2,3項目を作ってみたのですが、これじゃ日がくれそうです。
KaggleのKernelを見ると・・・トップダウンアプローチで作っている人が多いです。

トップダウン

    output_dir = "../../data/edited/all_mean"
    label_enc = LabelEncoder()

    def labelencode_cat(df):
        df = df.copy()
        cat_var = df.select_dtypes(['object']).columns.tolist()
        for col in cat_var:
            df["category_{}".format(col)] = label_enc.fit_transform(df[col].astype('str'))
            df = df.drop(col, axis=1)
        return df

    original_dir = "../../data/original"

    def output_mean(df, filename):
        df_avg = df.groupby("SK_ID_CURR").mean().reset_index()
        output_csv(df=df_avg,
                   output_path="{}/{}.csv".format(output_dir, filename))

    print("bureau")
    fname = "bureau"
    df_bureau = pd.read_csv("{}/{}.csv".format(original_dir, fname)).pipe(labelencode_cat)
    df_bureau = df_bureau.drop("SK_ID_BUREAU", axis=1)
    output_mean(df=df_bureau,
                filename=fname)
    del df_bureau

ざっくりと全部の項目についてユーザーごとに値の平均を取って、特徴量としてしまう。
なんと大雑把なー!!と思ったのですがこっちのほうが良さそうです。

なぜトップダウンがいいのか?

ローコスト

とにかく楽です。30行くらいのコードで、全ファイルの特徴量ごとの平均が取れちゃいました。

大事な項目を絞り込める

上記のような形で全部のデータをLightGBMやXGBoostなどの学習器で学習させると、feature_importances_を出力してくれます。

f:id:kurupical:20180530213313p:plain:w500

この図でわかることは、「予測にあたり学習器が重要視した項目」です。
つまり、(平均という大雑把なやり方とはいえ)重要な項目がなんとなくつかめます。
ここから、各項目について「ボトムアップ」で、特徴量作成するのがいいような気がします。

トップダウンのデメリット

カテゴリ変数(=文字列項目)の平均?

機械学習にかけるときは数値変換をする必要があります。
動物であれば、うさぎ=1、象=2、犬=3、・・・など。1
カテゴリ変数の「平均」を取ると、うさぎと犬の平均は象!?みたいな変なことになります。
トップダウン的なアプローチは、「数値」にのみ有効なんだと思います。

まとめ

最初からボトムアップで泥臭くやるより、トップダウン→特徴見てボトムアップのほうが当たりがつきやすく、素人にはよいのかもしれません。

途中経過

f:id:kurupical:20180530214633p:plain:w500

score: 0.706 -> 0.735
順位: 936位/1197 (上位80%)


  1. LightGBMはカテゴリ変数に対応しており、OneHotEncodeしなくてもよい