Sculley et al. (Google), SE4ML: NIPS 2014 Workshop
https://research.google.com/pubs/pub43146.html
機械学習: 『技術的負債』の高利子クレジットカード
機械学習を用いたシステムには,機械学習が本質的にもつ性質により, 様々な 『技術的負債』を抱え込むリスクが潜んでいる, …ということを明らかにする.
そうした技術的負債の返済方法を挙げる.
- 機械学習を用いたシステムでは, 『外部データ』を扱うということによる技術的負債が膨らみやすい.
- 機械学習利用システムに生じうる技術的負債
- 『システム境界の浸食』『データへの依存性』『システムレベルの絡まり』
- それぞれに実事例から得た教訓(技術的負債の返済方法)がある.
- 研究者(手法の提案者)と開発者(システムをつくる人)両方が意識して, そうしたアンチパターンに陥らないように, 『技術的負債の返済』を継続的におこなっていくべき!
- 機械学習を用いたシステム開発における『アンチパターン』を列挙したのは,
これがはじめてなのではないか.
- 経験談の類はブログなどでは共有されていたが…
- Googleのように機械学習をあらゆる自社製品で利用している企業の知見
- 表現のうまさ,体系化のわかりやすさ
- 『アンチパターン』をソフトウェア工学や現場でよく使われる 『技術的負債』というアナロジーを用いて表現した.
機械学習を活用する機運は高まっているが,行き当たりばったりでは辛そう... ...と思っていたので,これは良い説得材料になりそう.
技術的負債(英: Technical debt)とは、行き当たりばったりなソフトウェアアーキテクチャと、余裕のないソフトウェア開発が引き起こす結果のことを指す新しい比喩である。「設計上の負債(design debt)」とも言う。 1992年ウォード・カニンガムが、技術的な複雑さと債務の比較を経験報告で初めて行った。
たとえば...
ひどい設計やコードで初期バージョンの納品に間に合わせた(⇒ 借金)
後々それらにより発生した不具合の改修コストが膨らんで破綻する (⇒ 返済できなかった)
- ソフトウェア工学でよくつかわれる比喩表現
- すべての技術的負債が悪いわけではない
- 例: スタートアップ企業におけるサービス開発
- 資金調達に間に合わないとマズいので,暫定的な対応を行いリリースに間に合わせる!
- 余力ができてから(優秀なエンジニアを確保してから…) 設計の見直しやコードのリファクタリングを行う
- 金融における借金と同様に, バランスをコントロールして返済できるなら問題ないが…
- 例: スタートアップ企業におけるサービス開発
- 技術的負債は膨らみやすいし返済しにくい 💀
この論文では,機械学習を用いる際には特に注意が必要だと言っている
- 『品質と開発速度のジレンマ』 ⇒ 技術的負債の発生
- ソフトウェア工学で提案された返済方法の例
- リファクタリング,ユニットテストのカバレッジ向上,APIの絞りこみ
- ドキュメンテーションの強化
- 機械学習を利用したシステムが抱え込む追加の技術的負債
- 一般的なソフトウェアに関わる技術的負債だけではない
- 機械学習がもつシステムレベルの複雑性に起因する『隠れた負債』が膨らみやすい
- 機械学習を用いたシステムでは,技術的負債が膨らみやすく,返済しにくい!
システム境界の浸食というリスク:
- 機械学習は必ず『外界のデータソース』を扱うため, 『カプセル化』や『疎結合化』などのソフトウェア工学の知見を 厳密に適用するのは難しい!
以下の項では,さらに細分化したアンチパターンを挙げる.
- 機械学習パッケージは「複数のデータソースを混ぜ込むためのもの」
- それが「もつれ」を生じさせるもので,改良部分の分離をすることが事実上不可能
- CACE Principle: Change Anything Changes Everything
- 何かを変更するとすべてに変更が生じる
- 特徴ベクトル,元データの分布,ハイパーパラメータ(学習率,正則化項など) …などのもろもろがすべて関係してしまう.
- 返済方法
- モデルを孤立化し,アンサンブルモデルとする (問題がサブドメインに自然に分割できる場合に有効)
- モデルの予測の振る舞いに関する深い洞察を得る方法を確立する (例: 高次元データの可視化ツールを使って,効果をすぐに確認する)
- 精緻な正則化を利用し,予測精度のあらゆる変化を目的関数にコストとして含まれるようにする (余計に複雑性が増すかも…とも書いてある)
2.2 Hidden Feedback Loops (隠れフィードバックループ)
- モデル自身の変更によって取れるデータの性質が変わり, それがモデル自体にも影響を与えてしまっていることがあるかも…という話.
- 返済方法
- 注意深く探し出し,可能であれば取り除く
- (感想: そう簡単には見つけられないのだから,この方法自体が無意味 😓)
-
ソフトウェア工学で言うところの『可視性の負債』に関連するもの.
- アクセスコントロールがなければ,出力が知らぬ間に他のシステムで使われるかも
-
危険なケース
- 他のシステムが入力データに影響を与える変更をしうる場合, 2.2のHidden Feedback loop が生じるかもしれない.
- 例 『CTR予測システムの出力によって,
ページのフォントサイズを動的に変更する他のシステムがあったら…』
- ※Click Through Rate: Web広告などのクリック率
-
返済方法
- システムがそのような用途を防ぐように,防御的に設計されていること.
- そうでなければ,特定は難しいかもしれない… 😢
『データ依存性』はコードの依存性よりコストがかかる!
-
ソフトウェア工学では,技術的負債はコードレベルの複雑性を指すことが多い.
-
機械学習を利用したシステムの場合に当てはめると, "Data Dependencies"(データ依存性)によって同じような負債を生み出すといえそう.
-
コードレベルの依存性は静的解析などで特定できるが, データ依存性を特定する方法はほとんどない.
-
他のシステムからの入力を使う場合のデータ依存性について. それが継時的に変化するときの例と問題点を挙げている
- たとえば, 自然言語処理ベースのシステムでよくあるTF/IDFスコアのルックアップテーブルのように, 他のシステムの入力が変化したときの影響がある.
-
返済方法
- 『入力データのバージョンごとのコピーを作成すること』
- 変更の影響を見積もってから,適用することができる.
- ただし,バージョニング自体のコストがかかることに注意.
- 『入力データのバージョンごとのコピーを作成すること』
- コードで言うところの『未活用の依存性』 は不必要なもの.
- 『未活用のデータへの依存性』は,「あまり精度を高めない特徴量」を含む(なので不必要)
- 例
- 古くなった特徴量
- 抱き合わせになった特徴量(全てが必要かどうかは怪しいとか?)
- ε -特徴量: 微小な寄与しかしないか,効果の割にオーバーヘッドが大きすぎる特徴量
- 返済方法
- それぞれの特徴量を取り除いてみて,性能評価を継続的に実施する
- 組織としては, 不必要な依存性を取り除くことへの長期的な利益を意識する文化をつくることが大事
- データ依存性による負債で特に問題なのは,それが静的解析によって見つけるのが難しいところ
- コードの場合は,コンパイラなどで見つけられるが,データ依存性の場合は追及するための追加ツールが要求されそう
- Googleでの事例
- ツールを使ったアプローチによって,Googleのチームは安全に何千行もの特徴量関連コードを削除したり,バージョン違いやその他の問題にかかわることを自動で検証できるようになった
- アンチパターンの紹介:
- ある問題とそのためのモデルがあるとき, その問題とちょっと違うだけの問題に対するモデルを作りたい. このとき,前に作ったモデルの出力を入力とするモデルを作りたくなることはよくある.
- 返済方法
- 『元のモデルに,別の問題のための特徴量を追加して利用する』こと.
- (積み重ねて使わない!)
残念ながら, 機械学習を利用するシステムは負債まみれのデザインパターンに行きつくことがよくある.
以下では,システムレベルのアンチパターンを挙げる.
-
"Glue Code" = システムやライブラリ間をつなぐためのコード
-
よくある機械学習パッケージを使う場合, glue code systemというデザインパターンに陥ることがよくある.
-
何がまずいかというと, 特定のライブラリやパッケージに特化したシステムになってしまうことで,長期的にはコストがかかること.
-
😵 著者らによると機械学習そのもののコードは高々5%,少なくとも95%はGlue Code
-
返済方法
- 問題特化型にする: 汎用パッケージのうち,システム内で使われる特定のアルゴリズムを再実装する
- (感想: 優れた問題特化型ライブラリを書ける技術力があるGoogleだからできるのでは?)
-
Glue Codeパターンの特殊形.データ前処理時に表れることがある.
-
返済方法
- データ前処理パイプライン全体を考えることによってのみ減債できる
- データ前処理パイプラインを作り直すことで,劇的に負債を減らせる
-
Googleにおける事例
- 『Glue CodeやPipeline Junglesパターンは, 研究とエンジニアリングがひどく分離してしまっていることを根に持つ不和の予兆である』
- Googleでは,研究者とエンジニアを同じチームに配置することで不和を解消
- 既存の処理の流れからの派生物が増えすぎることによる負債.
- 実験的なコードが消されずに残り,積み重なることで, 予想外の振る舞いをしてしまうことがあるかもしれない.
- よい機械学習システムでは,実験的なコードは隔離されているべき
以下のように,断捨離をしなくてはならない.
- Googleでの事例
- ある重要な機械学習システムの大掃除をした
- 何万行もの不要なコードを削減できた
- 実験的なコードの削除
- 設計の見直しやAPIの削減
- 機械学習システムの各種設定による負債を指す (前処理・モデルのパラメータなど,膨大になりがち)
- 返済方法
- 構成設定の検証や, 2つの構成設定間のDiffをとったりすることが効果的.
機械学習システムで本質的についてまわる,外界の変化への対応について.
- 閾値を用いるシステムの場合,人手での設定はモデルの更新にコストがかかる.
- 入力データの分布が変わるたびに,人手で閾値を設定する…
- 返済方法
- 閾値をデータから自動設定できるようにすること
- 特徴量の共起や相関がなくなってしまった場合に対応できるようにする
-
各コンポーネントのユニットテストだけでは,システム全体の外界の変化への対応状況はわからない.
- リアルタイムにシステム全体の振る舞いをモニタリングすることが重要
-
モニタリングする項目
- 予測バイアス: システムが想定通りに稼動している場合, 予測したラベルの分布は観測したラベルの分布と等しくなるはず.
- Action Limits 何からの行動のために使われるシステムの場合, 基準につかう指標の上限を定め適用することでサニティチェックとなる. 定めた上限に達した時に,自動でアラートを出して,調査に当たれるようにする.
この論文では,機械学習が悪いとか,あらゆる技術的負債を抱えてはならない! といっているわけではない.
(得られた教訓として…)
技術的負債はエンジニアと研究者の双方が意識するべきものである: たとえば,精度にわずかしか寄与しないのにシステムの複雑性を多大に増加させてしまう研究成果は,実用には賢明ではない.
(メッセージ)
技術的負債の返済は新たな定理の証明と比べてエキサイティングではないが, 継続的な強いイノベーションに必要不可欠なものだ.