KaggleカーネルでBigQuery MLを使う

KaggleのカーネルでBigQueryが公式にサポート

先日(2019/6)、KaggleのカーネルでBigQueryが公式にサポートされました。

cloud.google.com

早速、使ってみようと思ったのですが、デフォルトでは開催中のコンペに対して

client = bigquery.Client()
dataset_ref = client.dataset("titanic", project="kaggle-official")

のような感じでデータセットとして指定できる訳ではなく、あくまで自分のGCPプロジェクトにデータセットを用意する必要があるようです。(せっかくなら直接アクセスできるようにして欲しい。。。)

 

ということで、実際のコンペ(Titanic)のデータからBigQueryデータセットおよびテーブルを作成するカーネルを公開しました。テーブルを作成したあとは、BigQuery MLを使ってロジスティック回帰でモデルの作成および予測を行い、submitファイルの作成をしています。簡単のためCVは行なっていませんが、PublicLBで0.722くらいが出ます。

 

ぜひ、BIgQuery MLを触ったことがない方は、これを使ってカーネル上で遊んでみてください。必要なものはGCPプロジェクトとの紐づけのみで、GCPコンソール上でのデータセットの操作は一切不要です。 

www.kaggle.com

 

BigQueryデータセットおよびテーブルを作成、と言っても単にカーネル上からgoogle.cloud.bigqueryクライアントを実行しているだけです。(データが大きければ結局GCSが必要になるはずなので、あまり汎用性ない)

 

下記のカーネルの画面で「BigQuery」をクリックして、

 

f:id:toshikishimizu:20190713233750p:plain

 

下記の画面で「Link an account」するだけです。

f:id:toshikishimizu:20190713231739p:plain

 

当たり前なのかもしれませんが、外部のサービスと連携させているため、

  • 冪等性
  • 非同期処理

辺りを意識して実装する必要があります。(普段カーネルを作る際は、カーネル内にスコープが閉じているので、冪等性を意識しなくてもよかった)

 

公開したカーネルでは、BigQuery MLの学習ジョブをポーリングしていますが、もっといいやり方があったら、コメントで教えていただけると嬉しいです。

 

 今後もGCPとKaggleが連携しやすくなっていくと、コンペが捗りそうですね!

BigQueryテーブル作成用のスキーマを自動生成する

GCPではCloud SDKなどでbqコマンドを使うことでBigQueryを扱うことができる。

 

さて、bqコマンドを使ってGCSにあるCSVからtableを作成する。BigQueryにはスキーマの自動検出がサポートされており、オプション--autodetectをつけてコマンドを実行すれば良い。

bq  load --autodetect  [DATASET].[TABLE] [PATH_TO_SOURCE]
BigQuery error in load operation: Error processing job 'clear-eye-231300:bqjob_r107534c5e807c9a3_00000168e21cb11a_1': Error while reading data, error message: CSV table encountered too many errors, giving
up. Rows: 1291; errors: 1. Please look into the errors[] collection for more details.
Failure details:

 失敗しとるやんけ。。。ドキュメントによると

自動検出を有効にすると、BigQuery はデータソース内でランダムにファイルを選択します。ファイルの最大 100 行をスキャンして代表的なサンプルとして使用し、推定プロセスを開始します。BigQuery は、各フィールドを検証し、そのサンプル内の値に基づいてそのフィールドにデータ型を割り当てようとします。

なるほど。。。

どうやらデータによっては自動検出はうまく動かないようだ。スキーマjsonに記述しても良いが、カラムが多いと正直大変だ。部分的にでも自動検出の結果が使用できれば嬉しいのだが、特にAPIはなくloadが失敗してしまうと自動検出の情報は取得できない。

 

そこで、スキーマのテンプレートを自動で生成したい。何を使っても良いのだが、ここではpandasのdtype情報を利用する方法を考える。サンプルスクリプトを作成した。

https://github.com/ToshikiShimizu/kaggle/blob/master/tool/source/generate_bq_fmt.py

このスクリプトを実行するとtable_schema.jsonが生成される。今回はサンプルであるので全てのカラムをSTRING型としているが、データに合わせて適宜修正を加えてほしい。

 

このスクリプトを作って生成したjsonを使って、

bq  load   [DATASET].[TABLE] [PATH_TO_SOURCE] table_schema.json

とすれば無事にtableが作成される。

 

もっと良い方法があればぜひコメントをお願いします!

Kaggle - Home Credit Default Risk挑戦記録

はじめに

Home Credit Default Riskに参加し211/7198の成績を収め、シルバーメダルを獲得することが出来ました。前回の記事は「Kaggle初挑戦」というテーマで書かせていただいたので、今回は「Home Credit Default Risk」をテーマにしたいと思います。私の経験不足&力不足で正直駄文だと思いますが、温かい目で読んでいただけると幸いです。間違いやご意見がありましたら、ぜひコメントをお願いいたします。 ↓前回の記事 toshikishimizu.hatenablog.com

参考になる記事

ちなみにid:kurupicalさんが書かれた記事があり、明らかにこの記事の上位互換なので、まだ読まれていない方は先にご覧になってください。Home Credit Default Riskがどういうコンペなのか、図を交えて非常にわかりやすく説明されています。 kurupical.hatenablog.com

目次

コンペの概要

複数のテーブルデータを用いて、顧客がローンの支払いを遅延するかどうかを予測します。

やったこと

開発環境

ローカルとクラウド(GCP)の両方を使いました。Jupyter NotebookによるEDAスクリプトデバッグをローカルで行い、本番はGCPで計算させていました。正直このやり方だとコードの管理が微妙だと思ったので、次回のコンペでは改善したいですが、よくわかりません。多分、常識的なレベルなのでしょうが知見がございましたらぜひ教えてください。
- 最初からすべてサーバで開発(Jupyter Hub + vim or emacs)
- gitでローカルとサーバのコードを同期しながら開発
とかでしょうか?

GCP

$300のクーポンがもらえますのでGCP(Google Cloud Platform)のGCE(Google Compute Engine)を使いました。私の場合$200で三か月間のコンペを乗り切ることが出来ましたので、(もちろん人によりますが)最初のコンペはこのクーポンだけで十分戦えると思います。インスタンスを何度か立て直したり、並列実行するために複数立てたりするので、初期設定用のスクリプトを書いておくと便利です。たとえば私は以下のようなスクリプトを使っていました。(あくまで一例です)

wget https://repo.anaconda.com/archive/Anaconda3-5.2.0-Linux-x86_64.sh
bash Anaconda3-5.2.0-Linux-x86_64.sh
source ~/.bashrc
sudo apt-get update
sudo apt-get install unzip
sudo apt-get isntall htop
pip install lightgbm
pip install tqdm

mkdir input output feature source
gsutil -m cp -r  gs://kaggle-hcdr/input/* ~/input
cd ~/input
unzip files.zip

私はコンペの最初にGCS(Google Cloud Storage)にデータを置き、そこからGCEにgsutilでコピーするという方法をとっていました。KaggleはAPIでデータがダウンロードできるのでそれでもいいかもしれません。

モデル

LightGBMを使いました。XGBoostも使いましたが、前者の方が私にはあっている気がして、前者に落ち着きました。 ニューラルネットワーク(Keras)も色々と試してみましたが、LightGBMよりも結構スコアが悪かったので採用はやめました。 釈迦に説法ですが、LightGBMには - 学習が比較的高速
- 欠損値に対応
- 自動でone-hot encoding
- 特徴量が増えても副作用軽微
などのメリットがあり、画像系コンペでなければとりあえず使っておいて間違いはないです。

CV

straified-kfold(k=5)

startified-kfold(k=5)を使用しました。それぞれのfoldでテストデータに対しても予測を行い、foldで平均をとったものをモデルの出力としました。コンペにおいては信頼できるCVを出せるようにすることが極めて重要といわれています。今回の私のCVは、モデルのseedを変えるとスコアが結構変わってしまったりして、本当にこのCVを信頼してよいのか不安になることも多かったです。モデルのseedを変えながら複数試行して平均をとればよいのですが、そうすると時間がかかりすぎます。どうやってCVスコアを計算し、扱うかはとても奥が深いと思いました。

他の参加者のCVスコアについて

"Trust your local CV."という金言があり、おかげで私も617位(PublicLB)→211位(PrivateLB)というshake upを果たせました。コンペ中はどうしても自分が集団のどの位置にいるかが気になってしまいます。CVは自分のスコアの変化を知ることはできますが、他者との比較が難しい(計算方法が違う・そもそも公開されない)ので、頭では、"Trust your local CV."を理解していながらも、やはりPublicLBを気にしてしまいます。そこで、主要なカーネルは実際にローカルで動かし、あなたの計算方法でCVを出すことをお勧めします。そうすることでカーネルのモデルはCVとPublicLBにどれだけ乖離があるかを知ることができます。ベストカーネルをコピペで出してくる参加者は多く、結構なボリュームゾーンとなります。それらより少し良いCVを出せていれば(PublicLBが悪くても)メダルは取れると思います。

特徴量

特徴量の管理

featherで管理しました。csvよりも容量が大きいですが、読み書きが高速です。この辺りは人によってやり方が色々あるようです。featherを用いた管理についてはid:amaotoneさんの以下の記事とGitHubを参考にさsていただきました。 amalog.hateblo.jp

特徴量エンジニアリング

多くの人がやっている通り
- 既存のカラム同士の四則演算
- min,max,mean,var,countなどを用いた集計
などを中心にオリジナリティがあるものも数個足しました。最終的には特徴量の数は1000くらいになりました。LightGBMは特徴量を増やしすぎても致命的な副作用はでませんが、無駄な特徴量があると学習も遅くなるので、思考停止して特徴量を量産するのはあまりよくないです。自作にしろコピペにしろ「狙いをきちんと説明できる特徴」を採用するのが重要だと感じました。目的をもって特徴量を作ると、あまり効果がなかったとしても、そこから何らかの知見を得られることが多いです。

CVの確認

特徴量生成の試行錯誤の過程で新特徴量の有無でCVがどう変化するのを知りたい時があります。このとき既存の全ての特徴量を使って学習するのではなく、「新特徴量に関連するもの」と「コンペで明らかに重要な特徴」だけで学習させました。
- 特徴量の追加に対してスコアが敏感になる
- 学習が速く、試行錯誤を増やせる
などのメリットがあると思います。

特徴量の削除

基本的には削除は行わない方針で行きました。ただし、何度か実験する中で、importanceが0のものはさすがに無駄だと思い削除しました。 また、過学習の可能性があるのでimportanceが高いからといって良い特徴量とは限りません。そこで最初から与えられているカラムに関しては、一つカラムを削除してCVを計算する操作をすべてのカラムに対して行い、削除した場合の方がCVが改善しないかをチェックしました。この方法は、RFE(Recursive Feature Elimination; 再帰的特徴量削減)っぽいですが重要度ではなくCVスコアに基づいて行いました。

ハイパーパラメータ

kernelのハイパーパラメータを手動で弄りながら使っていました。途中、グリッドサーチやhyperoptを試してみたのですが、時間をかけている割にはあまり精度が変わりませんでした。それよりも特徴量エンジニアリングに時間を割いた方がよいと思い、チューニングはあきらめました。また、ハイパーパラメータを弄り始めると今まで検証してきた実験の前提が変わり、やり直したくなってしまいます。基本的にはコンペ終盤までは固定でよいと思いました。

学習率

多くの場合で学習率を下げてステップを増やせば、精度が上がります。一方、これらの工夫は特徴量エンジニアリングとは切り離して考えられます。そこで、試行を速く回すために学習率は大きめ(0.1くらい)にしておいて、コンペ終盤に小さく(0.01-0.02くらい)しました。

アンサンブル

k-foldとLightGBMのseedを変えて複数の予測を行い、それらを平均してみましたがPublic LBが大きく変わることはありませんでした。(後から気づきましたがk-foldのseedを変えてしまうと、アンサンブルモデルのCVを算出することができなくなってしまうので、あまり得策ではないかもしれません。)結局、最後のサブミッションの一つはCVが最も高いシングルモデルの出力をそのまま提出しました。もう一つのサブミッションでは、そのモデルの予測ととベストカーネルの予測をブレンドしました。ブレンドする際は分散を統一するなどの処理が必要です。結果論ですが、どちらのスコアももあまり変わらなかったようです。コンペ終盤は仕事で時間が確保できなかったので、次回はここら辺もしっかりと取り組みたいです。

情報収集

ホットなKernelやDiscussionは基本的に目を通した方がよいです。自分が悩んでいることがすでに解決されていたり、今までになかった視点でデータを見れるようになります。また、自分がどういうオリジナリティをもって取り組めているかの比較ができます。

さいごに

Home Credit Default RiskでKaggleに初挑戦し初メダルを取れたことは本当にうれしかったです。日本のkaggleコミュニティ(slack, twitter)は大変優れており、ほとんどがそのおかげといっても過言ではないです。ありがとうございました!

最近は画像コンペしかなく参加するか迷っていたのですが、先日Google Analytics Customer Revenue Predictionという新しいコンペが始まりましたので、次はこれに挑戦したいと思います!

記事を最後まで読んでいただきありがとうございました!

Kaggle初挑戦でシルバーメダルを取った話

先日KaggleのコンペHome Credit Default Riskに参加し211/7198の成績を収め、シルバーメダルを獲得することが出来ました。 せっかくなので、取り組んだことを記事として残してみたいと思います。今回のコンペ固有の話というより、どのようにKaggleに取り組んだかについて焦点を絞ってまとめてみたいと思います。

 

想定する読者

  • Kaggleを始めてみようと思っている方
  • Kaggleを始めたけど、何をしていいかわからない方
  • Kaggleを始めたけど、まだメダルが取れていない方
  • お世話になった先駆者の方々

1. Kaggleのアカウントを作成

アカウントがないと何も始まりません。公式ページにアクセスして作りましょう。 (私は何年か前に作っていたのでパス)

2. 情報収集

Kaggleを進めていくうえで 時間を無駄にしないこと・モチベーションの維持 などが重要だと思いますので、使える情報は積極的に使っていきましょう

2.1 ブログ

色々ありますが、一例として私が勉強させていただいた記事を紹介します。

2.2 動画

「Kaggle入門動画をつくった」
http://yutori-datascience.hatenablog.com/entry/2017/10/24/215647
@tkm2261さんが公開されている大変すばらしい動画です。ぜひご覧になってください。

2.3 Slack

kaggler-slack
https://kaggler-ja.herokuapp.com/
日本Kagglerのslackです。日々登録者が増えており、強くて親切な方々がKaggleの事ならどんな質問にも優しく答えてくれます。(正直Kaggle関係ねーだろって質問も・・・)

2.4 Twitter

コンペは長期戦で、結構しんどいです。周りの様子が見えるとモチベーションが維持出来たり、ペースのコントロールに役立ちます。 (Kaggleではprivate sharingが禁止されているので、開催中コンペの直接的な情報を得ることはできませんが、上級者のツイートからヒントを得られることも・・・)

2.5 書籍

2018年9月現在、特に出版はされていないかと思います。 しかし、専業Kagglerのカレーちゃんさん(@currypurin)がkaggleの入門に最適な「kaggleのチュートリアル」という本を書かれています。 私も購入できてはいないのですが、プレビューを拝見したところとても良質な内容だと感じております。以下のリンクからプレビュー出来ます。
http://www.currypurin.com/entry/2018/02/26/001207

機械学習やプログラミングの経験が浅い方は、そちらの書籍などが手元にあるとよいかもしれません。

2.6 公式ページ

雰囲気知るためにいろいろと探索してみましょう。

3. コンペへの参加

そろそろ気持ちも高まってきたと思うので、コンペに参加しましょう。 チュートリアルとしてはTitanicが有名です。 こういった過去のコンペですと、解法の解説やコードが手に入るので、取り組みやすいかと思います。雰囲気を掴めたら開催中のコンペに突っ込みましょう。 開発環境についてですが、最初のうちは基本的には使い慣れているものでよいと思います。 私はwindowsデスクトップ、MacBookPro、Google Compute Engineなどを色々と使ってPythonで開発していました。

4. コンペ

ここからは試行錯誤しながら頑張ってみてください。私が特に重要だと思ったのは

  • スケジュール管理
    コンペは長期戦です。期間中は例えば、序盤:EDA→中盤:特徴量エンジニアリング→終盤:パラメータ調整・アンサンブルというような流れになると思いますが、自分のできる範囲でスコアを最善にするために、どの期間に時間が確保できるのかを把握して、どのようにコンペに取り組んでいくのかを随時管理する必要があります。

  • 特徴量エンジニアリング
    何を当たり前の事をって感じですね。コンペによりますが、基本的にスコアを大きく左右しているのはモデルやハイパーパラメータよりも特徴量です。如何に時間をかけて多くの特徴量を試せるかがコンペの勝敗のカギを握っていると言えます。よく用いられるLGBMなどの木系のモデルは特徴量が増えすぎても性能が悪くなりにくいので、恐れずにどんどん特徴量を生成しましょう。

その他に

  • モチベーションの維持

  • ソースコード・特徴量の管理

  • Kernel, Discussionでの情報収集

なども大事です。期間中、これらに真剣に取り組んだことでメダルが取れたのだと思います。詳細はHome Credit Default Riskの振り返りとして、別途記事にできたらなと思います。

5. 最後に

みなさん、良いKaggle Lifeを!

はてなブログを始めようと思います

はてなブログを始めようと思います。

 

目的は「Kagglerとしての実力をつけるため」です。具体的には、

  • 記録を残すことで知識の再利用を可能にする
  • アウトプットする過程で知識の整理を行う

といった形で実力をつけていきます。

 

記事は基本的には、Kaggle関連の内容にするつもりです。

  • 参加したコンペのまとめ
  • Kaggleに有用なツール・テクニック
  • その他備忘録など

などをまとめていけたらなと思います。

 

続けられるかはわかりませんが、少しずつやっていきたいと思います。どうぞよろしくお願いいたします。まずは、近日中にHome Credit Default Riskについて書くつもりです。