# 機能設計書 46-勾配ブースティング木分類

## 概要

本ドキュメントは、Apache Spark MLlibにおける勾配ブースティング木分類（GBT Classification）機能の設計を記述する。GBT（Gradient-Boosted Trees）アルゴリズムによる分類モデルの訓練と予測を提供する。

### 本機能の処理概要

勾配ブースティング木分類は、損失関数の勾配方向に逐次的に決定木を追加していくアンサンブル学習手法で、高い予測精度を実現する分類アルゴリズムである。

**業務上の目的・背景**：GBTはKaggle等の機械学習コンペティションで頻繁に上位成績を収めるアルゴリズムであり、精度が最重要視される分類タスクで広く採用されている。ランダムフォレストとは異なり、逐次的に弱学習器を追加することで予測精度を段階的に改善する。

**機能の利用シーン**：二値分類問題において高精度が求められる場面（不正検知、クリック予測、レコメンデーション等）で使用される。現時点では多クラス分類はサポートされていない。

**主要な処理内容**：
1. 入力データのバリデーション（二値分類のみ）
2. GradientBoostedTrees.run()による逐次的な木の訓練
3. 各イテレーションで残差に対する回帰木を構築
4. 予測時に全木の加重和を計算
5. ロジスティック損失に基づく二値分類

**関連システム・外部連携**：Pipeline API、CrossValidator/TrainValidationSplit。

**権限による制御**：特段のロール制御はない。

## 関連画面

本機能に直接関連する画面はない。

## 機能種別

計算処理 / 機械学習分類（アンサンブル・ブースティング）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| featuresCol | String | Yes | 特徴量カラム名 | Vector型カラム |
| labelCol | String | Yes | ラベルカラム名 | 0または1（二値） |
| maxDepth | Int | No | 各木の最大深度、デフォルト5 | 非負整数 |
| maxBins | Int | No | 最大ビン数、デフォルト32 | 2以上 |
| maxIter | Int | No | ブースティングイテレーション数（木の数）、デフォルト20 | 正の整数 |
| stepSize | Double | No | 学習率、デフォルト0.1 | (0, 1] |
| subsamplingRate | Double | No | サブサンプリング率、デフォルト1.0 | (0, 1] |
| lossType | String | No | 損失関数、"logistic"、デフォルト"logistic" | サポートされた値 |
| featureSubsetStrategy | String | No | 特徴量サブセット戦略 | サポートされた値 |
| seed | Long | No | 乱数シード | - |

### 入力データソース

MLlibのDataFrame/Datasetとして提供される二値ラベル付きトレーニングデータ。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| GBTClassificationModel | GBTClassificationModel | 学習済みGBTモデル（DecisionTreeRegressionModel配列 + 重み配列） |
| prediction | Double | 予測クラスラベル（0.0または1.0） |
| rawPrediction | Vector | raw予測値（GBT出力の符号で分類） |
| probability | Vector | 予測確率（ロジスティック関数により変換） |

### 出力先

メモリ内のGBTClassificationModelオブジェクト、またはMLWriter経由で永続化。

## 処理フロー

### 処理シーケンス

```
1. train()メソッド
   └─ 入力検証（二値分類チェック）
   └─ Instance抽出
   └─ GradientBoostedTrees.run()呼び出し
   └─ 各イテレーションで:
       ├─ 現在の残差を計算
       ├─ 残差に対する回帰木を構築
       └─ 木の重み（stepSize）を設定
   └─ GBTClassificationModel構築

2. predictRaw(features)
   └─ 各木のpredict(features)を重み付きで合計
   └─ [-margin, margin]のVector返却

3. raw2probabilityInPlace
   └─ ロジスティック関数で確率に変換
```

### フローチャート

```mermaid
flowchart TD
    A[train開始] --> B[二値分類チェック]
    B --> C[Instance抽出]
    C --> D[GradientBoostedTrees.run]
    D --> E[イテレーション1: 初期木構築]
    E --> F[残差計算]
    F --> G[イテレーション2: 残差に対する回帰木]
    G --> H{maxIter到達?}
    H -->|No| F
    H -->|Yes| I[GBTClassificationModel生成]
    I --> J[predict: 全木の加重和]
    J --> K[ロジスティック関数で確率変換]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-46-01 | 二値分類のみ | 多クラスラベルはサポートされない | 常時 |
| BR-46-02 | 不純度固定 | GBTでは不純度は常に"Variance"が使用される（setImpurityは無視） | 常時 |
| BR-46-03 | 損失関数 | ロジスティック損失を使用 | 分類モード時 |

### 計算ロジック

- GBT予測値: `margin = sum(treeWeights(i) * trees(i).predict(features))`
- 確率変換: `P(y=1) = 1 / (1 + exp(-2 * margin))`
- rawPrediction: `[-margin, margin]`

## データベース操作仕様

本機能はデータベースへの直接操作は行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 警告 | パラメータ警告 | setImpurity呼び出し | GBTでは無視される旨の警告 |

### リトライ仕様

特になし。

## トランザクション仕様

該当なし。

## パフォーマンス要件

- 逐次的な木構築のため、ランダムフォレストに比べて訓練時間が長い
- subsamplingRateで各イテレーションのデータ量を制御可能

## セキュリティ考慮事項

モデル永続化時のアクセス制御を適用する必要がある。

## 備考

- Stochastic Gradient Boostingの実装であり、TreeBoostではない
- 回帰木（DecisionTreeRegressionModel）のアンサンブルとして分類を実現
- setImpurity()は効果がなく、常にVarianceが使用される

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | GBTClassifier.scala | `mllib/src/main/scala/org/apache/spark/ml/classification/GBTClassifier.scala` | GBTClassifierParamsのパラメータ、GBTClassificationModelの構造（DecisionTreeRegressionModel配列 + treeWeights）を理解する |

**読解のコツ**: GBTは分類タスクでも内部的には回帰木（DecisionTreeRegressionModel）のアンサンブルを使用する。分類はロジスティック損失関数とシグモイド変換によって実現される。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | GBTClassifier.scala | `mllib/src/main/scala/org/apache/spark/ml/classification/GBTClassifier.scala` | train()メソッドとGradientBoostedTrees.run()呼び出しを理解する |

**主要処理フロー**:
1. **117-120行目**: `setImpurity`は無視（警告のみ）
2. **64行目**: デフォルトUID "gbtc"
3. **29行目**: GradientBoostedTreesインポート

#### Step 3: 予測処理を理解する

GBTClassificationModelのpredictRaw()がBLAS.dot()等を使用して全木の加重和を計算し、ロジスティック関数で確率に変換する仕組みを理解する。

### プログラム呼び出し階層図

```
GBTClassifier.train(dataset)
    |
    +-- extractInstances(dataset)
    +-- GradientBoostedTrees.run(instances, boostingStrategy)
    |       |
    |       +-- [逐次] 各イテレーション
    |               +-- 残差計算
    |               +-- DecisionTreeRegressionModel構築
    |
    +-- GBTClassificationModel(trees, treeWeights)

GBTClassificationModel.predictRaw(features)
    |
    +-- [各木] trees(i).predict(features) * treeWeights(i)
    +-- margin = sum(weighted predictions)
    +-- Vector(-margin, margin)
```

### データフロー図

```
[入力]                  [処理]                            [出力]

Dataset ──────> GradientBoostedTrees.run
(label=0/1,      |
 features)       +-- イテレーション1: 初期回帰木
                 +-- イテレーション2: 残差回帰木
                 +-- ...
                 +-- イテレーションN: 残差回帰木
                 |
                 v
            GBTClassificationModel
            (trees[], treeWeights[])
                 |
                 v
            predictRaw: margin = sum(w_i * tree_i.predict)
                 |
                 v
            probability: sigmoid(margin)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| GBTClassifier.scala | `mllib/src/main/scala/org/apache/spark/ml/classification/GBTClassifier.scala` | ソース | GBT分類の実装 |
| GradientBoostedTrees.scala | `mllib/src/main/scala/org/apache/spark/ml/tree/impl/GradientBoostedTrees.scala` | ソース | GBTの共通訓練アルゴリズム |
| DecisionTreeRegressionModel | `mllib/src/main/scala/org/apache/spark/ml/regression/DecisionTreeRegressor.scala` | ソース | 個々の回帰木モデル |
| TreeEnsembleModel.scala | `mllib/src/main/scala/org/apache/spark/ml/tree/TreeEnsembleModel.scala` | ソース | アンサンブルモデル基底 |
