10.10-10.13 勾配ブースティング

損失を勾配で削る最強アルゴリズム

XGBoost、LightGBM、GBM——現代のデータ競技で常に上位に君臨するアルゴリズムたち。 その核心にある考え方が「勾配ブースティング」です。 「なぜブースティングが収束するのか」「どうすれば過学習を防げるか」 「複雑な木の集合体からどう知識を読み取るか」を一気に解き明かします。

具体例で理解する「疑似残差」の発想

住宅価格を予測するモデルを作っているとしましょう。最初のモデルは単純に「全物件の平均価格(3000万円)」を予測します。

当然、これは大外れです。1億円の豪邸にも「3000万円」、500万円の古い物件にも「3000万円」。

ここで考えます:「各物件でどれだけ外れているか」がわかれば、そのズレを学習する木を追加できるのでは?

これが残差への当てはめです。1回目の木の後に残る誤差(残差)を新たな学習の目標にする。

しかし、標準的な「残差 = $y_i - f(x_i)$」は、平均二乗誤差を損失関数とした場合にしか通用しません

外れ値の多いデータでは頑健な損失関数(絶対値誤差)を使いたい。分類問題では別の損失関数を使いたい。 そういう場合、「残差」の代わりに何を使えばいいか?

答えは「損失関数の負の勾配」です。損失を $L(y, f(x))$ とすると:

$$r_{im} = -\frac{\partial L(y_i, f(x_i))}{\partial f(x_i)} \bigg|_{f=f_{m-1}}$$

この式が言っていること:「現在の予測 $f(x_i)$ を少し動かしたとき、 損失がどれだけ下がるか」の方向と大きさです。これを疑似残差と呼びます。

平均二乗誤差では $r_{im} = y_i - f(x_i)$(普通の残差)になります。 他の損失関数では違う計算式になりますが、考え方は全く同じです。

下のGIFで、「残差」が「損失を下げる方向」そのものであることを確認してください。 上向きの青い矢印は「予測が低すぎる(もっと上げたい)」、下向きの赤い矢印は「予測が高すぎる(下げたい)」を示しています。

疑似残差の概念 - データ点と水平線からの矢印
水平線(初期予測=全体平均)から各データ点への矢印が「残差」。上=過小予測(青)、下=過大予測(赤)

アルゴリズム — 疑似残差に木を当てはめる繰り返し

疑似残差の概念を使うと、どんな損失関数でも「残差に木を当てはめる」ブースティングが作れます。

勾配ツリーブースティングのアルゴリズム(Algorithm 10.3)を一緒に見ていきましょう。

ブースティングのイテレーション - 3段構成で可視化
上段: 現在の予測曲線。中段: 疑似残差(青=正、赤=負)。下段: 追加する木の出力(緑)

ステップ1: 初期化

定数値から始めます:

$$f_0(x) = \arg\min_\gamma \sum_{i=1}^{N} L(y_i, \gamma)$$

平均二乗誤差なら $f_0 = \bar{y}$(全体平均)です。

ステップ2: m = 1 から M まで繰り返す

(a) 疑似残差を計算:

$$r_{im} = -\left[\frac{\partial L(y_i, f(x_i))}{\partial f(x_i)}\right]_{f=f_{m-1}}$$

(b) 疑似残差を目的変数として J 枚葉の回帰木を学習

(c) 各葉領域 $R_{jm}$ 内で、損失を最小化する予測値 $\gamma_{jm}$ を計算

(d) モデルを更新:

$$f_m(x) = f_{m-1}(x) + \sum_{j=1}^{J_m} \gamma_{jm} \cdot \mathbf{1}(x \in R_{jm})$$

この式が言っていること:前のモデル $f_{m-1}$ に、 今回の木の出力(葉ごとの定数 $\gamma_{jm}$)を足すだけで更新します。

この繰り返しの直感:毎ステップ「今のモデルがどこで外れているか(疑似残差)」を計算して、 そのズレを学習する新しい木を追加します。

損失関数と疑似残差の対応

設定損失関数疑似残差の計算式
回帰(二乗誤差)½(y-f)²yᵢ - f(xᵢ)(普通の残差)
回帰(絶対値誤差)|y-f|sign(yᵢ - f(xᵢ))(方向だけ)
分類Deviance(交差エントロピー)1(yᵢ=Gₖ) - pₖ(xᵢ)(確率のズレ)

損失関数を変えるだけで、同じアルゴリズムが回帰にも分類にも使えます。 これが勾配ブースティングの強さです。

木のサイズ — J 枚葉は何を決めるか?

勾配ブースティングでは、全ての木に同じ枚数の葉(J)を使います。 この J がどんな意味を持つか、直感的に理解しましょう。

木のサイズと相互作用の関係 - 左右分割での比較
左: 1本の縦線 → 2色(1変数のみ)。右: 縦線+横線 → 4色(2変数の組み合わせ)

木を1回だけ分割すると(J=2、葉が2枚):

木を2回分割すると(J=4、葉が4枚):

一般的に、J 枚葉の木は J-1 次の相互作用まで表現できます。

J = 21変数の効果のみ(相互作用なし)
J = 32変数の相互作用まで
J = 65変数の相互作用まで

実際のデータでは変数間の複雑な相互作用は少ないことが多く、J = 4 〜 8が良好な結果を出します。 J = 2 でも主効果のみで十分な問題も多くあります。

最適な J は検証データで確認するのが確実です。

正則化 — 「少しずつ学ぶ」シュリンケージ

ブースティングのイテレーション M を増やすと訓練誤差はどんどん下がりますが、 ある時点でテスト誤差が上昇し始めます——過学習です。

シュリンケージ(学習率はこれを防ぐシンプルで強力な方法です。

各木の寄与を小さな係数 $\nu$(0から1の間)でスケーリングします:

$$f_m(x) = f_{m-1}(x) + \nu \cdot \sum_{j=1}^{J_m} \gamma_{jm} \mathbf{1}(x \in R_{jm})$$

この式が言っていること:毎回の更新を $\nu$ 倍に抑制します。$\nu = 1$ なら従来通り、$\nu = 0.1$ なら1/10のステップで更新。

学習率と過学習の関係 - 赤(大)と青(小)の2曲線
赤(大きな学習率): 急降下後に上昇するU字型=過学習。青(小さな学習率): ゆっくり降下して安定

$\nu$ を「学習率」と呼びます。

大きな学習率(例: $\nu = 1$

各ステップで大きく更新 → 少ない M で収束するが過学習しやすい

小さな学習率(例: $\nu = 0.1$

各ステップで少しずつ更新 → 多くの M が必要だが汎化性能が高い

実験では $\nu < 0.1$ が最も良い結果を出すことが多いです。

$$f_m(x) = f_{m-1}(x) + \nu \cdot \text{(m番目の木の出力)}, \quad 0 < \nu \leq 1$$

「小さい $\nu$ = 多くの M が必要 = 遅い?」

実はそうでもありません。各木が浅くて小さいため、1回の計算は非常に高速。 M が大きくても実用的な速度で動きます。

もう1つの正則化としてサブサンプリングがあります: 各イテレーションで訓練データの一部(典型的に50%)のみをランダムに使います。

シュリンケージとサブサンプリングを組み合わせると、さらに効果的です。 小さな $\nu$(0.05 〜 0.1程度)と大きな M の組み合わせが最高のパフォーマンスをもたらします。

変数重要度 — 「結局どの変数が大事だったか?」

100個の変数でモデルを作った後、「結局どの変数が一番効いていたか?」を知りたくなります。

1本の決定木なら、各変数がどのノードで何度使われ、どれだけ損失を改善したかを数えることができます。

ブースティングでは、M本の木の全体にわたってこれを平均します:

$$I_\ell^2 = \frac{1}{M} \sum_{m=1}^{M} I_\ell^2(T_m)$$

この式が言っていること:「M本の木全体で、変数 $\ell$ が使われるたびに 損失をどれだけ改善したか」の平均値です。

この値が大きい変数ほど「重要な変数」です。通常、最大値を1.0に正規化して横棒グラフで表示します。

変数重要度が収束していく様子
m=1では不安定(バラバラ)、m=100では最終的な重要度が安定する。最重要変数(黄)が収束していく

多数の木で平均することの効果:変数 A と変数 B が相関している(似た情報を持つ)場合、 単一の木ではどちらかが「たまたま」選ばれます。しかし M 本で平均すると、両方が均等に使われ、真の重要性が浮かび上がります

$$I_\ell^2 = \frac{1}{M} \sum_{m=1}^{M} I_\ell^2(T_m)$$

M(木の本数)を増やすほど推定値が安定します。これが「木の集合体」ならではの強みです。変数重要度はモデルの「なぜ」を説明する重要な手がかりになります。

部分従属性プロット — 変数の「効き方の形」を読む

変数重要度で「どの変数が重要か」はわかりました。次は「その変数はどう効くのか」—— その関係の形を知りたい。

例えば、「所得」が住宅価格の重要な変数だとわかっても、「所得が高くなるほど線形に価格が上がるのか」 「あるしきい値を超えると急に上がるのか」を知らないと、モデルの「学んだこと」が理解できません。

しかし、ブースティングのモデル $\hat{f}(X)$ はすべての変数が複雑に絡み合っています。 「所得だけ」の効果を取り出せるでしょうか?

部分従属性プロット(Partial Dependence Plot)は次のように計算します:

$$f_S(X_S) = \frac{1}{N} \sum_{i=1}^{N} \hat{f}(X_S, x_{iC})$$

この式が言っていること:変数 $X_S$(例: 所得)の値を固定し、 その他の全変数 $X_C$ は訓練データ上の全パターンで平均を取る—— これで「他の変数の影響を平均して打ち消した」$X_S$ だけの効果が得られます。

部分従属性プロットの計算過程 - 2D散布図から1D折れ線への変換
左: 2変数(X₁, X₂)の散布図(色=予測値)。帯内の点を平均化して右側の1D折れ線に変換

具体的な手順(「所得」の効果を知りたい場合)

  1. 所得の値のグリッドを作る(例: 300万, 400万, 500万, ...)
  2. 各グリッド値について、全訓練データの「所得」だけをその値に書き換えて予測値の平均を計算
  3. (所得の値, 平均予測値)をプロット

これにより、「他の変数が平均的な値を取る場合に、所得が1単位上がると価格がどう変わるか」が見えます。

注意:所得と立地が強く相関している場合(所得が高い人は良い立地に住む)、 「所得の純粋な効果」と「立地の効果」が混じってしまいます。 相関が強い変数間では解釈に注意が必要です。

変数 $X_S$ 以外を訓練データで「積分(平均化)」することで、$X_S$ の純粋な効果を抽出します。 このプロットを見れば、モデルが「変数をどのように使っているか」が一目でわかります。

まとめ — 勾配ブースティングの全体像

章全体を振り返りましょう。勾配ブースティングの強さは4つのポイントに集約されます。

勾配ブースティングの全フロー - 環状サイクル図
勾配ブースティングのサイクル: 初期化(青)→ 疑似残差計算(緑)→ 木の学習(赤)→ モデル更新(黄)→ 繰り返し
一般性

損失関数を変えるだけで回帰にも分類にも使える

柔軟性

木のサイズ J で相互作用の複雑さを制御できる

正則化

学習率 $\nu$ とサブサンプリングで過学習を防ぐ

解釈可能性

変数重要度と部分従属性プロットで「何を学んだか」を理解できる

実践的な設定の目安

木の葉数 J4 〜 8(典型的な選択)
学習率 $\nu$0.05 〜 0.1 程度
サブサンプリング率0.5(訓練データの50%)
イテレーション数 M検証データで決定

現代の GBM、XGBoost、LightGBM はすべてこの枠組みの実装です。 「勾配ブースティング」を理解していれば、これらの強力なツールの使い方と限界が明確に見えてきます。

「損失を勾配で削る」——このシンプルな発想が、なぜこれほど強力なのかが、 今は少しわかってきたのではないでしょうか。