# 機能設計書 59-等張回帰

## 概要

本ドキュメントは、Apache Spark MLlibが提供する等張回帰（IsotonicRegression）機能の設計を記述する。本機能は、単調増加または単調減少の制約の下でデータにフィットする非パラメトリック回帰手法を提供する。

### 本機能の処理概要

等張回帰は、予測値が入力特徴量に対して単調（増加または減少）であるという制約を課した回帰分析である。Pool Adjacent Violators（PAV）アルゴリズムの並列化版を使用して実装されている。

**業務上の目的・背景**：確率キャリブレーション（分類器の出力スコアを実際の確率に変換）、単調性が仮定される関係のモデリング（例: 経験年数と給与の関係）、用量反応曲線の推定等で利用される。

**機能の利用シーン**：確率キャリブレーション（Platt scaling後の補正）、単調性制約付き回帰、区分線形関数によるフィッティングで利用される。

**主要な処理内容**：
1. 単変量特徴量の抽出（Vectorの場合はfeatureIndex指定で1要素を抽出）
2. Parallelized Pool Adjacent Violators (PAV) アルゴリズムの実行
3. 区分線形関数による予測モデルの構築
4. 新規データに対する区分線形補間による予測

**関連システム・外部連携**：mllib IsotonicRegressionの内部利用。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能に直接関連する画面はなし |

## 機能種別

計算処理（機械学習 - 等張回帰）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| isotonic | Boolean | No | 単調増加(true)/単調減少(false)（デフォルト: true） | - |
| featureIndex | Int | No | Vector特徴量のインデックス（デフォルト: 0） | >= 0 |
| featuresCol | String | No | 特徴量列名（デフォルト: "features"） | Double型またはVector型 |
| labelCol | String | No | ラベル列名（デフォルト: "label"） | - |
| predictionCol | String | No | 予測列名（デフォルト: "prediction"） | - |
| weightCol | String | No | 重み列名 | - |

### 入力データソース

DataFrame形式。特徴量列はDouble型またはVector型（Vectorの場合はfeatureIndexで要素を指定）。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| prediction | Double | 区分線形関数による予測値 |

### モデル属性

| 属性名 | 型 | 説明 |
|--------|-----|------|
| boundaries | Vector | 区分境界点（単調増加順） |
| predictions | Vector | 各境界点に対応する予測値（単調） |

### 出力先

入力DataFrameに予測列を追加。

## 処理フロー

### 処理シーケンス

```
1. スキーマ検証（ラベル列・特徴量列の型確認）
2. 訓練データの抽出: (label, feature, weight) の RDD
   └─ Vector特徴量の場合はfeatureIndexで要素抽出
3. データのキャッシュ（非永続の場合）
4. mllib IsotonicRegression.run()で PAVアルゴリズム実行
5. IsotonicRegressionModel生成（boundaries, predictions, isotonic）
```

### フローチャート

```mermaid
flowchart TD
    A[開始: fit] --> B[スキーマ検証]
    B --> C{特徴量列の型?}
    C -->|Double| D[そのまま使用]
    C -->|Vector| E[featureIndexで要素抽出]
    D --> F[RDD: (label, feature, weight)]
    E --> F
    F --> G[必要ならキャッシュ]
    G --> H[MLlib IsotonicRegression.run]
    H --> I[IsotonicRegressionModel生成]
    I --> J[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-59-01 | 単変量回帰 | 単変量（1つの特徴量）のみサポート | 常時 |
| BR-59-02 | 特徴量型 | featuresColはDouble型またはVector型（VectorUDT）のみ | 常時 |
| BR-59-03 | 単調性制約 | isotonic=trueで単調増加、falseで単調減少 | 常時 |
| BR-59-04 | 区分線形予測 | 予測は境界点間の線形補間 | 予測時 |

### 計算ロジック

- 訓練: PAVアルゴリズムにより、単調性制約を満たすステップ関数を構築
- 予測: 区分線形補間。`boundaries`の範囲外は境界値の予測を返す

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

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | RequireError | featuresCol型がDoubleでもVectorでもない | 適切な型の列を使用 |

### リトライ仕様

特になし。

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

Sparkの遅延評価に基づく。

## パフォーマンス要件

- PAVアルゴリズムは並列化されている
- 入力データが非永続の場合、MEMORY_AND_DISKでキャッシュ

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

Sparkの標準セキュリティ機構に従う。

## 備考

- Spark 1.5.0で導入
- 内部的にmllib.regression.IsotonicRegressionを使用
- Estimator直接継承（Regressorではない）
- numFeaturesは常に1

---

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | IsotonicRegression.scala | `mllib/src/main/scala/org/apache/spark/ml/regression/IsotonicRegression.scala` | IsotonicRegressionBase（45-123行目）でisotonic, featureIndexパラメータ定義 |
| 1-2 | IsotonicRegression.scala | 同上 | extractWeightedLabeledPoints()（84-101行目）で特徴量抽出ロジック |

**読解のコツ**: IsotonicRegressionはRegressorを継承せず、Estimator[IsotonicRegressionModel]を直接継承している。これは単変量回帰であり、Regressorが想定するVector特徴量の枠組みに当てはまらないため。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | IsotonicRegression.scala | 同上 | fit()（170-188行目） |

**主要処理フロー**:
1. **171行目**: transformSchemaでスキーマ検証
2. **173行目**: extractWeightedLabeledPointsでRDD取得
3. **174-175行目**: キャッシュ判定と実施
4. **182行目**: mllib IsotonicRegression.run()でPAV実行
5. **187行目**: IsotonicRegressionModel生成

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | IsotonicRegression.scala | 同上 | transform()（250-261行目）でDouble型/Vector型の分岐予測 |
| 3-2 | IsotonicRegression.scala | 同上 | predict()（264行目）でoldModel.predictを呼出し |

**主要処理フロー**:
- **252-258行目**: 特徴量型に応じてUDFを選択
  - DoubleType: `oldModel.predict(feature)`
  - VectorUDT: `oldModel.predict(features(featureIndex))`

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

```
IsotonicRegression.fit(dataset)
    |
    +-- transformSchema(schema)
    +-- extractWeightedLabeledPoints(dataset)
    |       +-- [Vector特徴量の場合] featureIndexで要素抽出
    +-- instances.persist() [非永続の場合]
    +-- MLlibIsotonicRegression.run(instances)
    |       +-- [Parallelized PAV Algorithm]
    +-- new IsotonicRegressionModel(uid, oldModel)

IsotonicRegressionModel.transform(dataset)
    |
    +-- [Double型] udf { feature => oldModel.predict(feature) }
    +-- [Vector型] udf { features => oldModel.predict(features(idx)) }
```

### データフロー図

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

DataFrame          fit()
  (label,          +-- 特徴量抽出(Double/Vector)      IsotonicRegressionModel
   features,       +-- PAVアルゴリズム                   (boundaries,
   weight)                                                predictions,
                                                          isotonic)

DataFrame          transform()
  (features)       +-- 区分線形補間                  DataFrame
                                                       (prediction)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| IsotonicRegression.scala | `mllib/src/main/scala/org/apache/spark/ml/regression/IsotonicRegression.scala` | ソース | ml API Estimator/Model |
| IsotonicRegression.scala (mllib) | `mllib/src/main/scala/org/apache/spark/mllib/regression/IsotonicRegression.scala` | ソース | PAVアルゴリズムの実装 |
| IsotonicRegressionModel.scala (mllib) | `mllib/src/main/scala/org/apache/spark/mllib/regression/IsotonicRegressionModel.scala` | ソース | 区分線形予測の実装 |
