Robert C. Martin の Clean Architecture に倣い、Google Cloud のエンジニアたちが何百もの ML チームを観察して共通のベストプラクティスを抽出した「GoF 本の ML 版」的な一冊です。
本書は 30 のデザインパターン を 8 章にわたって体系化しています。各パターンは「問題 → 解決 → トレードオフ」の形式で書かれており、GoF を知っているエンジニアには馴染みやすい構成です。
本書の構成
| 章 | テーマ |
|---|---|
| 1章 | 機械学習デザインパターンの必要性(序論) |
| 2章 | データ表現のパターン(4パターン) |
| 3章 | 問題表現のパターン(6パターン) |
| 4〜7章 | モデル訓練 / 対応性のある運用 / 再現性 / 責任あるAI |
| 8章 | パターンのつながり |
実装例は TensorFlow/Keras・scikit-learn・BigQuery ML が中心です。
1章: ML 固有の共通課題
- データ品質 — 正確性・完全性・一貫性・適時性の 4 要素
- 再現性 — 乱数シード、フレームワークバージョン、分散訓練環境の差異
- データドリフト — 時間とともに入力分布が変化する問題
- 規模 — データ取込・訓練・運用フェーズそれぞれでの課題
- 複数の異なる目的 — DS・PM・経営陣がそれぞれ異なる最適化対象を持つ
2章: データ表現のパターン
パターン 1: 特徴量ハッシュ(Hashed Feature)
問題: カーディナリティが高いカテゴリ変数はワンホットエンコーディングが現実的でない。コールドスタート問題もある。
解決: フィンガープリントハッシュでバケットに写像。語彙の事前知識が不要。
ABS(MOD(FARM_FINGERPRINT(airport), 100)) AS hashed_airport
MD5 など暗号化ハッシュは決定論的でないため使えません。FARM_FINGERPRINT のような決定論的なものを使う必要があります。
トレードオフ: バケット衝突による情報損失。経験則「バケットあたり 5 エントリ」を目安にバケット数を選ぶ。
パターン 2: 埋め込み(Embeddings)
問題: ワンホットエンコーディングでは語彙間の意味的な近さを表現できない。
解決: 埋め込み層で低次元密ベクトルに変換。重みは訓練中に学習される。
plurality_embed = tf.feature_column.embedding_column(plurality, dimension=2)
次元数の目安は unique_categories^(1/4)(4 乗根ルール)。Word2Vec・BERT などの事前訓練済みモデルの転移学習も有効です。
パターン 3: 特徴量クロス(Feature Cross)
問題: 単独では予測力の弱い特徴量でも、組み合わせると非線形の関係を表現できる。
解決: 2 つ以上のカテゴリ型特徴量の直積で合成特徴量を生成する。
gender_x_plurality = tf.feature_column.crossed_column(
["is_male", "plurality"], hash_bucket_size=1000)
BigQuery ML のベンチマークでは特徴量クロスを持つ線形モデルが DNN と同等の RMSE を 100 倍速く 達成しています。
| モデル | 特徴量クロス | 訓練時間(分) | RMSE |
|---|---|---|---|
| 線形 | あり | 0.42 | 1.05 |
| DNN | なし | 48 | 1.07 |
パターン 4: マルチモーダル入力(Multimodal Input)
問題: 画像+メタデータ、テキスト+表形式データなど、異なるデータ形式を単一モデルで扱いたい。
解決: 各モダリティを埋め込みで表現した後、concatenate 層で結合する。
merged = keras.layers.concatenate([embedding_layer, tabular_layer])
output = Dense(1)(Dense(16)(merged))
3章: 問題表現のパターン
パターン 5: 問題再設定(Reframing)
回帰 → 分類: 降雨量予測を 512 クラス分類として学習すると二峰性分布などの不確実性を捉えられます。AlphaFold もアミノ酸間距離を 64 クラス分類として解いています。
分類 → 回帰: 映画推薦を「視聴確率」分類から「ユーザ特性空間での位置」回帰に再設定することで、クリックベイト最適化を避けつつ類似ユーザ探索が可能になります。
ラベルをクリック数に変えるとクリックベイトを促進してしまいます。視聴時間など真の目的に近いラベルを選ぶことが重要です。
パターン 6: マルチラベル(Multilabel)
問題: 1 つのサンプルに複数のラベルを割り当てたい(Stack Overflow の質問タグなど)。
解決: 出力層をソフトマックスからシグモイドに変更し、損失関数は二値交差エントロピーを使う。本質的にはラベル数分の二値分類問題の集合として捉えられます。
keras.layers.Dense(N, activation='sigmoid') # マルチラベル
パターン 7: アンサンブル学習(Ensemble)
| 手法 | 対象 | 仕組み |
|---|---|---|
| バギング | 高分散(過学習) | 復元抽出で k サブセット、並列訓練後に集約 |
| ブースティング | 高偏り(学習不足) | 残差を逐次的に学習、弱 → 強学習器 |
| スタッキング | 両方 | 複数モデルの出力を入力としてメタモデルを訓練 |
ドロップアウトはバギングの近似として解釈できます。
パターン 8: カスケード(Cascade)
問題: 典型ケースと例外ケースで振る舞いが大きく異なる場合、単一モデルでは例外の学習が埋もれる。
解決: 問題を複数の ML モデルに分割し、前段の予測を後段の訓練データ作成に利用する。
前段の予測ラベルで後段の訓練データを作成することが重要です(実際のラベルではなく)。Kubeflow Pipelines や TFX で自動化することが推奨されています。
単純な特徴量追加やマルチモーダル入力で解けるならカスケードは不要です。使いすぎに注意してください。
パターン 9: 中立クラス(Neutral Class)
問題: 専門家間で意見が分かれるケースを二値分類器に押し込むと精度が下がる。
解決: 「どちらでもない」中立クラスを追加した 3 クラス分類に変更する。出生データでのアプガースコア分類の精度が 0.56 → 0.79 に改善した例が示されています。
中立クラスは事後的に設定できません。データ収集設計の段階で組み込む必要があります。
パターン 10: リバランシング(Rebalancing)
問題: 不正取引・欠陥品など、レアケースの検出では少数派クラスが 0.1% 未満になることがある。
評価指標: 正解率ではなく適合率・再現率・F 値・PR-AUC を使う。
| 手法 | 概要 |
|---|---|
| ダウンサンプリング | 多数派クラスを削減 |
| クラス重み付け |
class_weight で少数派を重視 |
| アップサンプリング(SMOTE) | 少数派の合成データを生成 |
| データ拡張 | 画像・テキストの変換で水増し |
4〜7章の概要
- 4章 モデル訓練: チェックポイント・転移学習・分散訓練・価値ある過学習
- 5章 対応性のある運用: ステートレス関数・キー付き予測・継続的モデル評価
- 6章 再現性: 変換パターン(訓練/推論スキューを防ぐ)・再現可能なサンプリング・特徴量ストア
- 7章 責任あるAI: 説明可能な予測(SHAP 値)・フェアネスレンズ
感想
パターン名があると議論が楽になります。「これ特徴量ハッシュじゃない?」「カスケード使うべきか?」という会話ができます。GoF や Clean Architecture と同様に、共通言語としての価値が高いです。
一方で GCP(BigQuery ML・Vertex AI)前提のコードが多く、他環境の読者は読み替えが必要です。また 2020 年刊行のため Transformer 以降のアーキテクチャはほぼ扱われていません。
実務で使える頻度が高いと感じたトップ 5
- 特徴量ハッシュ — カーディナリティ問題は必ず来る
- リバランシング — 不均衡データは業務データでは当たり前
- 変換パターン — 訓練/推論スキューは気づかないうちに起きている
- 継続的モデル評価 — データドリフトを監視しない ML は機能停止に向かう
- 問題再設定 — 「本当にこれは回帰問題か?」を問い直す視点
参考: Valliappa Lakshmanan, Sara Robinson, Michael Munn「Machine Learning Design Patterns」(2020, O'Reilly)