# 機能設計書 49-多層パーセプトロン分類

## 概要

本ドキュメントは、Apache Spark MLlibにおける多層パーセプトロン分類（Multilayer Perceptron Classification）機能の設計を記述する。多層パーセプトロン（ニューラルネットワーク）による分類モデルの訓練と予測を提供する。

### 本機能の処理概要

多層パーセプトロン分類は、全結合フィードフォワードニューラルネットワークによる分類器であり、中間層にシグモイド活性化関数、出力層にソフトマックス関数を使用する。

**業務上の目的・背景**：多層パーセプトロンは、線形分離不可能なデータに対しても非線形な決定境界を学習できる分類器である。特徴量間の複雑な相互作用を捉えることができ、画像認識や自然言語処理等の幅広いタスクに適用される。

**機能の利用シーン**：多クラス分類問題において、線形モデルでは捉えきれない非線形パターンの学習が必要な場面で使用される。入力サイズは特徴量ベクトルの次元数に、出力サイズはクラス数に対応する。

**主要な処理内容**：
1. ネットワークトポロジーの定義（layers配列で入力層、隠れ層、出力層のサイズを指定）
2. FeedForwardTopologyとFeedForwardTrainerによる訓練
3. L-BFGS（準ニュートン法）またはミニバッチ勾配降下法による重み最適化
4. ソフトマックス出力に基づく多クラス分類

**関連システム・外部連携**：Pipeline API。

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

## 関連画面

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

## 機能種別

計算処理 / 機械学習分類（ニューラルネットワーク）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| featuresCol | String | Yes | 特徴量カラム名 | Vector型カラム |
| labelCol | String | Yes | ラベルカラム名 | 非負整数 |
| layers | Array[Int] | Yes | 各層のサイズ配列（入力→隠れ→出力） | 2層以上、各値が正の整数 |
| maxIter | Int | No | 最大反復回数、デフォルト100 | 正の整数 |
| tol | Double | No | 収束許容誤差、デフォルト1E-6 | 正の値 |
| blockSize | Int | No | ミニバッチサイズ、デフォルト128 | 正の整数 |
| solver | String | No | 最適化アルゴリズム、"l-bfgs"/"gd"、デフォルト"l-bfgs" | サポートされた値 |
| stepSize | Double | No | 学習率（gdソルバー時）、デフォルト0.03 | 正の値 |
| seed | Long | No | 乱数シード（重み初期化用） | - |
| initialWeights | Vector | No | 初期重みベクトル | サイズが正しいこと |

### 入力データソース

MLlibのDataFrame/Datasetとして提供されるラベル付きトレーニングデータ。入力層のサイズは特徴量ベクトルの次元数と一致する必要がある。出力層のサイズはクラス数と一致する必要がある。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| MultilayerPerceptronClassificationModel | MultilayerPerceptronClassificationModel | 学習済みモデル（重みベクトル） |
| prediction | Double | 予測クラスラベル |
| rawPrediction | Vector | 各クラスの出力値 |
| probability | Vector | 各クラスの予測確率（ソフトマックス） |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. train()メソッド
   └─ クラス数と特徴量次元数の取得
   └─ layers配列の入力/出力サイズ検証
   └─ FeedForwardTopology.multiLayerPerceptron(layers)でトポロジー構築
   └─ FeedForwardTrainerでトレーナー構築
   └─ ソルバー設定（L-BFGS or GD）
   └─ 初期重み設定（指定時 or ランダム初期化）
   └─ trainer.train(data)で訓練実行
   └─ MultilayerPerceptronClassificationModel構築

2. predict(features)
   └─ フィードフォワード計算（各層: sigmoid活性化→出力層: softmax）
   └─ 最大確率のクラスを予測値として返却
```

### フローチャート

```mermaid
flowchart TD
    A[train開始] --> B[クラス数・特徴量次元取得]
    B --> C[layers検証]
    C --> D[FeedForwardTopology構築]
    D --> E[FeedForwardTrainer構築]
    E --> F{solver}
    F -->|l-bfgs| G[L-BFGS最適化]
    F -->|gd| H[ミニバッチ勾配降下法]
    G --> I[重み最適化]
    H --> I
    I --> J[MultilayerPerceptronClassificationModel生成]
    J --> K[predict: フィードフォワード計算]
    K --> L[softmax出力]
    L --> M[argmax → prediction]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-49-01 | 層サイズ整合性 | layers(0)=特徴量次元数、layers(last)=クラス数 | 常時 |
| BR-49-02 | 活性化関数 | 中間層: シグモイド、出力層: ソフトマックス | 常時 |
| BR-49-03 | 最小層数 | layersは2層以上（入力+出力）が必要 | 常時 |
| BR-49-04 | ソルバー選択 | l-bfgs: 準ニュートン法（デフォルト）、gd: ミニバッチ勾配降下法 | solver設定時 |

### 計算ロジック

- 中間層: `h = sigmoid(W * x + b)`
- 出力層: `P(class=k|x) = softmax(W_out * h_last + b_out)`
- 損失関数: クロスエントロピー

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| IllegalArgumentException | バリデーションエラー | layers(0)が特徴量次元数と不一致 | layersの入力サイズを修正 |
| IllegalArgumentException | バリデーションエラー | layers(last)がクラス数と不一致 | layersの出力サイズを修正 |
| IllegalArgumentException | バリデーションエラー | initialWeightsのサイズが不正 | 正しいサイズのベクトルを設定 |

### リトライ仕様

特になし。

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

該当なし。

## パフォーマンス要件

- blockSizeでミニバッチサイズを制御（大きい値でスループット向上）
- L-BFGSソルバーは一般的にGDより高速に収束

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

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

## 備考

- 活性化関数はシグモイドに固定されており、ReLU等の他の活性化関数は選択できない
- 内部的にOneHotEncoderModelを使用してラベルをone-hotベクトルに変換する

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | MultilayerPerceptronClassifier.scala | `mllib/src/main/scala/org/apache/spark/ml/classification/MultilayerPerceptronClassifier.scala` | MultilayerPerceptronParamsのパラメータ定義（37-86行目）、特にlayers/solver/initialWeightsを理解する |

**読解のコツ**: `layers`パラメータはIntArrayParamで、各要素が各層のニューロン数を表す。例えば`Array(780, 100, 10)`は入力780次元、隠れ層100ニューロン、出力10クラスを意味する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | MultilayerPerceptronClassifier.scala | `mllib/src/main/scala/org/apache/spark/ml/classification/MultilayerPerceptronClassifier.scala` | train()メソッド（150行目以降）でFeedForwardTopology/FeedForwardTrainerの使用を理解する |

**主要処理フロー**:
1. **48-52行目**: `layers`パラメータ定義（バリデーション: 2層以上、各値正の整数）
2. **66-69行目**: `solver`パラメータ定義（"gd" or "l-bfgs"）
3. **77-78行目**: `initialWeights`パラメータ定義
4. **84-85行目**: デフォルト値（maxIter=100, tol=1e-6, blockSize=128, solver="l-bfgs", stepSize=0.03）
5. **96-100行目**: クラス定義（ProbabilisticClassifierを継承）

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

```
MultilayerPerceptronClassifier.train(dataset)
    |
    +-- FeedForwardTopology.multiLayerPerceptron(layers)
    |       +-- 各層のレイヤー定義（AffineLayer + ActivationFunction）
    |
    +-- new FeedForwardTrainer(topology, numInputs, numOutputs)
    |       +-- setSolver("l-bfgs" or "gd")
    |       +-- setInitialWeights(weights)
    |
    +-- trainer.train(data)
    |       +-- [L-BFGS or GD] 重み最適化
    |       +-- 損失: クロスエントロピー
    |
    +-- MultilayerPerceptronClassificationModel(weights)

MultilayerPerceptronClassificationModel.predict(features)
    |
    +-- フィードフォワード計算
    |       +-- 層1: sigmoid(W1 * features + b1)
    |       +-- 層2: sigmoid(W2 * h1 + b2)
    |       +-- ...
    |       +-- 出力層: softmax(Wn * h_last + bn)
    |
    +-- argmax(output) → prediction
```

### データフロー図

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

Dataset ──────> FeedForwardTopology構築
(label,          |
 features)       v
            FeedForwardTrainer
            (solver: L-BFGS/GD)
                 |
                 v
            重み最適化
            (クロスエントロピー損失)
                 |
                 v
            MultilayerPerceptronClassificationModel
            (weights: Vector)
                 |
                 v
            フィードフォワード計算
            (sigmoid → sigmoid → softmax)
                 |
                 v
            (prediction, rawPrediction, probability)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| MultilayerPerceptronClassifier.scala | `mllib/src/main/scala/org/apache/spark/ml/classification/MultilayerPerceptronClassifier.scala` | ソース | 多層パーセプトロン分類の実装 |
| FeedForwardTopology.scala | `mllib/src/main/scala/org/apache/spark/ml/ann/FeedForwardTopology.scala` | ソース | ニューラルネットワークトポロジー定義 |
| FeedForwardTrainer.scala | `mllib/src/main/scala/org/apache/spark/ml/ann/FeedForwardTrainer.scala` | ソース | ニューラルネットワーク訓練器 |
| Layer.scala | `mllib/src/main/scala/org/apache/spark/ml/ann/Layer.scala` | ソース | ニューラルネットワーク層の定義 |
| ProbabilisticClassifier.scala | `mllib/src/main/scala/org/apache/spark/ml/classification/ProbabilisticClassifier.scala` | ソース | 確率的分類器基底クラス |
