はじめに
「精度は出たのに、そのモデルは本番に行かなかった」
機械学習の案件に関わったことがある方なら、一度は見た光景ではないでしょうか。本書『Machine Learning Engineering in Action』(Ben Wilson 著 / Manning)は、まさにその「モデルの外側で起きている失敗」に正面から向き合った一冊です。
本書はアルゴリズムの解説書ではありません。損失関数の導出も、最新アーキテクチャの比較もほとんど出てきません。代わりに扱われるのは、要件定義・スコープ設定・会議設計・コードのモジュール化・テスト・ドリフト監視・サービング基盤といった、ソフトウェアエンジニアリングそのものです。
著者は Databricks で数多くのML案件の立ち上げと炎上を経験してきた人物で、本書の記述は一貫して「実際に燃えた現場」の温度感を持っています。読んでいて何度も「これ見たことある」と口に出しそうになりました。
この記事では、本書の全体構成をたどりながら、設計・アーキテクチャに関心のあるエンジニアの視点で特に刺さった論点を整理していきます。
書籍情報
| 項目 | 内容 |
|---|---|
| 原題 | Machine Learning Engineering in Action |
| 邦題 | 機械学習エンジニアリングの実践 |
| 著者 | Ben Wilson |
| 出版社 | Manning Publications |
| 原書刊行 | 2022年 |
| 構成 | 全3部・全16章 + 付録A/B |
| 主な題材 | Python / Spark / MLflow / Hyperopt / SHAP |
本書の立ち位置 ― 「モデルを作る本」ではありません
本書の前提は、冒頭からかなり挑発的です。
ML プロジェクトが失敗する原因の大半は、モデルの性能ではない。
著者が繰り返し指摘するのは、次のような構図です。
- 解くべき問題が定義されないまま、実験が始まっている
- ステークホルダーが期待している出力と、チームが作っている出力が別物
- プロトタイプのスクリプトが、そのまま本番コードになっている
- デプロイ後に誰も監視していないので、静かに劣化していく
これらはすべて、モデリング技術ではなくプロセスと設計の問題です。本書はこの4つの穴を、そのまま3部構成の骨格に落とし込んでいます。
アルゴリズムを学びたい場合は別の本を読むべきです。本書は「ML を成果物として届けるための工学」に特化しています。
全体構成
大きく言えば、「プロジェクトの入口」→「コードの品質」→「本番の基盤」 という順で、上流から下流へ降りていく構成です。
パート1:機械学習エンジニアリング入門(1〜8章)
1〜2章:MLエンジニアリングとは何か
冒頭2章で、著者はMLエンジニアリングを6つの局面として定義します。
- 計画
- スコープ設定と調査
- 実験
- 開発
- デプロイ
- 評価
そのうえで「データサイエンスにはエンジニアリングの力が必要である」と主張します。ここで語られる原則は、実はML固有ではありません。アジャイルの基本原則そのものです。
- コミュニケーションと協働を軽視しない
- 変化を受け入れ、前提として設計する
- シンプルさを基盤に置く
MLの文脈でこれが強調されるのは、ML案件が構造的に「変化しかしない」領域だからです。データは変わり、ビジネス要求は変わり、そもそも何が実現可能かが実験するまで分からない。だからこそ、変化を前提としない設計は最初から破綻している、というのが著者の立場です。
3〜4章:モデリングの前にやること
個人的に、本書で最も価値があると感じたのがこの2章です。
3章では「何を予測してほしいのか」を徹底的に確認させます。印象的なのは、デモを何度もやれという主張です。
- 最初の接触時点で、成果物のイメージを合わせる
- 完成前に、粗くてもいいから見せる
- 見せるたびに認識のズレを潰す
さらに手厳しいのが、「ソリューションを作り込むことで実験する」ことへの警告です。プライドを守るために時間を溶かす行為だ、と切って捨てています。
4章では、会議の設計にまで踏み込みます。
| 会議 | 目的 |
|---|---|
| 実験更新会議 | 方向性が合っているかの確認 |
| SME / プロトタイプレビュー | ドメイン専門家による妥当性検証 |
| 開発進捗レビュー | 実装が要求から逸れていないか |
| MVPレビュー | 要求されたものを作れたか |
| プリプロダクションレビュー | 本番投入前の最終確認 |
会議の話が技術書に載っているのは奇妙に思えるかもしれませんが、著者の主張は明確です。認識ズレの検出が遅れるほど、手戻りのコストは指数的に増える。会議はそのための検査工程である、と。
そして本書で最も有名かもしれない対比が登場します。
- TDD(Test-Driven Development)
- RDD(Resume-Driven Development:履歴書のための開発)
- PDD(Prayer-Driven Development:祈りに駆動された開発)
- CDD(Chaos-Driven Development:混沌に駆動された開発)
RDD は「新しい技術を使いたいから使う」開発、PDD は「Stack Overflow を検索して祈りながら貼り付ける」開発です。笑えるのですが、笑えません。
「バックアッププランは何ですか?」という問いが本書には何度も出てきます。MLは確率的な成果物である以上、うまくいかなかった場合の縮退動作を設計に含めることが必須だという主張です。
5〜8章:実験の実践
ここから実際の実験フェーズに入ります。
5章では「ブログを読むのをやめて API ドキュメントを読め」という、なかなか身も蓋もない助言があります。断片的な記事をつなぎ合わせた理解では、境界条件で必ず破綻するからです。
また、複数のアプローチを比較するときは公平な競争条件を作れと強調されます。前処理もチューニング予算も揃えずに比較して「Aのほうが良かった」と結論づけるのは、単なる思い込みの追認です。
6章はテストと評価、7章はチューニングの自動化(Hyperopt)とスケール戦略(Spark)、8章は MLflow によるトラッキングです。
8章の「print をやめてログを残せ」という主張は、そのまま普段の開発にも効きます。実験の再現性は、記録の有無で決まります。
# 実験結果が print で消えていく世界
print(f"accuracy: {acc}")
# 実験結果が資産として残る世界
with mlflow.start_run():
mlflow.log_params(params)
mlflow.log_metric("accuracy", acc)
mlflow.log_artifact("confusion_matrix.png")
パート2:本番環境の準備(9〜13章)
ここからが、設計・アーキテクチャに関心のある読者にとっての本番です。
9章:モノリシックスクリプトとの決別
ML のコードは、なぜあれほど巨大な1ファイルになりがちなのでしょうか。著者はその発生過程を丁寧に描きます。
- ノートブックで探索を始める
- 動いたセルを下に足していく
- 「あとで整理する」と思いながら足し続ける
- 気づくと2000行のテキストの壁ができている
そしてこの壁の何が悪いかというと、デバッグできない、テストできない、再利用できないという三重苦です。
対策として提示されるのは、ごく普通のソフトウェア設計です。責務ごとに関数を切り、副作用を隔離し、入出力を明示し、テストを書く。特別なことは何も言っていません。しかしMLの現場では、この「普通」が驚くほど徹底されていない、というのが著者の見立てです。
10章:保守可能なMLコードの標準
本書で最も実用的な章です。「MLコードの臭い」として、以下のようなアンチパターンが列挙されます。
命名と構造
-
df,df2,df_final,df_final_v2のような名前 - 賢すぎるワンライナー(読めないコードは負債です)
タプル展開
# 位置が意味を持つため、順序変更で静かに壊れます
train_x, train_y, test_x, test_y = prepare(data)
著者は、要素数が増えるタプル返却をやめ、NamedTuple や dataclass を使うことを推奨しています。
from dataclasses import dataclass
@dataclass
class SplitData:
train_x: pd.DataFrame
train_y: pd.Series
test_x: pd.DataFrame
test_y: pd.Series
例外処理
「ショットガンの精度」と「レーザーの精度」という対比が秀逸です。
# ショットガン: 何が起きたのか永遠に分かりません
try:
result = pipeline(data)
except Exception:
pass
握りつぶした例外は、後工程で必ず、より分かりにくい形で牙をむきます。
グローバルな可変オブジェクト
どこからでも書き換えられる状態は、ML パイプラインのように処理が長い系では致命的です。カプセル化によって副作用を封じ込めるべきだ、と繰り返されます。
過度なネスト
深いネストは、それ自体が設計の失敗のシグナルである、と。
この章は、ML に限らずあらゆる Python コードのレビュー観点として使えます。チーム内のコーディング規約のたたき台としてもよくできています。
11章:モデルの計測
「精度が高い」ことと「ビジネスに貢献している」ことは別である、という当たり前ですが忘れられがちな話です。
- 予測性能の計測(オフライン指標)
- 帰属(attribution)の計測 ― そのモデルが実際に何を変えたのか
- 相関と因果の切り分け
- A/Bテストによる効果検証
連続値の指標とカテゴリ指標のそれぞれについて、評価の勘所が示されます。「モデルが良いかどうかは、モデルの外側でしか測れない」という視点は重要です。
12章:ドリフト
デプロイした瞬間から、モデルは劣化を始めます。
- 入力データ分布の変化(データドリフト)
- 入力と出力の関係性の変化(コンセプトドリフト)
- 上流の仕様変更やバグ
著者は、検出だけでなく対応の設計まで求めます。何を閾値として、誰が判断し、再学習をどう回すのか。これが決まっていない監視は、アラートを増やすだけです。
13章:ML開発の傲慢さ
タイトルからして刺さる章です。扱われるのは、エンジニアの自意識がプロジェクトを壊すパターンです。
- エレガントな複雑さと、単なる過剰エンジニアリングの境界
- 意図しない難読化(自分でも半年後に読めないコード)
- 早すぎる一般化 ― 「汎用フレームワークを作りたくなる病」
- 早すぎる最適化
- 最新のアルファ版・出たばかりのOSSに飛びつくリスク
- 技術主導開発 vs. ソリューション主導開発
「一般化は、できなくなるまで避けろ」という助言は、耳が痛い人が多いのではないでしょうか。まだ2つしか事例がない段階で抽象化した基底クラスは、3つ目の要求で必ず壊れます。
パート3:本番コードの開発(14〜16章)
14章:プロダクションコードを書く
まずデータの話から入ります。
- そのデータは本当に存在するか
- 出所は追跡できるか
- どれが真実の源(source of truth)か
- データクレンジングを本番コードに埋め込むな
最後の指摘は重要です。前処理の中に暗黙のデータ修正が紛れ込むと、学習時と推論時で挙動が変わり、原因究明が極めて困難になります。
また「カーゴカルト的なML行動を避けよ」という節では、意味を理解せずに他所の手法をコピーする姿勢が批判されます。
15章:品質と受入テスト
- 学習時と推論時の歪み(training/serving skew)
- フィーチャーストアの導入意義
- コールドスタート問題と、そのフォールバック設計
- ドッグフーディングと社内テスト
- SHAP によるモデルの解釈可能性
特に skew の話は、実装レベルで再現しにくい不具合の温床として詳しく扱われます。「学習用と推論用で前処理コードが二重管理になっていないか」は、そのままチェックリストになります。
16章:本番インフラ
締めくくりは基盤の話です。
- アーティファクト管理(MLflow Model Registry)
- フィーチャーストアの用途・使い方・評価軸
- 予測サービングのアーキテクチャ
サービング方式は4分類で整理されます。
| 方式 | 特徴 | 向くケース |
|---|---|---|
| バッチ外部配信 | 事前に予測して書き出す | 日次のレコメンド等 |
| マイクロバッチ / ストリーミング | 準リアルタイム | 数分単位の更新 |
| リアルタイム(サーバサイド) | リクエスト時に推論 | 都度の判定が必要な処理 |
| エッジ組込み | 端末側で推論 | オフライン・低遅延要件 |
この分類は、レイテンシ要件・コスト・運用負荷のトレードオフとして提示されており、アーキテクチャ選定の議論のたたき台として非常に使いやすいです。
付録:Big O(no)
付録Aのタイトルは「Big O(no)」です。ML コードにおける計算量とランタイム性能の考え方を扱っています。データ量が増えた瞬間に破綻するコードは、実験では通ってしまうため、事前の見積もりが効きます。
特に刺さった5つの論点
1. 「何を予測してほしいのか」を確認しないまま実験を始めない
技術的に面白い問題と、価値のある問題は違います。着手前に、成果物の形とその使われ方を合意しておくだけで、失敗の大半は防げます。
2. デモの頻度は多すぎるくらいでちょうどいい
認識のズレは、時間の経過とともに修復コストが跳ね上がります。粗い状態で見せることを恥じない文化が必要です。
3. 早すぎる一般化を避ける
抽象化は、繰り返しが「発見された」あとに行うものです。予測して作った抽象は、ほぼ確実に外れます。
4. 例外は握りつぶさない
except Exception: pass は、問題を消すのではなく、発見を遅らせているだけです。
5. 監視は「検出」ではなく「対応」まで設計する
閾値・判断者・再学習トリガー・縮退動作。ここまで決めて初めて運用可能になります。
現場に持ち帰れるチェックリスト
本書を読みながら作った、自分用のチェックリストを共有します。
プロジェクト着手時
- 予測対象と、その予測が使われる意思決定を書き出したか
- 成功の定義(ビジネス指標)を合意したか
- 実験の時間制限を決めたか
- うまくいかなかった場合のフォールバックを決めたか
実験フェーズ
- 比較対象は公平な条件になっているか
- 実験結果はログとして残っているか(print で消えていないか)
- スクリプトが再利用可能な単位に分かれているか
本番化フェーズ
- 学習時と推論時で前処理が二重管理になっていないか
- データの出所と真実の源を特定したか
- ドリフト検出後の対応フローが決まっているか
- サービング方式は要件から選定されているか(流行りではなく)
こんな方におすすめです
向いている方
- ML案件のリードやアーキテクトを担う立場の方
- PoC は動くのに本番に行かない、という状態に心当たりのある方
- データサイエンティストと開発チームの橋渡しをしている方
- ソフトウェア設計の観点からMLに関わりたい方
向いていない方
- アルゴリズムそのものを学びたい方
- 特定フレームワークのハンズオンを求めている方
- 数式ベースの理論的裏付けを期待している方
まとめ
本書を読み終えて残ったのは、「MLエンジニアリングとは、結局のところ不確実性を扱うためのソフトウェアエンジニアリングである」という感覚でした。
出てくる原則の多くは、実はML固有ではありません。責務を分ける、テストを書く、副作用を隔離する、早すぎる抽象化を避ける、変化を前提に設計する。どれも普通の設計原則です。
ただML の領域では、
- 成果物が確率的で、成功が保証されない
- データという外部要因で挙動が変わり続ける
- 探索的なノートブック文化が、そのまま本番に流れ込みやすい
という理由で、この「普通」が特に守られにくい。だからこそ、あえて一冊かけて言語化する価値がある、というのが本書の存在意義だと理解しました。
原書は2022年刊行で、ツール周りの記述(MLflow、Hyperopt、Spark)には時間の経過を感じる部分もあります。ただし本書の核であるプロセス設計とコード品質の議論は、ツールが変わっても陳腐化しません。
MLに関わっていて、技術以外の理由でプロジェクトが止まった経験がある方には、強くおすすめできる一冊です。
参考
- Ben Wilson, Machine Learning Engineering in Action, Manning Publications, 2022