今年も例年同様、jupyter notebookを眺めていたら、いつの間にか夏が終わっていました。
フェスといえば、パリピがインスタ映えのために行く野外音楽イベントやナイトプールでのDJイベントではなく、
Kaggleのコンペを意味する皆様において、今年も実りの多い夏であったかと思います。


さて、パリピがトークネタを常に更新し磨きをかけるように
データサイエンティストも、自らのノウハウを整理しておかなければ、
いざという時に活用できないことは言うまでもありません。

そこで、Kaggleや普段の業務を通して得られた
ここ最近の機械学習のTipsを自らの備忘録として記載したいと思います。
※すでにご存知の方は、安心してナイトプールでインスタしててください。

<<目次>>
(1) 環境編:GoogleCloudPlatformとDataLab
(2) 前処理編:クロスフィーチャーの自動生成
(3) 機械学習編:CatBoostとベイズによるハイパーパラメーター探索


| (1) 環境編:GoogleCloudPlatformとDataLab
最近のKaggleコンペは画像系が増加しており、
またそうでなくても、数百万レコードのデータを用いるものがスタンダートとなります。
そのようなデータを処理するには大きなStorageが必要であることはもちろん、
処理するマシンの性能もできれば良いものを用意しておきたいところです。
そこで、最近はGoogleCloudPlatformを用いることが増えましたので、
備忘録がてら、基本操作を整理しておきます。

GoogleCloudPlatformでは様々な機能が提供されておりますが、
機械学習においては、特にStorageとDataLabを利用することになると思います。

– Storage:クラウドストレージ
– DataLab:クラウド上のオンラインnotebook。基本的な機械学習ライブラリはデフォルトインストール済み(新規追加可能)


多くの人はすでにGoogleアカウントを取得済みかと思いますので、
ログイン後、GoogleCloudPlatformにアクセスします。



左のメニューバーから「Storage」を選択、「ブラウザ」とすることで、
自分の利用中のバケット(Storageの単位のようなもの)一覧を閲覧することができます。



「バケットを作成」を選択すると、新規でバケットを作成することができます。
利用用途にあわせて、詳細設定しましょう。
※自分の場合は、機械学習用途で個人利用が多く、
 公開するウェブサービスではないので、世界中からアクセスすることを
 想定しなくてよいので「デフォルトのストレージクラス」を「Regional」、
 コストが安いため、場所を、「us-central1」にすることが多いです。
※後から変更可能です。



これでバケット一覧に瞬時に反映されます。あとは、そのバケットを選択すると、
ファイルのアップロードやフォルダの作成などを行うことができます。
Kaggleなどの場合、ここにファイルをアップロードすると次に説明するDataLabからの利用がやりやすいです。
※コマンドラインからもファイルアップ可能
※GoogleのKaggleコンペの場合、そもそもGoogleCloudStrage上にファイルがオープンにアクセス可能になっている場合が多い。
 その場合、もちろん、自分のStorageへのコピーは不要。


さて、次にDataLabの準備にとりかかります。
DataLabは、オンライン上のnotebookとなります。
人によるかもしれませんが、普段コマンドラインではなくnotebookで分析作業している方は、
非常に便利な機能となります。

DataLabの利用には、DataLab用のVMインスタンスを立ち上げることになります。
まずは、右上のメニューボタンの一番左の「Cloud Shellをアクティブにする」を選択します。



次に今回の分析用のインスタンスを作成します。
※あらかじめ、インスタンスを作成する必要はなく、DataLabのcreateコマンドで自動でインスタンスが生成されます。



上記により5分ほどでインスタンスが立ち上がります。



インスタンスの準備ができたら、シェルの右上のプレビューから、「ポートの変更」で「8081」を選択することで、
DataLabが立ち上がります。



下記がDataLabの画面となります。後は新規notebookを追加して、(いつもの通りに)作業すればよいことになります。


ちなみに、一度立ち上げた後は、次回からはVMにConnectすることで利用できます。



なお、DataLabを利用中に、もっとマシンパワーが欲しい、となった場合、
都度変更が可能です。ここら辺がクラウドの良いところですね。
※左上メニューの「Compute Engine」から「VMインスタンス」を選択、
 該当のインスタンスを選択します。




ちなみに、、あくまでご参考までですが、
「n1-standard-8(vCPU x 8、メモリ 30 GB)」のスペックで
Kaggleのとあるコンペへの2週間での断続的な利用で、
¥4,035となりました。
相当ビビりながら使用しましたが、
もっとハイスペックのCPUのものを利用してもよかったかもしれません。

DataLabから、Storageのデータを読み込むには下記のようにします。
(mirandora_sample_storageというstorageの中のinputフォルダの中のファイルを読み込む場合)



ちなみに、DataLabの分析結果などを、逆にStorageに書き出すには下記のようにします。
※dataframeの表示が短縮されて書き出されてしまう場合があるので、
 その場合は、dataframeのmaxの表示行を増やしておきます。




| (2) 前処理編:クロスフィーチャーの自動生成
どのような機械学習手法を用いるにせよ、特徴量の前処理および生成が重要なのは言うまでもありません。
いくつかの特徴量を掛け合わせて新しい特徴量を生成することも必要な時もあるでしょう。
ここでは、クロスフィーチャーの自動生成を行うためのPythonコードを備忘録がてらまとめておきます。

クロスフィーチャーとは、既存のフィーチャー(特徴量)をクロス(加算、乗算、など掛け合わせ)して
新たな特徴量を生成することです。
なぜそれが良いかというと、下図左側のように、既存の特徴量では線形分離不可に見える分布も、
z = x^2 + y^2という新たな特徴量を生成することで分離できるようになることがあるためです。


しかし、このようなクロスフィーチャーを手動で様々な高次の組み合わせを作成するのは手間になります。
そこで、scikit learnのPolynomialFeaturesの出番となります。

PolynomialFeaturesは、入力した変数に対して、指定した次元の多項式を自動で生成してくれます。
例えばdegree=2で[x1, x2]を入力すると、
[x1**2, x1*x2, x2**2, x1, x2]を自動で計算してくれます。
あまり変数を多くしたり、次元を高くすると、多くの無駄な特徴量を生成することになりますので、
まずは、様々なクロスフィーチャーを生成してみて、重要度が高い組み合わせを残す、
などの処理が良いかもしれません。

既存のDataFrameのx1,x2,x3から新規でクロスフィーチャーを生成してマージするコードは下記となります。




| (3) 機械学習編:CatBoostとベイズによるハイパーパラメーター探索
機械学習手法は、主に、決定木系とニューラルネット系があると思いますが、
決定木系では、XgBoost、LightGBMが精度が高く、良く用いられておりました。
しかし、ここ最近、上記2手法より精度が高い(とベンチマークテストでは言われている)CatBoostという手法が開発されました。
実際、オンラインカーネルで、CatBoostを利用したものを良く見かけます。

CatBoostとは、ロシアのYandexが開発した勾配ブースティング系アルゴリズムでして、
2017年7月に発表されました。(そのため、記事にするには、やや時期を逃した感がありますが、。汗)
こちらが、公式サイトでして、アルゴリズムの特徴などが掲載されておりますので、
一度目を通して見ると良いかと思います。
ちなみに動画もあります。



超ざっくり言うと、Xgboostなどよりも過学習をおさえるように作られているとのことで、
データから異常値を検出するタスクにもっとも適しているとのことです。
実装は簡単で、カテゴリデータなどのサポートもやってくれます。

DataLabで利用する場合は、新規でインストールが必要ですので
インストールと合わせて下記のように行います。




実際には、XgBoostやLightGBMとのアンサンブルなどで並列使用するのがよいかもしれません。
ちなみに、私も過去Kaggleのコンペで2回使用しましたが、XgboostやLightGBM単体よりも
CatBoost単体の方が、精度が高かったです。

さて、Xgboostしかり、Catboostしかり、ハイパーパラメータの探索が重要です。
従来、ハイパーパラメータの探索は、grid searchなどで行うことが常套手段でしたが、
時間がかかりすぎるという問題がありました。
そこで、もう少し効率良くベストなハイパーパラメータを探索する方法として、
ベイズで最適化する手法が提案されています。
※KaggleのKernelでも”parameters found by Bayesian optimization”というフレーズを良く見ますね。

実装は下記のように行います。
(こちらの記事を参考にさせていただきました。)



たとえば、とあるデータでXgBoostのパラメータをベイズ最適化で
探索したときの精度の推移は下記のようになりました。




いかがでしたでしょうか。
とは言っても、上記を書いている最中にも、
また次のコンペが始まり、新たなトレンドが次々と生まれてきますので、
いつまでたってもナイトプールに行ける日は来ないでしょう。
むしろ、一緒に行く友人もいませんし、行きたくもありません。(嗚咽)