はじめに
本書は、機械学習の基礎概念から深層学習の実装まで、Aurélien Gérón氏が体系的にまとめた実践書です。
scikit-learn・Keras・TensorFlowという業界標準ツールを軸に、理論と実装の両輪で学べる構成になっています。
第I部でクラシックな機械学習、第II部でニューラルネットワーク・深層学習を扱います。
第I部:機械学習の基礎
1章:機械学習とは何か
機械学習の定義から始まり、システムのタイプ分類を丁寧に整理しています。
学習の分類軸
| 軸 | 種類 |
|---|---|
| 教師の有無 | 教師あり / 教師なし / 半教師あり / 自己教師あり / 強化学習 |
| 学習タイミング | バッチ学習 / オンライン学習 |
| 汎化方法 | インスタンスベース / モデルベース |
教師あり学習では、ラベル付きデータでモデルを学習します。代表タスクは分類と回帰です。
教師なし学習は、クラスタリング・次元削減・異常検知などで活用されます。
強化学習は、エージェントが環境からの報酬を最大化する方策を学習します。AlphaGoがその好例です。
バッチ学習とオンライン学習
バッチ学習はすべてのデータで一括学習し、オフラインで実行されることが多い方式です。
時間経過によるモデルの性能低下(モデル劣化 / データドリフト)への対策として、定期的な再学習が必要です。
オンライン学習はデータを逐次的に処理し、リソースが限られる環境や急変するデータに適しています。
学習率(learning rate)が高すぎると新データへの過適応、低すぎるとノイズに対して鈍感になります。
機械学習が抱える課題
- 学習データの量の不足
- 非代表的なデータ(サンプリングバイアス)
- 品質の低いデータ
- 無関係な特徴量
- 過学習(overfitting)
- 過少適合(underfitting)
「データとアルゴリズムのどちらが重要か」という問いに対し、Banko & Brill(2001)は「十分なデータがあれば、異なるアルゴリズムでもほぼ同等の性能が出る」という結果を示しています。データの質と量が土台です。
モデルの検証とハイパーパラメータ調整
| 手法 | 概要 |
|---|---|
| ホールドアウト検証 | 学習セットの一部を検証セットとして取り分ける |
| 交差検証(k-fold) | データをk分割し、ローテーションで評価する |
| 学習-開発セット | データミスマッチ問題の診断に使う手法 |
ノーフリーランチ定理:データに前提を設けなければ、あるモデルが別のモデルより優れているとは言えません。すべての候補を試すことはできないため、合理的な前提のもとで候補を絞り込む必要があります。
2章:機械学習プロジェクトの全体像
カリフォルニアの住宅価格予測プロジェクトを題材に、エンドツーエンドのワークフローを解説します。
プロジェクトの主要ステップ
① 全体像を把握する
② データを取得する
③ データを探索・可視化する
④ アルゴリズム向けにデータを準備する
⑤ モデルを選択・学習する
⑥ モデルをファインチューニングする
⑦ ソリューションをプレゼンする
⑧ 本番稼働・モニタリング・メンテナンス
性能指標の選択
回帰問題では RMSE(二乗平均平方根誤差)が一般的な指標です。
外れ値が多い場合は MAE(平均絶対誤差)の採用も検討します。
ℓ1ノルム(MAE)よりもℓ2ノルム(RMSE)の方が大きな誤差に重みをかける特性があります。
テストセット設計:層別サンプリング
純粋なランダム分割は、重要な属性の分布を歪めるリスクがあります。
例として、収入の中央値が住宅価格の強い予測子である場合、収入カテゴリごとに適切な割合が含まれるよう 層別サンプリング(StratifiedShuffleSplit) を使います。
データ準備パイプライン
scikit-learnの設計原則(推定器 / 変換器 / 予測器の3役割)に従い、Pipeline と ColumnTransformer を組み合わせて一貫した前処理を構築します。
preprocessing = ColumnTransformer([
("bedrooms", ratio_pipeline(), ["total_bedrooms", "total_rooms"]),
("log", log_pipeline, ["total_bedrooms", "total_rooms", "population",
"households", "median_income"]),
("geo", cluster_simil, ["latitude", "longitude"]),
("cat", cat_pipeline, make_column_selector(dtype_include=object)),
], remainder=default_num_pipeline)
カスタム変換器(ClusterSimilarityなど)をパイプラインに組み込むことで、k-meansクラスタ重心との類似度を特徴量として追加できます。前処理ハイパーパラメータもモデルハイパーパラメータと合わせてグリッドサーチで最適化できる点が大きなメリットです。
モデル選択と交差検証
| モデル | RMSE(交差検証) |
|---|---|
| LinearRegression | 約 69,858 |
| DecisionTreeRegressor | 約 66,868(過学習あり) |
| RandomForestRegressor | 約 47,019 |
ランダムフォレストが最も良好でしたが、それでも訓練誤差と検証誤差の乖離(過学習)が見られました。
GridSearchCV や RandomizedSearchCV でハイパーパラメータを探索し、最終的な RMSE は約 41,424 まで改善しています。
本番稼働と運用
- joblib でモデルを保存し、REST API として提供する構成が一般的です
- モデルの性能はライブでモニタリングし、劣化を検知したら再学習を自動化します
- データセット・モデル・ハイパーパラメータは全バージョンをバックアップし、ロールバックに備えます
3〜9章:古典的な機械学習アルゴリズム群
| 章 | テーマ | キーポイント |
|---|---|---|
| 3章 | 分類 | 精度・再現率・F1スコア、混同行列 |
| 4章 | モデルの学習 | 線形回帰、正則化(Ridge / Lasso / ElasticNet)、学習曲線 |
| 5章 | SVM | ソフトマージン、カーネルトリック(RBF・多項式) |
| 6章 | 決定木 | CART、Gini不純度、過学習リスク |
| 7章 | アンサンブル学習 | バギング、ランダムフォレスト、ブースティング(AdaBoost・Gradient Boosting) |
| 8章 | 次元削減 | PCA、カーネルPCA、LLE |
| 9章 | 教師なし学習 | k-means、DBSCANs、混合ガウスモデル |
第II部:ニューラルネットワークと深層学習
10〜11章:Kerasによるニューラルネットワーク設計
Kerasの3つのAPIスタイル(Sequential / Functional / Subclassing)を状況に応じて使い分けます。
| トピック | 詳細 |
|---|---|
| 活性化関数 | ReLU / ELU / SELU / Swish |
| バッチ正規化 | 各層の出力を標準化し、深いネットで安定した学習を実現 |
| ドロップアウト | 正則化として過学習を抑制 |
| 学習率スケジューリング | 指数的減衰・1サイクルポリシーなど |
| オプティマイザ | SGD / Adam / Nadam / RMSProp |
12章:TensorFlowで作るカスタムモデルとその学習
Kerasの高水準APIでは対応できない場面のために、TensorFlowの低水準APIを活用します。
テンソルの基本操作
TensorFlowのテンソルはNumPyの ndarray に近い概念で、GPUサポートと計算グラフ最適化が加わります。
import tensorflow as tf
t = tf.constant([[1., 2., 3.], [4., 5., 6.]])
tf.square(t) # 要素ごとの二乗
t @ tf.transpose(t) # 行列乗算
tf.Variable はバックプロパゲーションで更新可能なミュータブルなテンソルです。
カスタム損失関数
def huber_fn(y_true, y_pred):
error = y_true - y_pred
is_small_error = tf.abs(error) < 1
squared_loss = tf.square(error) / 2
linear_loss = tf.abs(error) - 0.5
return tf.where(is_small_error, squared_loss, linear_loss)
model.compile(loss=huber_fn, optimizer="nadam")
ハイパーパラメータ(しきい値など)を保存・復元したい場合は keras.losses.Loss のサブクラスとして実装し、get_config() メソッドを定義します。
カスタム層
class MyDense(tf.keras.layers.Layer):
def __init__(self, units, activation=None, **kwargs):
super().__init__(**kwargs)
self.units = units
self.activation = tf.keras.activations.get(activation)
def build(self, batch_input_shape):
self.kernel = self.add_weight(
name="kernel",
shape=[batch_input_shape[-1], self.units],
initializer="glorot_normal")
self.bias = self.add_weight(
name="bias", shape=[self.units], initializer="zeros")
def call(self, X):
return self.activation(X @ self.kernel + self.bias)
def get_config(self):
base_config = super().get_config()
return {**base_config, "units": self.units,
"activation": tf.keras.activations.serialize(self.activation)}
build() メソッドは層が初めて呼ばれるときに実行されます。入力の形状(batch_input_shape[-1])が確定した時点で重みを生成する設計になっているため、コンストラクタで形状を決め打ちする必要がありません。
自動微分(GradientTape)
w1, w2 = tf.Variable(5.), tf.Variable(3.)
with tf.GradientTape() as tape:
z = 3 * w1 ** 2 + 2 * w1 * w2
gradients = tape.gradient(z, [w1, w2])
# → [36.0, 10.0]
テープはすべての変数に関わる演算を記録し、gradient() の呼び出し時に逆方向に1回だけトレースすることで勾配を計算します。
カスタム学習ループ
for epoch in range(1, n_epochs + 1):
for step in range(1, n_steps + 1):
X_batch, y_batch = random_batch(X_train_scaled, y_train)
with tf.GradientTape() as tape:
y_pred = model(X_batch, training=True)
main_loss = tf.reduce_mean(loss_fn(y_batch, y_pred))
loss = tf.add_n([main_loss] + model.losses)
gradients = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
複数オプティマイザの使い分けや、勾配への独自変換が必要な場面でカスタムループが有効です。ただし、コードが複雑になるため、fit() メソッドで実現できる場合は使用を避けます。
TF関数と AutoGraph
@tf.function デコレータで Python 関数を TensorFlow 計算グラフに変換し、実行を高速化できます。
@tf.function
def tf_cube(x):
return x ** 3
AutoGraph が for / while / if などのフロー制御を TensorFlow 演算(tf.while_loop 等)に自動変換します。TF 関数内では NumPy 関数ではなく TensorFlow 演算を使うことが原則です。
13〜19章:深層学習の応用テーマ
| 章 | テーマ |
|---|---|
| 13章 | tf.data による高効率データパイプライン |
| 14章 | CNN(畳み込みニューラルネットワーク) |
| 15章 | RNN・LSTM・GRUによる時系列処理 |
| 16章 | アテンション機構・Transformer・NLP |
| 17章 | オートエンコーダ・GAN・拡散モデル |
| 18章 | 強化学習(Q学習・方策勾配・アクタークリティック) |
| 19章 | 本番環境へのデプロイ(TF Serving・Vertex AI・分散学習) |
全体を通じた設計思想
本書全体を通じて、以下の考え方が一貫しています。
- データが土台 — どんなアルゴリズムも、データの量と質が決め手になります
- パイプライン化 — 前処理〜学習〜評価を一貫した Pipeline に収めることで再現性を担保します
- 実験の反復 — データ探索 → 特徴量エンジニアリング → モデル選択のサイクルを回し続けます
- 本番を見据えた設計 — モニタリング・バージョン管理・ロールバックを初期段階から組み込みます
学習ループ、カスタム損失、自動微分など、TensorFlowの低水準APIは強力ですが、複雑さのトレードオフを伴います。Kerasの高水準APIで実現できる場合は、fit() + コールバックを優先することが推奨されています。
おわりに
本書はページ数も情報量も膨大ですが、1〜2章のプロジェクト体験から始まり、アルゴリズムを積み上げ、最終的に本番デプロイまで扱う構成は非常に実践的です。
理論と実装のバランスが取れており、手を動かしながら「機械学習の地図」を体得するための良書だと感じました。
付属のノートブック(Google Colab)と合わせて読み進めることで、コードの動作確認をしながら理解を深めることができます。