u++の備忘録

【Kaggleのフォルダ構成や管理方法】タイタニック用のGitHubリポジトリを公開しました

はじめに

本記事では、Kaggle用フォルダ構成や管理方法について、現時点での自己流の方法をまとめます。「現状自分はこういうやり方を試している」という話なので、よりよい方法などあれば、ぜひTwitterなどで教えてください。

具体例がないと抽象的で分かりづらいと思ったので、Kaggleのタイタニックを題材にしました。GitHubリポジトリも公開しています。

Kaggleのタイタニック

Kaggleのタイタニックとは、Kaggleのチュートリアル的な問題として認知度の高いコンペティションです。タイタニック号の乗客の属性情報(性別・年齢・チケットの種類など)から、生存したか否かを予測します。

Titanic: Machine Learning from Disaster | Kaggle

執筆の経緯

Twitterで今月冒頭にkaggle Advent Calendarに書く話題を募集したところ、次のようなリプを頂きました。本記事は、これらの質問にお答えできるような内容にしたいと思います。


大まかな方針

  • 大雑把に機能別でフォルダを切り「どこに何が書いてあるか」を分かりやすくする
  • コンペのデータに依存する要素はconfigsやrun.pyなど一部のみに限定し、その他は編集無しで使い回せるようにする

参考にした情報

Kaggleの「TalkingData AdTracking Fraud Detection Challenge」で優勝したflowlightさんのリポジトリを非常に参考にしています。

github.com

特徴量の管理に関する部分では、同じくflowlightさんのリポジトリを参考に執筆されたというamaotoneさんのブログが理解の助けになりました。

amalog.hateblo.jp

フォルダ構成

フォルダ構成は以下の通りです。

f:id:upura:20181219082838p:plain

  • configs
  • data
    • input
    • output
  • features
  • logs
  • models
  • notebook
  • scripts
  • utils

configs

jsonファイルで、諸設定を記載しています。

記載している情報は「利用している特徴量」「学習器のパラメータ」などです。

{
    "features": [
        "age",
        "embarked",
        "family_size",
        "fare",
        "pclass",
        "sex"
    ],
    "lgbm_params": {
        "learning_rate": 0.1,
        "num_leaves": 8,
        "boosting_type": "gbdt",
        "colsample_bytree": 0.65,
        "reg_alpha": 1,
        "reg_lambda": 1,
        "objective": "multiclass",
        "num_class": 2
    },
    "loss": "multi_logloss",
    "target_name": "Survived",
    "ID_name": "PassengerId"
}

またコンペのデータに依存するカラム名なども、このjsonファイルから読み取る形式にしています。

data

dataフォルダは、input/outputに分けています。

input

inputフォルダには、元データのcsvファイルや、feather形式に変換したファイルなどを配置しています。

output

outputフォルダには、提出用のcsvファイルを出力します。ファイル名は「sub_(year-month-day-hour-min)_(score)」のように設定し、後述するログと照合できるようにしています。

features

featuresフォルダには、train/testから作成した各特徴量を保存しています。

base.pyなど、詳細については先に紹介したamaotoneさんのブログをご参照ください。

amalog.hateblo.jp

1階層深いimportancesフォルダは、特徴量の重要度を出力するために用意しました。

logs

logsフォルダには、計算の実行ごとに下記の情報などを出力しています。ファイル名は「log_(year-month-day-hour-min).log」のように設定し、前述した通り提出用のcsvファイルと照合できるようにしています。

  • 利用した特徴量
  • trainのshape
  • 学習器のパラメータ
  • cvのスコア

LightGBMのログ出力についても、amaotoneさんの次のブログを参考にしました。

amalog.hateblo.jp

loggerに関しては、現在こちらのブログを読みながら更なる良い方法を検討しているところです。

icebee.hatenablog.com

models

modelフォルダには、学習器を用意しています。下記のように汎用的に作ることで、別のコンペでも使い回せることを意識しています。

  • 入力:pandas.DataFrame、パラメータ
  • 出力:予測結果

notebook

notebookフォルダには、探索的データ分析などで利用したJupyter Notebookを配置しています。ここで試行錯誤した結果を、適切なフォルダ内のpythonファイルに取り込んでいきます。

scripts

scriptsフォルダには、汎用的なpythonファイルを配置します。例えば convert_to_feather.py ファイルは、csvファイルをfeather形式のファイルに変換します。

import pandas as pd

target = [
    'train',
    'test',
]

extension = 'csv'

for t in target:
    (pd.read_csv('./data/input/' + t + '.' + extension, encoding="utf-8"))\
        .to_feather('./data/input/' + t + '.feather')

utils

utilsフォルダには、汎用的に使える関数を書いています。

計算の実行

リポジトリのルートで以下を実行します。

このrun.pyは、コンペに応じて比較的自由に記述することにしています。このrun.pyから、汎用的に書いた各フォルダの要素を取り出してくるイメージです。

python run.py

Git管理

リポジトリはGit/GitHubで管理しています。自分一人でしか作業しないので、masterに直pushする運用をしています。

tkmさんのブログに書いてある方針が近い印象です。

yutori-datascience.hatenablog.com

おわりに

本記事では、Kaggle用フォルダ構成や管理方法について、現時点での自己流の方法をまとめました。

Kaggleを始めた当初はJupyter Notebookだけで処理していましたが、再現性が破綻しかけたこともあり、最近は適切にフォルダを分割して疎結合でファイルを管理するよう意識しています。最初にフォルダ構成を検討する際には時間がかかりましたが、コンペに依存しないよう切り分けておくことで業務などでの再利用も可能で、良い循環になっているかと思います。