機械学習のルールとベストプラクティス（Rules of Machine Learning: Best Practices for ML Engineering の意訳）

#WHY

1：自分の勉強のためです。
2：機械学習に興味があるけど英語ができない人でも大まかな内容が理解できれば良いな

機械学習は近年話題になっている技術ですが具体的な運用のための指針はあまり明確になっていないのが現状です。企業の担当者が知恵を振り絞って工夫されていると思います。
今回、参考にした資料はGoogleの中の人が書いているので参考にできるはずです。
機械学習の適用で悩めるエンジニアの指針になれば良いと思います。
ただし参考資料の方が詳しいので英語ができる方は元の参考資料を読まれる
ことを強くオススメします。

http://martin.zinkevich.org/rules_of_ml/rules_of_ml.pdf

誤訳がある可能性があります。（できれば指摘していただけるとありがたいです）

43個のルールがありますが、これが指針となって機械学習をどのように適用していくかの方針になるでしょう！！

#参考

http://martin.zinkevich.org/rules_of_ml/rules_of_ml.pdf

# 全体像

![ML Architecture.jpg](https://qiita-image-store.s3.amazonaws.com/0/10496/bc2cf215-e518-c842-cc42-a120cef07339.jpeg)

MLは機械学習の略

1：機械学習システムをどんな時に構築するか理解する
2：デプロイ
3：新しい特徴量を加えてローンチとイテレーションを回す場合のモデルの評価方法と学習からモデルを本番環境にデプロイする方法
4：精度向上が止まった場合にやるべきこと

4つの心がけ

1：End to Endで硬いパイプラインにする
2：目的を持って始める
3：単純な方法で共通の特徴量を加える
4：硬いパイプラインを保つ

# 機械学習の前に

## ルール1：機械学習を使わないことを恐れるな！！

機械学習はクールだよ！！ただしデータが入るまでは手を出さない。手間の割に人手でやった方が精度が高い・・・

人手でやった方が優秀なのでデータが手に入るまで我慢しましょう。

## ルール2：最初にデザインと実装の評価

将来的に機械学習を導入したいのならできるだけ現状のシステムをトラックしましょう。

１：早くからシステムに関わっている人には権限を得やすい
２：将来的に機械学習を導入したいならデータの歴史を追う
３：評価機構をつけておくと将来的にログを辿って評価する必要がなくなるよ
４：何が変わっていて何が同じか気付いた方が良い。評価が適切でないとあなたがユーザーのために最適化したことがユーザーエクスペリエンスが変わっていても気づかないかもしれない

評価とトラックが重要！！

参考のリンクではGoogle Plusの例がありました。

## ルール3：複雑なルールになってきたら機械学習を選択！！

シンプルなルールならば良いが複雑なルールではメンテナンスができない。データがありシンプルな機械学習の方法のアイディアがあれば試すとメンテナンス性が向上する。

# 機械学習 Phase1

## ルール4：シンプルなモデルを保ち、インフラを適切に保つ

決めるべきこと

１：学習アルゴリズムのサンプルの取得方法
２：どうなれば”良い”か”悪い”かを決める
３：あなたのモデルをどのようにアプリケーションに埋め込むか。モデルをオンラインで適用もしくはExampleデータでオフラインで学習して結果をテーブルに出力できるようにする。

信頼性のインフラがもたらすもの

１：特徴量は正しくモデルにデプロイされる
２：モデルが学習する重みには理由がある（深層学習は除く
３：サーバー内で特徴量が正しくデプロイされる

最初はシンプルなモデルをベースラインに置く。複雑なモデルは後で・・
ニューラルは後でね・・

## ルール5：インフラは機械学習とは独立してテストしよう

１：データが機械学習アルゴリズムに入る部分のテスト。適切に特徴量が入力されるかチェック。統計的な手法で比較できるとさらに良い
２：学習した環境と本番の環境で出力が同一であるかチェックしよう

機械学習は予測できない要素があるのでExampleのデータで学習とテストとServingすること
重要なのは扱うデータを理解すること

## ルール6：パイプラインでデータをコピーした時のデータ欠損に注意しよう。

既存のシステムと新しいシステムをつなげる時に発生するので注意しましょう。
参考のリンクではGoogle Plusの例がありました。

## ルール7：特徴量は人間が操作します。もしくは外部からこれらを操作します！！

機械学習が解く問題は特に目新しいものはありません。これは既に人手のルールがあることを意味します。

１：前処理はルールの力を頼る。
２：特徴量の作成
３：人手で作ったルールを入れる。（アンサンブル学習などに有効
４：ラベルの設定

人手のルールは複雑さを持ち込むけど古くから効果を保証されているからバランスを考えて導入しよう。シンプルに保つことが重要なのは忘れずに

# モニタリング

## ルール8：あなたのシステムをフレッシュにする条件を知りましょう

1日、1週間、1クォーターあたりでのパフォーマンスがどの程度か見ましょう。
サービスによってデータの投入量が変わるのでデータの投入量によってモデルの更新

## ルール9：モデルを出力する前に問題を発見する。

ROCカーブとAUCカーブで最低限確認する。サニタイズチェックしてからモデルを出力する

## ルール10：静かな失敗を観測する

他のシステムよりも機械学習のシステムは失敗が分かり難い。データをチェックすることでこの失敗は観測しやすい。

## ルール11：特徴量を設定したオーナーの把握とドキュメントを用意しておく

特徴量を設定したオーナーにその特徴量は何か、どんなことに気をつけるか、どのように助けてくれるかがわかるドキュメントを用意しておくとシステムが巨大になり特徴量が増えてもメンテナンスできる

# あなたの最初の目的

## ルール12：どの目的を最適化するのに選ぶか考えすぎないこと

多くのユーザーをハッピーにしてお金もうけしたいならたくさんの評価尺度をケアしないといけないけど、それは現実的でない。そのかわり単純な方法を保って評価尺度のバランスを考えすぎずにしよう。もし直接的に評価尺度を最適化できる場合でも目標の変更が要求されるかもしれないのでプロダクトにローンチするのは控えよう。

## ルール13：シンプルなことを保つ、観測できてかつあなたの目的に関係する評価尺度を決める。

あなたは本当の目的を知らない。データを見たり、過去のシステムと新しい機械学習のシステムを分析したりして気付きたいと思っている。機械学習の目的関数は本当の目的の代替で成り立つ。その方がシンプル。例を挙げると

１：クリックのランク
２：ダウンロードのランク
３：メールの送信と返信のランク
４：スパムかポルノか攻撃か

間接的な場合

１：ユーザーは過去に次の日も訪れたか
２：ユーザーの滞在時間は
３：日ごとのアクティブユーザーは何をしていたか

間接的な尺度はA/Bテストを行えば測れる。下記のような尺度は取れない

１：ユーザーはプロダクトで幸せになったか
２：ユーザーは体験に満足しているか
３：プロダクトはユーザーを向上させているか
４：企業の健康状態にどの程度影響を与えているか

これは真の目的かもしれないが測るのが困難なので、置き換えで考える。例えばユーザーがハッピーならば長くサイトに滞在しているなdp

## ルール14：解釈可能なモデルの方がデバッグが簡単なので良い

線形回帰やロジスティック回帰、確率的なモデルに従ったポアソン回帰
これらの予測値は解釈可能な確率と値になる。
このことによってデバッグが容易になる。

単純なモデルはフィードバックループを受けることが容易

## ルール15：スパムフィルターとランキングの品質評価は分ける

ランキングの品質の評価はその評価だけに着目する。スパム評価も混ぜて評価を下げない。
スパムフィルターでスパムを取り除いた後にランキング評価を行う。
正反対な効果をもたらすものは分けて処理をしないと効果的でない。

#特徴量エンジニアリング

## ルール16：計画にローンチとその回数を含める

ローンチは何回もする前提にするべきでその理由は下記の3つである。

１：新しい特徴量の設定
２：チューニングや正則化、古い特徴量の新たな組み合わせ
３：目標へのチューニング

特徴量の追加や削除、新たな組み合わせをどれだけ楽にできるか考える。
正しさの確認とどれだけ楽にコピーできるかを考える。
並列にコピーができないかも考える。

## ルール17：始めは直接的に観測かつ報告可能な特徴量を使用する。

クラスタリングやファクターモデル、深層学習のような特徴量を機械学習側で抽出する手法は役に立つがたくさんの課題があるので最初のモデルには使用しない。
ファクターモデルや深層学習を使用する場合は多大なるケアが必要なことに気づくべき

## ルール18：意図を生成するような内容の特徴量を探索する

例を挙げて説明

What's Hotを多くの人が見て、シャアしてコメントするか

Youtubeの閲覧者数、他のビデオを見た後に同じものを何度見るか
ユーザー率
ユーザーアクションに基づくユーザーラベル
アクションに基づく文書

これらの特徴量は新たな内容を意図に追加している

## ルール19：使えるなら特定の特徴量を使う

大量のデータの場合は大量のシンプルな特徴量は複雑な少ない特徴量を超える。

## ルール20：人間が理解できる方法で既存の特徴量を修正して組み合わせる

標準的なアプローチは離散化と共起

詳しい内容は参考資料へ

## ルール21：データの量と特徴量の数はバランスを考慮する

検索システムを例に挙げて説明

1：ミリオンレベルの異なる単語がドキュメント内にあり1000ラベルのExampleがあればHuman Engineeringした特徴量を使用する。
2：ミリオンのExampleがあれば正則化と特徴量の選択が必要。10ミリオンで10万程度の特徴量
3：ビリオンもしくは100ビリオンの場合も正則化と特徴量の選択が必要。ビリオンのデータで10ミリオンの特徴量

## ルール22：使わない特徴量は消しておく

使わない特徴量はインフラから消しておいていつでも戻せるようにしておく。
消すことで速度が向上する

# 人間によるシステムの分析

## ルール23：あなたは典型的なエンドユーザーではない

作成したエンジニアは作成したプロダクトを使ってテストしてはいけない。クラウドソーシングや本当に使っているユーザーに答えをもらうのが一番

理由

1：コードに近いため、感情を持って行動してしまう。
2：エンジニアの時間は価値が高いので単純作業はやらせないほうが良い

早い段階でユーザーペルソナを作ってユーザー体験してもらったほうが良い

## ルール24：既存のモデルと適用したいモデルの差分を測る

新しいモデルを適用したい時は既存のモデルと比較してその変化量が大きければなぜその大きさが出るかを把握する
安定している状態だとモデルの差分は小さい

## ルール25：モデルを選択する時は実用的なパフォーマンス

クリック率を予測する場合に本当にクリック率を予測することが正しいか疑問を持つ。文書の場合はクリック率よりもランキングの質が重要。不本意な向上だと特報量を別に探す。これが多く起きればあなたのモデルの目標を探す時間です。

## ルール26：エラーを計測するパターンを見つけ、新しい特徴量を作成する

分類のタスクではfalse positiveとfalse negative
ランキングのタスクではポジティブなデータがネガティブなデータより低い

機械学習のモデルは同じ特徴量では同じミスが出る。言い換えると特徴量を作り変えると同じミスが出ない。

## ルール27：不要な挙動を観測できる量を定めることを試みる

メジャー First、最適化 Second

## ルール28：短い期間での挙動と長い期間での挙動は異なることに気づくべき

例が参考資料にあります。

# 学習とモデルをデプロイすることの歪みについて

歪みが発生する要因として

・データをハンドルして学習してプロダクションにデプロイのパイプラインに不一致
・学習してプロダクションにデプロイするまでにデータが変わる
・アルゴリズムとモデルへフィードバックが来ること

モニタリングしてデータが変わった時に導入しないことが最良の解決策

## ルール29：最も良い方法は学習してモデルをデプロイする時間に特徴量を保存する。パイプは学習時間内のこれらの特徴量のログを取っておく。

小さな特徴量でも保存してログを取っておき、継続的に確認する。
Youtubeのホームページでの例が参考資料にある。

## ルール30：重みのサンプルデータは重要。無くさないように

たくさんのデータがあった場合に幾つかのデータを無視したくなる衝動にかられる。
重みは重要なので要素の補正は保つ

## ルール31：　テーブルからのデータを学習やプロダクションにデプロイしている時間にジョインした時、テーブルにあるデータは変わっているかも

簡単な解決方法は特徴量のログをディリーベースで取っておくこと。
そうすれば直近のものに復元できる。

## *ルール32：いつでも学習のパイプラインとモデルをプロダクションにデプロイするパイプラインは再利用可能なコードにしておく

バッチプロセスとオンラインプロセスは異なる。
オンラインプロセスではそれぞれ届いたリクエストを操作する必要がある。
バッチプロセスはタスクを合わせられる。

プロダクトにデプロイする際の時間にオンライン処理をしつつバッチプロセスで学習

すべての情報を集めて共通のメソッドで機械学習用のフォーマットに合わせて動作させるのがベター
学習とプロダクトにデプロイするコードが違う言語の場合は使いまわせない。

## ルール33：6月5日までのデータでモデルを作成したらテストは6月6日以降のデータですべき

一般的に過去のデータで学習して未来のデータを予測して性能をつとする必要がある。
もし新しいデータに対して性能が出ない場合はそのモデルは使用しない。

## ルール34：フィルタリングのための2値分類（スパムの発見もしくは興味深いemailを発見）で短い時間を犠牲にしてクリーンなデータをパフォーマンスのために用意する。

仮にフィルタリングのタスクの場合は75％がネガティブな例なのでフィルタリングして学習させる。これはサンプルのバイアスが入っているため1％減らして74％をブロックするようにしてそれを"held out"方式で学習データを作成する

仮に95％の場合はもっと小さく0.1%もしくは0.01%でデータを作成すると十分な精度の出るデータが作成できる

## ルール35：ランキング問題の歪みの継承に気づく

ランキングアルゴリズムを変更する時は十分な変更が見られるかどうか判断してから行う。

1：特徴量の高い正則化によってユニークな特徴量のみ残り、不要なクエリをしなくても良くなる
2：重みが正のものだけにする。良くわからない特徴量を考慮しなくても良くなる
3：文書だけの特徴量ではだめ。シンプルに効果のある特徴量もいれるべき。アプリであればダウンロード数など

## ルール36：場所の特徴量をフィードバックループに入れない。

場所の情報はどうしても支配的でかつ強くなる。例えばアプリのダウンロードボタンの設置場所の場合は最初にベストの場所をいれると他の特徴量よりも優先される。なぜなら強力に効果を発揮するから

効果を発揮する強力な特徴量は他の特徴量とは別にして考える。
それ自体は有効だが他の特徴量の効果を計れなくなる

## ルール37：学習とモデルのデプロイの歪を測っておく

歪の原因はいくつかあるがこれは分離が可能

１：学習データとホールドアウトデータのパフォーマンスが異なることがあるがこれは一般的なのでいつも悲観的になる必要はない
2：次の日にパフォーマンスが下がることもよくある。そのときにチューニングしておくべき。ただし大幅にパフォーマンスが落ちた場合はいくつかの特徴量が時間に関連性が深い場合がある
3：次の日、現状のデータからいくつか抽出して学習してデプロイして結果を確認して同一でない場合はどこかで間違っている

# 機械学習 Phase2：グロースが遅い、最適化改善、複雑なモデル

ここから先は答えがないのでそれぞれ自分たちの最適な道を探してね

## ルール38：もし設定されていない目的が出てきているなら、新しい特徴量に無駄な時間を割かない。

計測結果が安定してきたら、一旦、外からあなたの機械学習が目的を達成しているかみよう。もしそのときに機械学習の目的関数があなたのプロダクトの目的と一致していないなら機械学習の目的関数もしくはプロダクトの目的を変更しよう

## ルール39：長期的な価値に基づいてモデルをローンチするかどうか決める。

具体的な例は参考資料にて
短期的な利益を取るか長期的な利益を取るために今は損をするか

”5年後にこのプロダクトがどうなっていたいかが観点”

## ルール40：組み合わせはシンプルに

シンプルな特徴量とシンプルなモデルは解釈性が高い
組み合わせのモデルは精度が高いが下記のことに気をつけよう

１：モデル組み合わせるときはベースとなるモデルの出力を他のモデルに入れるべき
２：多数の特徴量をベースとなるモデルに導入

## ルール41：パフォーマンスが向上しない場合は新しい情報元を見たほうが良い

単純な特徴量や正則化をしても精度が向上しないときがくる。その時は新しい特徴量を入れましょう。投資や複雑さの増加に見合うものを入れることを考えてやりましょう。

## ルール42：多様性、個別最適化、関連性には期待しないこと。人気とは共通性がないので

直接的には多様性、個別最適化、関連性は人気には関係ないが長期的な目標達成には価値がある。

## ルール43：あなたの友人は違うプロダクトでも同様に振る舞うかもしれない。あなたがそうでなくても

他のプロダクトで使った履歴は違うプロダクトでも役に立つ。

# まとめ

ここまで網羅的に機械学習のプラクティスの方法が載っている資料は珍しいと思うので今後の参考にしていきたいと思っています。

これを公開してくれているGoogleの研究開発者である”Martin Zinkevich”には感謝です！！