kaggleの雑記

給与推定コンペとkaggleで勝つデータ分析の技術で急成長した話

ある日ぼんやりとtwitterを眺めていたら、kagglerのwakameさんのtweetを見つけました。全てはここから始まりました。

本記事の概要

コードを公開しました!

https://prob.space/competitions/salary-prediction/discussions/hirayuki-Post7e04622d00218ebc3c02

なぜ書いたのか

本記事では給与コンペkaggleで勝つデータ分析の技術を使って、分析の技術を少し身につけられた経験を共有したいと思います。

私と同じようにkaggleの問題が難しすぎて次どうしたらいいかわからない人に向けてお役に立てばと思います。

実際どれくらい成長したのか

スコアは小さい方が精度が高いです。実際のランキングとスコアの分布はこちらのページからご確認ください。

2019年12月5日現在においては220人中100位でした。だいたい上位はスコア20台に入っており、スコア30を超えてしまうと下位20%以下に入ってしまいます。

そんな中24.5のスコアを初心者の私が出せたのは驚きです!

給与推定コンペとは

ProbSpaceの開催しているコンペです。今回これに挑んだ理由は簡単だからです!

データが簡単

  • position 役職(0=役職なし, 1=主任, 2=係長, 3=課長, 4=部長)
  • age 年齢(歳)
  • area 勤務地
  • sex 性別(1=男性, 2=女性)
  • partner 配偶者の有無(0=なし, 1=あり)
  • num_child 子供の人数(人)
  • education 教育(0=高校, 1=短大専門学校, 2=大学, 3=修士, 4=博士)
  • service_length 勤続年数(年)
  • study_time 一週間あたりの勉強時間(h)
  • commute 通勤時間(h)
  • overtime 一ヶ月あたりの残業時間(h)

こんな風に意味が一目瞭然日本語でデータの意味が説明されています!

提出形式が簡単

id,y
0, 324.5
1, 694.3
2, 495.2
3, 200.4

上のデータが提出の形式(一例)ですが、IDに対して給与を数値として予測するだけです。

結論

初心者の皆さんはぜひKaggleで勝つデータ分析の技術を片手に、ProbSpaceの給与推定コンペに挑戦してみてください!

 

 

これだけだとつまらないので、私がこの本を手に取って四苦八苦したコントを書かせていただきます。本当にちゃんと成長したければもっと有用な記事がございますが、初心者の苦労の共有・あるあるとしてご覧いただければと思います。

以下、コント

拾ってきたlightgbmをコピーして使う

https://www.codexa.net/lightgbm-beginner/

上のリンクはlightgbmの名著です。一冊の本にするべきくらいわかりやすく書かれています。

このなかにあるコードを丸々コピーしました。

params = {
    'task': 'train',
    'boosting_type': 'gbdt',
    'objective': 'multiclass',
    'num_class': 10,
    'verbose': 2,
}

gbm = lgb.train(
params,
train_data,
valid_sets=eval_data,
num_boost_round=100,
verbose_eval=5,
)

これで実行したところエラーが起きました。

当然です。目的変数が数値型の回帰問題なのにそれを10種類に分類しようとしているのですから。

LightGBMError: Label must be in [0, x), but found y in labelが出た時の対処法LightGBMError: Label must be in ....と言われて嵌った話 lightgbmを初めて使った頃に下記のよ...

これは(実行させたいだけなら)分類したいクラス数に合わせてpramas.num_classを調整する必要があります。

この時給与コンペの目的変数である給与は1100(万)まであったので、num_classを1100にすることで無事に実行できました!(笑うところです‘objective’: ‘multiclass’となっていることが根本的な間違いです。

この時のスコア:106.88995

なんとなく手でparamsを変更する

こちらのlightgbmについてまとまっている記事公式ドキュメント(Parameters Tuning)にparamsの設定方法が書かれています。

これだけを参考に過学習しないように、適当なパラメータを作成しました。(この時のパラメータを残すのを忘れてしまいました。)

主にnum_leavesとlearning_rateを直すだけでも随分とマシになり、この時のスコア

この時のスコア:58.41037

optunaを実装する

lightgbmとoptunaで検索して実装してみました。参考にした記事はこちらです。

これによりparamsのなかにあるハイパーパラメータはこちらが自動で選択できるようになりました。

def objective(trial):
    # <中略> 
    return accuracy
study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=100)

以下2点で失敗し、時間を溶かしました。

  • このobjectiveの返り値が大きな値であるほどポジティブに捉えることに気が付かなかった
  • random_seedを設定していなかったため、再現性が無かった

しかしこれにより、一番適切なパラメータを選択できるようになりました。

この時のスコア:56.41910

特徴量を生成しまくる

ここからがKaggleで勝つデータ分析の技術のすごいところです。特徴量生成に関するあらゆるコツが書かれています。

カテゴリ変数・数値変数の扱い、それぞれを組み合わせてどのように特徴量を生成するか。encodingの方法などなど。

それらをすべて試したところ、(中には精度悪化するものもあったのですが・すぐにやめて)精度はグンと向上しました!(回帰問題を多分類モードで説いているにも関わらず笑)

この時のスコア:44.42915

回帰問題を多分類モードで説いていることに気が付く(笑)

本記事一番の大ボケです。

こちらの記事を参考にしていただくとわかりやすいのですが、機械学習は目的変数次第で、回帰問題と分類問題に大きく分けられます。

回帰問題は株価予測など数値を予測するもので、分類予測は「YesかNoか」「犬か猫かうさぎか」というせいぜい多くても10種類(?)の分類です。

ligthgbmではobjectiveで設定しています。下の様に記載すると多分類

params = {'objective': 'multiclass','num_class': 10}

下記で2値分類

params = { 'objective': 'binary'}

下記で回帰問題です。

params = {'objective': 'regression'}

今回は給与推定問題なので回帰問題です。この設定に変えることでスコアは一気に上昇、計算速度も速くなりました。

この時のスコア:28.59000

交差検証を取り入れる

(ここからはネタ的な面白い要素はないので淡々と書こうと思います・・・)

Kaggleで勝つデータ分析の技術それをそのまま真似して交差検証をsklearn.model_selection.KFoldで実装しました。

この時のスコア:27.70131

特徴量生成の章を再度読み込む

特徴量生成でやれることはまだないかと探っているとまだまだ見つかりました。データを見ては本を読んで、データを見ては本を読んで。そうしていると特徴量生成だけでもたくさんの学びがあります。

この時のスコア: 25.82300

「target encodingは強力」という文章を見つける

Kaggleで勝つデータ分析の技術に「target encodingは強力」という一文を見つけました。

なんのこっちゃ!

こんな私でも本を読んだら30分で実装できました。また概要についてもざっくりと理解することができました。

この時のスコア:24.91910

もう1回optuna

その時の特徴量によって最適なハイパーパラメーターは変わるようです。最適値を再度学習させます。その結果またスコアが伸びました。

この時のスコア:24.50361

以上、初心者のコントでした!同じように駆け出しの人のお役に立てばうれしいです!お読みいただきありがとうございました。
ABOUT ME
hirayuki
今年で社会人3年目になります。 日々体当たりで仕事を覚えています。 テーマはIT・教育です。 少しでも技術に親しんでもらえるよう、noteで4コマ漫画も書いています。 https://note.mu/hirayuki