ひよっこの僕がビッグデータ分析について学んだこと


背景

僕は直近の4年間をビッグデータ分析に従事してきたのですが、それを通じて「こうしていたら良かった!」と反省することがあったため、それをまとめたのがこの投稿です。

*注意点
この投稿はその道のプロが書いたものではありません。とある学生の個人的な見解として流し読みして頂ければと思います

*ビッグデータの定義
この界隈ではよく議論になりますが、この投稿ではビッグデータを「システム一台では処理できない量のデータ」とします。例えば、HDD 500GBのラップトップしか使えないのでしたら扱えるデータ量は小さくなりますが、Hadoopを複数台のサーバで走らせて、十分にディスク容量がある分散システムを利用しているのであれば扱えるデータ量が増えます。僕の場合、最初はデスクトップPC (メモリ16GB, CPU Core i7 3.2GHz, HDD 1TB) 一台で処理していましたが、扱うデータが大きくなり、最後の方は1台のサーバと2台のデスクトップで処理を分散化してました。

学んだこと (一般的な話)

1. 最終的なゴールを見失わないように気をつける

僕の場合、データを分析しているうちに分析の目的(例. 精度の改善)を見失って、時間がしばらく経ってから実装していたコードが無駄であったことに気がついたことがありました。
研究でも仕事でもPDCAサイクルを回していくことが大切ですが、ビッグデータは特にDoとCheckに時間がとてもかかります。常になぜこのデータを分析する必要があるのかを考え、「これって分析のコードを書いても意味ないんじゃないのか?」ということに気がついたら、誰かに相談するか、目的の再確認をした方が良いと思います。Plan - Delay - Cancel - Apologize にならないようにしましょう。

2. Garbage In Garbage Out (GIGO)を常に意識する

どんなことでも通じる法則ですが、極端な話、ノイズを処理してもノイズしか生まれないということです。自分が扱っているデータが本当にノイズが除かれているのか(ちゃんと前処理したのか)、あるいは処理の最中にノイズが混ざっていないかどうかを確認することが重要です。
最初だけでなく、常にGIGOを意識する必要があるのは、データを処理していくうちに、徐々に有益なデータまで除いてしまっている可能性を考慮するためです。

3. 人間に分からないことは、基本的に機械にも分からない(視覚化が重要)

Deep Learningなどの成功を通じて、機械学習が万能であるかのような錯覚がありますが、基本的に人間が見て区別がつかないデータを機械で精度良く区別することはできません。機械でうまく区別できるのは、データ量や次元が大きすぎて人間が見ても分からない場合に限られます。

機械学習の中で行なわる数学は難しいものが多いため、ブラックボックスになりがちですが、途中結果などを視覚化することで「これは機械でうまくいきそう」ということが分かります。国際学会に参加していて、「この研究すごいな」と思うものの多くは、前処理後のデータの波形や機械学習の途中経過を視覚化することで、「どおりでこの手法でうまくいくのだ」と納得させられます。

その他にも視覚化は以下の理由で重要です。

  • 直観的に理解ができるため、他人と議論がしやすくなり、進捗報告や説得が簡単になる(重要)
  • データに問題がないか、どういった傾向があるかというのを確認できる
  • 自分の処理に間違いがないか、方向性が間違っていないかを確認できる

学んだこと(技術的な話)

データはビッグでない方がいい(一つのシステムで処理できた方がよい)

僕の研究では計算に時間がかかるため、逐一処理した結果をファイルに出力していました。処理していくうちにデータ量が増大し、最終的にはデータをディスク容量が大きい別のシステムに移さなければ処理しなければならなくなりました。このとき、注意しておけばよかったと思う事項を列挙します。

データの一貫性を保つ(バージョン管理)

機械学習ではランダムサンプリングを用いたり、学習パラメータを調整することが多いため、実行タイミングやパラメータによって出力される結果が異なることがあります。そのため、出力された結果がPC間で異なり、それらを統合した結果が意図しない結果になっていることがありました。
出力されたデータがどういったパラメータ(シード値など)で作られたのかを記録して、再現性を保てるようにしましょう。特に分散して処理を行っているときは注意が必要です。
(再現性のないos.urandom()などシステムの乱数生成器を用いる関数は使わないように)

小規模なデータから徐々に大規模に

最初から大規模データを試す人もなかなかいないとは思いますが、ランダムサンプリングした小規模なデータで精度をある程度確認してから大規模にすることが重要です。小規模なデータで精度が低い場合、データの数を数倍にしたところで精度が望むほど高くならないことが多いです。まずは小規模データでPDCAサイクルを速く回しましょう。

データ形式 & serialization に気をつける

データ形式はデータ分析において非常に重要です。バイナリにするのか、csvにするのかによって必要なディスク量が大きく変わってきます。また、データが大きくなってくるにつれて、データ形式を変換するのにも数日取られることがあります。
僕の場合は、最初のうちはcsvやjsonなど視認性の高い形式で出力し、データの形式が固まり次第、バイナリなどでデータ量を減らしてました。

バックアップは大切

これも言うまでもありませんが、定期的なバックアップは重要です。前述したように調整したパラメータによって結果が変わるため、それに応じたバックアップを取っておくのが理想です。バックアップはディスクアクセスが高いので、計算を並行して回すのは危険です。分析や他の仕事があるときに回しておきましょう(理想的にはSSDで十分な容量があれば良いのですが...)。

notification の重要性

大規模なデータの分析で苦労したことに一つに最初の数分で処理が止まっていたのに気付かず、数時間経った後にやり直したことが挙げられます。
例外が発生した場合、計算が正常に終了した場合には、メールでもSlack、Twitterでも良いので通知を自分の元へ飛ばすようにしましょう。notificationが精神的な支柱になってくれます。

信頼できる結果を出すための設計スキルが求められる

ここまでの話のように、ビッグデータ分析に要求される技術は多岐にわたります。それらをプログラムに落とし込むときに、理路整然とした分かりやすいコード(リーダブルコード)が求められます。
データとアルゴリズム(処理するプログラム)は密接な関係があるため、データが複雑になれば俄然プログラムも複雑になります。しかし、1箇所でも間違っていると分析結果は間違ったものになります。結果を保証するためには適切なプログラムの設計が求められます。