初コンペ SIGNATE 国立公園の観光宿泊者数予測で18位でした

参加の背景

f:id:taigok:20181221001639p:plain

国立公園の観光宿泊者数予測というデータ分析コンペに初めて参加しました。目的としてはデータ分析の一通りの流れを試行錯誤しながら学びたかったためです。データ分析コンペは初参加で、このコンペ後にMicrosoft Malware Predictionに参加予定です。

コンペ概要

タスク

前日以前のデータを元に翌日以降の宿泊者数が予測可能なモデルを作成することです。
予測対象は8つの国立公園付近の1年間(2017/1/1~2017/12/31)の宿泊者数になります。

データ

  • SNSデータ
  • ロケーション付SNSデータ
  • メッシュ型流動人口データ
  • 公共交通検索ログデータ
  • 国別月別来訪者数集計データ
  • 気象データ
  • 積雪気象観測データ
  • 地域経済分析システム(RESAS)

最終順位の決定

コンペ最終日までの評価(暫定評価)は評価用データセットの一部で評価し、コンペ終了後の評価(最終評価)は評価用データセットの残りの部分で評価します。

これは特定のデータに過学習(Overfitting)するのを防ぐためで、暫定評価用のデータセットに最適化したモデルを作成するとコンペ終了後の評価用データセットに適合しないモデルになってしまいます。つまりモデルが汎化していないといけないということになります。この辺りの話は Machine Learning | Courseraで学びました。

また、順位確定の際に下記の情報を提出する必要があります。予測結果の再現の為の手順書は、コメントかJupyter NotebookのセルにMarkdownで記載すれば良さそうです。

  • 予測モデルのソースコード
  • 学習済モデル
  • 予測結果の再現の為の手順書(前処理部分、学習部分、予測部分が分かるよう明記)
  • 実行環境(OSのバージョン、使用ソフトウェア及び解析手法)
  • 乱数シード(Random Forest等の乱数を利用した手法の場合)
  • 各説明変数の予測モデルへの寄与度(寄与度の算出が可能な手法を用いた場合)
  • データの解釈、工夫点、モデリングから得られる示唆等

評価

精度評価は、評価関数「Mean Absolute Error(MAE)」です。
MAEは平均絶対誤差ともいい、外れ値をより大きな誤差として扱う傾向があるそうです。 また、Pythonの代表的な機械学習のライブラリであるscikit-learn には MAE を計算する関数が実装されています。

モデル作成までの流れ

データのDL

国立公園の観光宿泊者数予測のデータページからデータをダウンロードしました。

分析環境作成

プロジェクトフォルダの作成

ディレクトリ構成を作るためのライブラリである Cookiecutter を使用して、機械学習用のプロジェクトディレクトリを作成しました。ディレクトリ作成後、ダウンロードしたデータを data/raw ディレクトリに格納しました。

参考:DockerコンテナでPython3、Jupyterの入ったデータ分析環境を作成する

初めはローカル環境(Macbook Pro)で分析を進めていましたが、リソースが足りない時が時々あったため、途中からはソース管理していたGitHubから読み込んでGoogle Colabrataryを使用して進めました。
Google Colabのスペックは下記になります。

  • n1-highmem-2 instance
  • 2vCPU @ 2.2GHz
  • 13GB RAM
  • 33GB Free Space
  • idle cut-off 90 minutes
  • maximum 12 hours

ソース管理

ソース管理はgitを使いました。リポジトリの作成方法は、https://github.com/new において New Reposotryを作成し、下記コマンドを対象ディレクトリで行えばいいでしょう。これ以降は適宜commit, pushをしていきます。(コンペ開催期間でのPublicリポジトリでの管理は有りなのでしょうか。)

$ pwd
/Users/username/national_park_prediction

$ git init # ワーキングディレクトリにgitリポジトリ作成
$ git add . # 全ファイル、全ディレクトリをインデックスに追加
$ git commit -m "first commit" # インデックスにあるファイル・ディレクトリをローカルリポジトリに記録

# リモートリポジトリ(national_park_prediction.git)をoriginという名前で登録 
$ git remote add origin git@github.com:TaigoKuriyama/national_park_prediction.git 
$ git push -u origin master # リモートリポジトリにアップロード

issue管理

issue管理もGithub上で行いました。issueとは例えば、モデル作成中や環境構築時に出たエラーなどをあげて、どうやって解消したかを記載していきます。 今後似たようなことが起きた時に参考にできます。

f:id:taigok:20181220233135p:plain
Issue

ToDo管理

ToDo管理もGithubのProjects機能を使い、Inbox, In Progress, Doneと分けてタスクを管理しました。 f:id:taigok:20181220233557p:plain

コンペへの取り組み方理解

kaggleのチュートリアル。機械学習の入門に最適!に取り組み、コンペへどう取り組むかについて理解しました。こちらのnoteはkaggle(データ分析コンペプラットフォーム)を対象としたチュートリアルになりますが、コンペの取り組み方という意味ではとても参考になります。有料ですので詳細については書くことができませんがコンペに取り組んでみたいが、どうすればいいかわからないという方は購入してみてもいいかもしれません。
有料が厳しい場合は、こちら 一から始める機械学習(Kaggleで学ぶ機械学習) で学ぶのがいいかもしれません。

分析は主に下記の流れを繰り返すことと理解しました。

  1. データ前処理
  2. アルゴリズム選択
  3. パラメータ選択
  4. モデルの学習
  5. 評価
  6. 提出

データ概要理解

データ説明

コンペページのデータ説明に内容が書かれているのでまずはそれを読みつつ、実際のデータを確認しました。

データ詳細

データ分析のライブラリであるpandasを使って各データの詳細について理解を深めました。read_csv時には ファイル形式はcsv ( 項目間をカンマで区切ったデータ ) ではなく、tsv形式 ( 項目間をタブで区切ったデータ )なので、read_csvには sep='\t' というオプションが必要です。

# データの確認(観光宿泊者学習データの場合)
import pandas as pd
df_train = pd.read_csv('../data/raw/train.tsv',sep='\t')
df_train.head()
# データ確認
df.head(n)        # データフレームの上からn行を表示
df.shape          # データフレームの行数と列数
df.columns        # カラム
df.info()         # データの概要
df.isnull().sum() # 欠損値の数
df.describe()     # 要約統計量

日付ごとの平均visitor数を降順に並べると、当たり前ですがGWや年末年始が多いことがわかります。よって祝日フラグデータがあればいいと考えました。

ネットで見つからなかったのでGoogle SpreadSheetで休日データの作成をしました。 まずは、土日フラグを下記の式で立てます。

=IF(( WEEKDAY(A2, 2) >= 6 ),1,0)

祝日のリストはこちらいただきました。土日リストと祝日リストからholiday.csvを作成しました。

特徴量について

最終的に使用した特徴量は下記になります。
仮説を立ててデータから試行錯誤して特徴量を作成し、モデルを作成、Cross Validationの結果を見てSubmitを繰り返すという流れを続けましたが最終的に使用したのは気象データ(気象庁)のみでした。

  • 曜日
  • 公園
  • 休日
  • sin, cos, tan
  • 気温
  • 降水量
  • 降雪量

結果

終結果は18位/124人となりました。

f:id:taigok:20181220235733p:plain

学び・反省・疑問

自分の足りないスキル、知識が明確になったのでとてもいい機会になりました。具体的には下記が学び・反省・疑問になります。

  • データ探索のスキルが浅く与えられたデータから有益な特徴量が発見できなかった
  • フォーラムのようなものが無く、完全に個人で進める感じだったので周りから勉強をする機会が無く残念だった
  • モデルのアンサンブルをする時間が無かった
  • 特徴量、モデル、提出ファイルの管理をどうすればいいか分からなかった
  • 時系列データへの取り組み方が正しいのか分かっていない
  • コンペ中はずっと Jupyter Notebookでコーディングするのだろうか?

当該Gitリポジトリ

全然まとまっていませんが、下記がコンペのリポジトリになります。 https://github.com/TaigoKuriyama/national_park_prediction

参考