Kaggle公式講座の内容がなかなか良かったです。これに沿って、Titanicコンペを卒業して、住宅価格コンペに参戦することで、自分自身の機械学習実践スキルの成長が実感できました。その体験を共有します。
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
こんにちは、初心者Kagglerの一色です。また、この連載の記事を開いてくれてありがとうございます!
前回は「Kaggle初心者のためのコンペガイド ― Titanicの先へ:僕たちのKaggle挑戦記」という記事を公開して、ブックマーク数は少なかったものの、そこそこのページ参照数が得られました。ドキドキしながらの記事公開でしたが少し安心しました。これを受けて、自分もそうだったのですが、「取りあえずTitanicコンペでSubmission(提出)まではやったけど、次のコンペティション(本稿ではコンペと表記)になかなか取り組めない」という人が少なくないということなのかなと思いました。
筆者はどうやって「Titanicの次」という壁を突き破れたのか。そのきっかけになったのが、前回の記事で「Kaggleを始めるのに役に立ったこと」章でも書いた「“30 Days of ML”公式プログラム」でした。このプログラムの前半は、下記3つの無料のKaggle公式講座を2週間かけて履修するというものでした。
よって、上を素直に履修していけば誰もが2週間×毎日1時間程度の勉強時間で私の体験したことのまねができます。「いやいや、あなたのまねをしても意味ないでしょ」と思いますよね、分かります(苦笑)。本稿でまねをオススメするのは、自分でも驚くぐらいにきれいな成長曲線を描くことができたからです。本題に入る前に、説得材料として「どう成長したか」を示しておきます。
「30 Days of ML」ならダラケぐせがある自分でも何かやれそうな気が! と思ったら、[Registration is now closed]ってなってるじゃないですか……。ん? リンクがあるってことは、「30 Days of ML」に登録しなくても、同じ講座の内容で今から勉強を始められるってこと? なら、ちょっと手を出してみようかなぁ。(かわさき)
期間限定プログラムだったけど、今からでも同じ勉強はできると思うよ。プログラムの後半のコンペも参加はできないけど、同じ内容は試せると思う。
同プログラムの第2回開催については何も情報がないけど、アンケート調査で改善点などを聞かれたから、計画があるのではないかと思うので、それを待つのもありかも。ただし1年後とかちょっと先かもしれないね。(一色)
入門講座の最後(7回目)の演習問題は、下記の住宅価格コンペに取りあえず参戦すること。中級講座の1回目〜6回目の演習問題は、その住宅価格コンペで機械学習モデルを少しずつ改善していくことでした。
なお、Kaggleコンペのための機械学習は、[Code]タブで作ることができるKaggleノートブックを使って「無料」で行えます(GPUやTPUも時間制限はあるものの使用可能です)。
講座の各回を毎日1つずつ取り組むことで、次のように成績が変化しました。※図と下記の箇条書きでは、トップ何%に入ったかを示しています。【数値】はモデルのスコアで、数値が小さいほど精度が高いことになります。
どうでしょうか。きれいな成長曲線を描いていますよね。
とはいえ、この住宅価格コンペ自体が、入門/中級講座に付属のもので初心者Kagglerしかいないので、それほど参加者のレベルは高くないと考えられます。その点を差し引いて受け止めてください。
やー、差し引いてもここまではなかなかヤレないと思います! ぼくはそこまで目指しませんから(笑)。
ちなみに30 Days of MLプログラムの後半では、別の回帰問題のコンペに取り組みましたが、中級講座までの内容だけで上位に食い込むのは不可能だと感じました。筆者の場合は、さまざまな前処理を試したり、ハイパーパラメーターの自動チューニングをしたり、モデルのブレンディングやスタッキングという手法(後述)を試したりしました。Kaggleのコンペで本気で参戦していくには、中級講座の後でこういったより高度な内容を習得していくことも必要だと思いました。
これら後半でしたことについては次回以降の記事で書くとして、今回は、中級講座までに筆者が試して体験した内容を、読者の皆さんが追体験するイメージで書いていきます。ターゲットとなる読者は、Kaggle未経験者〜私と同じような初心者Kagglerを想定しています。
30 Days of MLプログラムの初日は、Titanicコンペに初めてのSubmissionをすることでした。その内容は、次のリンク先で説明されています(※英語ですが、前回の記事で日本語に翻訳する方法を紹介しています)。
その後はPython講座(全7回)に取り組みますが、これはウォームアップの講座だと思います。演習問題は少し考えるものもありますが、扱う文法などの内容は易しいレベルです。Pythonに慣れている人は飛ばしてよいでしょう。プログラミング言語が全く初めてという人は、説明が少ないため完全な理解ができないかもしれないので、書籍やWeb上のコンテンツ(例えば「Python入門 - @IT」)などで事前に学んだ方がよいと思います。Python講座のボーナス回で「Titanicチュートリアル」に取り組み、初Submissionを行います(このノートブックは、上記の「Getting Started with Kaggle」で20分でやってみる作業と同じものです)。
次の機械学習入門講座(全7回+ボーナス回)は次のように進みます。
それぞれ基本的な内容で難しくないと思います。中級講座でやることが一気に増えるので、Python講座から機械学習入門講座までは日程を前倒しで進めるぐらいのペースがちょうどよいです。
機械学習モデルの精度/性能を上げていくには、比較対象となる基準、つまりベースラインが必要です。Kaggleでは、取りあえず必要最低限のベースラインとなるモデルを作って、いったんそれでSubmissionすることが一般的です。これについては、「脱・Kaggle初心者 〜 一歩先に行くためのノウハウ:Kaggle入門 - @IT」でも記載されています(※自分の手でKaggleコンペを始めて取り組めば取り組むほど、この記事に納得できることが増えていきますね)。
このベースラインは、機械学習入門講座の第7回の演習問題で作ったものそのものにしました。ここでコードを含むノートブックを公開しても何ら問題ないのですが、読者自身が入門講座を経て自らの手で考えながら作った方がよいと思うので、ここでは控えておきます。この時点で特徴量は全部使わずに(全81列から、先頭列のID、末尾列の予測ターゲットとなるラベル「販売価格」を除く)8個を選択しました。機械学習の手法としてはランダムフォレストを使用し、パラメーター(後述)は指定しませんでした。
「CatBoostを使おう」「最新のディープラーニング手法を使おう」などの今後試したい目標がこの時点であると思いますが、最初のベースラインはスタート地点となるものなので、複雑な処理はそぎ落とした最もシンプルでコアな処理のみで構成したノートブックを作った方がいいと個人的には思います。
この後、新しい手法を学びながら新しい戦略を加えて毎日進化させていきますが、演習問題のノートブックは各回に1つずつ用意されているので、毎日1つずつ新しいノートブックができていきました(図4)。同様に、コンペ参戦では戦略ごとに新しいノートブックを作っていき、戦略ごとにバージョンを付けて(戦略内の修正はリビジョンを付けて)管理すると便利でした。これについては次回説明します。
回帰問題を解く最もシンプルな手法は、線形回帰(scikit-learnならLinearRegressionクラス)でしょう。次にシンプルなのが決定木(DecisionTreeRegressorクラス)、その次がランダムフォレスト(RandomForestRegressorクラス)ではないでしょうか。これらの機械学習の手法は、「5分で分かる機械学習」という記事の「3分 ―― 機械学習の代表的な手法 パート1(教師あり学習)」で紹介しています。
中級講座の1回目では、このランダムフォレストに指定できる各種パラメーター(詳細は割愛しますが、n_estimatorsやmax_depthなどがあります)にさまざまな値を指定してモデルを作成し(リスト1)、各モデルのスコアを比較して最適なモデルを選択します。
from sklearn.ensemble import RandomForestRegressor
model_1 = RandomForestRegressor(n_estimators=50, random_state=0)
model_2 = RandomForestRegressor(n_estimators=100, random_state=0)
model_3 = RandomForestRegressor(n_estimators=100, criterion='mae', random_state=0) # scikit-learn v1.0からは'absolute_error'
model_4 = RandomForestRegressor(n_estimators=200, min_samples_split=20, random_state=0)
model_5 = RandomForestRegressor(n_estimators=100, max_depth=7, random_state=0)
筆者が試した例では、model_3がベストでした。
なお、ここでrandom_state(乱数シード)に何らかの固定値を指定することは重要です。これを指定しない場合、実行ごとに結果が変わってしまい、スコアを比較しづらいからです。機械学習の各手法に対応する「各種ライブラリ内の各クラス」ではrandom_stateが指定できることが多いので、忘れずに指定しましょう。ここでは0を指定していますが、好きな数値で構いません。ただし42を指定する人が非常に多いです。これは『銀河ヒッチハイク・ガイド』(ダグラス・アダムス著)の中で、スーパーコンピュータが750万年かけて「生命/宇宙/万物についての究極の疑問に対する答え」を計算した結果が42だったから、といわれています。ちなみに前回も紹介した、
の中では「42が好きな数値」と言っていました。
中級講座の1回目〜7回目まで、Abhishek Thakur氏によるYouTube動画でそれぞれ解説がありましたので、それらも演習問題を自分で解くと同時に視聴しました。講座とセットで視聴するのがオススメです。
『銀河ヒッチハイク・ガイド』って懐かしい。紙の本で持っていたはずなんだけど、見当たらないから電子書籍を買っちゃいました!(反応するところが違うような気がしますね? 違いますが、反応しちゃうんです)
かわさきさんは雑談のとき、SF小説の話をよくするね。この業界ってSF小説好きの人が多いなぁ。
機械学習モデルの精度を改善するには、そのモデルにどのようなデータを与えるか、つまり特徴量の選択と加工(エンジニアリング)が重要です。いわゆる前処理ですが、その最も基本となるのが欠損値を補完することです。
中級講座の2回目では、下記3つの欠損値の前処理方法が説明されています(※詳細は講座をご確認ください)。
欠損値の前処理方法ごとに、スコアを出して比較しました。その結果、2の「補完する」方法でのスコアが一番良かったです。補完する方法(scikit-learnではSimpleImputerクラス)として平均値(mean)/中央値(median)/最頻値(most_frequent)/固定値(constant)といった戦略(strategy)を選択できますが、ここでは平均を選択しました(リスト2)。
import pandas as pd
from sklearn.impute import SimpleImputer
imp = SimpleImputer(strategy='mean') # シンプルな補完器
imp.fit(X_train) # 平均を取るためにまずは補完器にデータ内容を学習させる
imputed_X_train = pd.DataFrame(imp.transform(X_train)) # 次に補完器で変換する(=補完する)
# 値がNumPy配列になるので、pd.DataFrame()でpandasデータフレーム化する必要がある
欠損値を前処理したことで、スコアが大幅に改善してTop 49%に入りました。前処理の効果はやはり大きいですね。
Copyright© Digital Advantage Corp. All Rights Reserved.