こんにちは、馬場です。
シナジーマーケティングの技術者向けサイトTECHSCOREで行われているTECHSCORE Advent Calendar 2014に参加しました。この記事でGoogle の論文を紹介しましたが、ここではこの論文の翻訳メモを公開します。参考になれば。
機械学習:技術的負債を生む高金利なクレジットカード
論文はここにあります。
Abstract
機械学習を利用すれば、複雑ですばらしいシステムがすぐできる。
でも、それが「ただ」で手に入る、と考えているのなら、それは危険だ。
機械学習を利用しているシステムは、簡単に【技術的負債】をもつシステムになってしまうから。
この論文では、機械学習をシステムに導入する場合の「アンチパターン」を紹介する
1.機械学習と複雑なシステム
- システムには「技術的負債」というアイディアがある
- 解消するには「リファクタリング」「テストのカバレッジをあげる」「いらないコードを削除」「疎結合」「APIでつなげる」「ドキュメントの整備」
- 機械学習を含むシステムは通常のものより複雑で、大きな技術的負債を生みやすい
- 機械学習そのものはブラックボックスとして扱われる
→ 「のり」となるコード、調整するコード
→ 他システムへの密な結合を生む - 外のシステム変更 → 機械学習アルゴリズムに致命的な影響
- きちんと意図した処理をしているのか、監視することも難しい
- アカデミックと違い、長い目でみると、このあたりのシステム設計を考慮することが重要
2. 複雑なモデルは境界を浸食する
機械学習にはらむ課題:"外部データへの依存なしに、望む振舞をするソフロウェアを、効果的に実装することができない"
2.1 Entanglement (もつれ あるいは 鉄条網)
- 機械学習は複数のデータソースから何か導きだす、という性格上きちんと疎な状態を維持するのが難しい
→ CACE : Changing Anything Changes Everything - 対策1 : モデルを分解、ただしスケールしなくなる
- 対策2 : モデルの推論の振舞に関する深い洞察を得るようなメソッドを開発する(? すみません、わからなかった)
- 対策3 : より洗練されている正規化メソッドを利用する
- どの対策も役立つ場合もあるが、いずれにしろこの問題が発生するのは機械学習の宿命。
- 最初のバージョンの機械学習システムをリリースするのは簡単、けれども改良していくのは難しい
- Ver 1.0 の締め切りのプレッシャーに追われて、軽く扱われやすい
2.2 Hidden Feedback Loops (隠されたフィードバック ループ)
- 「隠れた」ループの例を紹介
- 例:CTRモデル
- x_week 変数:過去1週間でユーザがクリックしたニュースの数、CTRモデルの説明変数に利用
- モデルを変更したら、改善した = クリック数があがる
→ ユーザが多くクリックするようになる
→ 正確なモデル改善の結果は1週間では明らかにならない なぜなら x_week が従属変数だから
→ モデルが新しいモデルのデータを証拠として使えるようになると、モデルはその新しいx_weekに合わせて学習する ... - 従属変数が目的変数の一部となる場合、モデルがゆっくりと振る舞えを変えていくので、評価が難しいし、単純な改良でも大きなコストが発生する
2.3 Undeclared Consumers (宣言されていない消費者)
- 機械学習の結果、あるいは途中経過が思いのほかたくさんのシステムに使われていること
- この「知らないうちに消費している人たち」は、最善でも「高価」、最悪だと「危険」
- 高価:モデルを変えづらくなる
- 危険: " additional hidden feedback loop"
3 コードの依存性よりデータの依存関係の方が高くつく
静的解析で検出しやすいコードの依存性に対して、データ依存性を検出するコードはあまりないので、簡単に巨大なデータ依存チェーンがいとも簡単にできあがってしまう
3.1 Unstable Data Dependencies (不安定なデータへの依存性)
- 機械学習で利用する変数はunstableなことが多い(implicitly/explicitly)
→ 入力信号の変化は、利用している機械学習システムと関係なく起こる - 対策: versioned copy をつくる。安定するが、潜在的な老化を生み出すし、複数バージョンの運用は文字通りの技術的な負債を生み出す
3.2 Underutilized Data Dependencies (未活用データへの依存)
- 初期モデルに組み込んだ変数が改善により不要になった
- 効果的かどうか、評価すらしていない
- そんなに変わらないけど、ちょっと変わる(有意差がわずかにある)から入れる
- 上記のように結果に影響ないものの一度組み込んだ変数は、システム的に外すのは難しい
- 対策:定期的に変数の精査を行いましょう
3.3 Static Analysis of Data Dependencies (データの依存性を静的に解析する)
- データ依存性の静的解析ツールは、ないことはない(らしい...)
3.4 Correcton Cascades (カスケードの補正)
- データのカスケードは、deadlock を生む
- 対策:(? ... わからなかった!だれか!)
4. システムレベルのスパゲッティ
いくつかのシステムデザインのアンチパターンをみてみよう
4.1 Glue Code (のり コード)
- 機械学習アルゴリズム部分はライブラリなど使うことが多い
- 巨大なのりコードが書かれる → 特定のパッケージに固定される
- 機械学習システムと一般的なMLパッケージはデザインのゴールが違う
- 特定のソフトウェアシステムは、特定のラージスケールな問題に取り組む
- Glue Codeパターンは他のアプローチによる実験を難しくする
- 対策:特定のアルゴリズムを再実装 。例えば、RにあるアルゴリズムをC++やJavaで書き直す
- めんどくさ... と思うかもしれないが、簡単に保守できるようになるし、他のアプローチもテストしやすい
- 機械学習システムでは、機械学習のコードは全体の5%、他95%はGlue Code
- API を再利用し続けるより作り直した方がいいよ
4.2 Pipeline Jungles(パイプラインのジャングル)
- 新しいシグナルや新しい情報ソースが追加されたときにおきやすい
→ 中間ファイルたちとともに、scrapes/joins/sampling steps のジャングルが - 高い end to end integration tests
- 対策:data の収集と素性の展開を全体論で考えよう
- 過去を清算するアプローチはかなりの投資になるが、コストを抑え、イノベーションのスピードをあげることができる
- これらのアンチパターンは、リサーチとエンジニアリングの役割が分断されはじめている前兆
- Google では、researcherとengineerが同じチームに
4.3 Dead Experimental Codepaths(死に絶えた実験コードパス)
- glue code や pipeline jungles をなくしていくと、実験をもっとしたくなる
- ただし、実験コードへの互換性を維持するのはしんどい
- 実験コードが致命的な損害をもたらした事例もある
- 対策:定期的に実験ブランチの評価を行い削除する
- 効率的にすすめるには、定期的に部品を書き換えていく
4.4 Configuration Debt
- 設定は軽視されがち
5 . 外界の変化に取り組む
不安定な外の世界と相互に通信する「機械学習システム」をどう運用するか
5.1 Fixed Thresholdes in Dynamic Systems (動的システム内の固定された閾値)
- 閾値をどうするか? manually set → モデルを変えたら閾値もかえないと
- 対策: 閾値を評価データから算出するようにする
5.2 When Correlations No Longer Correlate (すでに相関のない相関関係)
- 依存関係のない相関関係は 隠れた負債のもうひとつのソースになりうる
5.3 Monitoring and Testing (監視とテスト)
- 機械学習が「意図通り」動いているか、どうやったらテストができるのか?
- Predicion Bias と Action Limits
6. 結論
がんばって払っていこう!
さいごに
終盤若干息切れ感があり、すみません。論文はもう少し詳しく書いてありますし、私の理解の及ばないところもありますので、お時間があればぜひ原著をお楽しみください。