Edited at
GunosyDay 6

私が機械学習研究をするときのコード・データ管理方法

More than 3 years have passed since last update.


はじめに

Gunosy Advent Calender 6日目を担当します,Gunosyの関と申します.

Gunosyではデータ分析部に所属し記事配信ロジックの開発やログ解析によるユーザ行動分析を主に担当しております.

また博士後期課程に在籍しておりウェブマイニングを中心とした機械学習応用の研究の取り組んでおります.

本エントリではソフトウェアエンジニアとして働く過程で身につけた開発手法を,

自分なりに研究活動に活用しながら得たコード管理に関するノウハウを公開するものです.

研究者向けのコーディング技術については各研究室で伝承されているノウハウはあるものの,

まとまった資料やそれに伴う議論などは少ないのが現状であると考えております.

そしてその研究室でのノウハウもエンジニアとしての経験の少ない学生や研究者によって作られたノウハウであり,

近年急速に進歩しているソフトウェア開発ノウハウに対して非常に遅れているといえます.

東北大学岡崎先生の研究者流コーディングの極意は数少ない資料の一つです.

上記資料でも述べられていますが,研究とソフトウェア開発では目的が大きく異なるため,

ソフトウェア開発で良いとされている慣習がそのまま当てはまるわけではありませんが,

研究の目的に転用可能なノウハウは非常に多いです.

私はまだ研究者としてもエンジニアとしても未熟であるためこれが正解というわけではありませんが,

これをきっかけに様々なノウハウの公開や議論が起これば非常に有益かなと考えて今回このようなエントリを公開させて頂きました.

(研究者同士でプログラムのディレクトリ構成や、バージョン管理,実験結果の管理方法などのノウハウ共有会なんてやれたら楽しそうですね)


機械学習研究における要件

研究を行う上で最も重要になるのは,実験結果が正確であることであると私は考えます.

提案手法を正確に実装することはもちろん大事ですが、それ以外にも担保すべき項目は多いです。


  • 実験に用いたデータが意図したとおりに収集されており,再実験可能なように保管されている

  • 前処理済みデータに対して処理を行ったコードが特定可能であり,元データから同様な前処理済みデータを再現することができる

  • 実験結果がどのコードでどのようなパラメータから生成されたか特定可能であり,その実験結果を再現することが可能である

一見当然のことのように思えるかもしれませんが,研究というのは試行錯誤の連続であり,

試行錯誤の過程においてこれらの情報が損失してしまう状況を私は数多く見て体験してきました。

読んでいる方にも心当たりがある人もいらっしゃると思います。


元データを保つ

実験に用いる元データは改変不可能になっていることが大前提です。

しかし上書きされてしまうことなどが生じます

そのため以下のようなルールを敷いています。


  • 大元となるデータをS3に管理する


    • データ例


      • Tweetデータ

      • サイトをクロールしてきたデータ

      • 研究の過程でいただいてきたデータ



    • 実験の際はデータを期間で区切ることが多いので、その方法に応じてディレクトリを切っておく


      • クロールデータなど、随時増えていく場合も一貫性を保つことができる

      • 見るタイミングによって参照した元データが増えていたなんてことは辛い





  • 実験に使うデータを大元のデータから切り出して圧縮し保存する


    • 概要を記載しておく

    • 目的, データソース, 期間などを書いておく



tweets/

2015/
01/
01/
tweet-001.gz
...
...
02/
...
2014/
...

projects/

20151101_{project_name}/
data.gz
readme.txt
...


前処理済みデータを管理する

機械学習研究では元データに前処理をかけることはよくあります。

ここで重要なことは前処理をする際に用いたデータ, 用いたコード, 出力されたコードが定まっていることです。

そのため私は生成されたファイル名とコミットIDをログとして書き出しています。

そしてファイルが上書きされないように生成の時刻を付与しています

これによりコードがコミットさえされていれば,あとからどのコードから生成されたかを追跡することが可能になります

ちなみに現在のコミットIDはこんなワンライナーで取れます

$ git rev-parse HEAD


実験結果を管理する

実験結果についても用いたデータ, パラメータ, コード, それによって得られた結果が一意に定まるようにする必要があります。

こちらでも同様に用いたデータのファイル名, コミットID, 実行時の引数, 出力結果のファイル名とします


その他気をつけていることや考えていること


  • 実行する前に絶対コミットする

  • データベースなどはあまり用いない。


    • MySQLとかはどれから生成されたかわからなくなったり、誤って上書きしたりする

    • SQLiteなどにすればデータとして管理できるのでよい



  • 実験結果とかはGithubのIssueにAPI経由でPostしたり, Evernoteに登録したりしたいなと思っている


    • gitにコミットするのもありかなとは思いつつ、閲覧したいから微妙かなとも思っている



  • 環境構築をDockerなりVagrantなりで仮想化しておきたい

  • TexをコンパイルするAPIが欲しい