# 機能設計書 57-AFT生存回帰

## 概要

本ドキュメントは、Apache Spark MLlibが提供するAFT生存回帰（AFTSurvivalRegression）機能の設計を記述する。本機能は、加速故障時間（Accelerated Failure Time）モデルに基づくパラメトリック生存分析を提供する。

### 本機能の処理概要

AFT生存回帰は、Weibull分布に基づくパラメトリック生存時間モデルである。打ち切りデータ（censored data）を適切に扱い、生存時間の予測と分位数の推定を行う。

**業務上の目的・背景**：生存分析は医療（患者の生存時間予測）、工業（機器の故障時間予測）、マーケティング（顧客の離脱時間予測）等の分野で広く用いられる。データには打ち切り（イベントが観測期間内に発生しなかった）が含まれることが多く、通常の回帰分析では適切に扱えない。

**機能の利用シーン**：生存時間分析、信頼性工学（故障時間予測）、顧客生涯価値分析、チャーン予測で利用される。

**主要な処理内容**：
1. 打ち切り情報（censorCol）を考慮したデータ処理
2. L-BFGS最適化によるパラメータ推定（係数、切片、スケール）
3. 特徴量の標準化とブロック化による最適化
4. 分位数予測の出力

**関連システム・外部連携**：Breezeライブラリ（L-BFGS）、AFTBlockAggregatorによるブロック集約。

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

## 関連画面

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

## 機能種別

計算処理（機械学習 - 生存分析）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| censorCol | String | No | 打ち切りフラグ列名（デフォルト: "censor"） | 値は0または1 |
| quantileProbabilities | Array[Double] | No | 分位数確率（デフォルト: [0.01,0.05,0.1,0.25,0.5,0.75,0.9,0.95,0.99]） | (0,1)の範囲 |
| quantilesCol | String | No | 分位数出力列名 | - |
| fitIntercept | Boolean | No | 切片推定（デフォルト: true） | - |
| maxIter | Int | No | 最大反復回数（デフォルト: 100） | >= 0 |
| tol | Double | No | 収束判定閾値（デフォルト: 1E-6） | >= 0 |
| aggregationDepth | Int | No | treeAggregate深度（デフォルト: 2） | >= 2 |
| maxBlockSizeInMB | Double | No | ブロックサイズ（デフォルト: 0.0=自動1MB） | >= 0 |

### 入力データソース

DataFrame形式。ラベル列（生存時間）はDouble型かつ正値、打ち切り列は0/1のDouble型、特徴量列はVector型。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| prediction | Double | 予測生存時間 |
| quantiles | Vector | 各分位数確率に対応する予測生存時間（quantilesCol設定時） |

### 出力先

入力DataFrameに予測列を追加。

## 処理フロー

### 処理シーケンス

```
1. 入力検証（打ち切りフラグは0/1、ラベルは正値）
2. 特徴量の統計量計算（平均、標準偏差）
3. 特徴量の標準化
4. ブロック化とキャッシュ
5. AFTBlockAggregatorによるコスト関数構築
6. L-BFGS最適化（パラメータ: 係数 + 切片 + log(sigma)）
7. 標準化空間から元の空間への逆変換
8. AFTSurvivalRegressionModel生成
```

### フローチャート

```mermaid
flowchart TD
    A[開始: train] --> B[打ち切り列バリデーション]
    B --> C[特徴量統計量計算]
    C --> D[特徴量標準化]
    D --> E[ブロック化・キャッシュ]
    E --> F[AFTBlockAggregator + RDDLossFunction]
    F --> G[BreezeLBFGS最適化]
    G --> H{収束?}
    H -->|Yes| I[係数の逆変換]
    H -->|No + maxIter到達| I
    I --> J[AFTSurvivalRegressionModel生成]
    J --> K[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-57-01 | 打ち切りフラグ | censorCol値は0（打ち切り）または1（イベント発生）のみ | 訓練時 |
| BR-57-02 | 生存時間 | ラベル値は正値でなければならない | 訓練時 |
| BR-57-03 | パラメータ構造 | 最適化パラメータは[coefficients, intercept, log(sigma)]の順 | 訓練時 |
| BR-57-04 | 予測式 | prediction = exp(dot(coefficients, features) + intercept) | 予測時 |
| BR-57-05 | 分位数予測 | quantile(p) = prediction * (-log(1-p))^scale | 予測時 |

### 計算ロジック

- 予測生存時間: `exp(dot(coefficients, features) + intercept)`（Weibull分布のスケールパラメータ）
- 分位数: `prediction * (-log(1 - p)) ^ scale`（pは分位数確率）
- スケール: `exp(log(sigma))`（最適化結果の最後の要素の指数関数）

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | SparkException | 打ち切りフラグがNull/NaN | 有効な0/1値を設定 |
| - | SparkException | 打ち切りフラグが0/1以外 | 0または1に修正 |
| - | 最適化失敗 | L-BFGSが収束しない | maxIter/tol調整 |

### リトライ仕様

特になし。

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

Sparkの遅延評価に基づく。

## パフォーマンス要件

- Spark 3.1.0以降、ブロック化によるGEMV最適化
- デフォルトブロックサイズは1MB

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

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

## 備考

- Spark 1.6.0で導入
- Weibull分布を前提とするパラメトリックモデル
- Instance.weightフィールドを打ち切りフラグの格納に流用している（内部実装上の便宜）
- R survival::survregとは定数非ゼロ列の扱いが異なる場合がある

---

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | AFTSurvivalRegression.scala | `mllib/src/main/scala/org/apache/spark/ml/regression/AFTSurvivalRegression.scala` | AFTSurvivalRegressionParams（51-126行目）でcensorCol, quantileProbabilities等のパラメータ定義 |
| 1-2 | AFTSurvivalRegression.scala | 同上 | デフォルト値設定（95-98行目）: censorCol="censor", maxIter=100, tol=1E-6 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AFTSurvivalRegression.scala | 同上 | train()（202-284行目） |

**主要処理フロー**:
1. **215-221行目**: censorColの値バリデーション（0/1のみ）
2. **223-231行目**: 訓練インスタンスの構築（Instance.weightにcensorを格納）
3. **233-238行目**: 特徴量の統計量計算（mean, std, count）
4. **246-251行目**: ブロックサイズ設定
5. **260行目**: L-BFGSオプティマイザ生成
6. **268行目**: 初期解の構築（numFeatures + 2次元）
7. **270-272行目**: trainImpl呼出し
8. **278-283行目**: 係数・切片・スケールの抽出

#### Step 3: 最適化処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AFTSurvivalRegression.scala | 同上 | trainImpl()（287-345行目）で標準化・ブロック化・L-BFGS反復 |

**主要処理フロー**:
1. **295-296行目**: 逆標準偏差とスケール済み平均の計算
2. **300-303行目**: 特徴量の標準化（StandardScalerModel使用）
3. **305-308行目**: ブロック化とキャッシュ
4. **310-311行目**: AFTBlockAggregator + RDDLossFunction構築
5. **323-331行目**: L-BFGS反復と損失履歴の収集

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

```
AFTSurvivalRegression.train(dataset)
    |
    +-- censorCol バリデーション
    +-- 訓練インスタンス構築
    +-- Summarizer (mean, std, count)
    +-- trainImpl()
    |       +-- StandardScalerModel.getTransformFunc()
    |       +-- InstanceBlock.blokifyWithMaxMemUsage()
    |       +-- AFTBlockAggregator -> RDDLossFunction
    |       +-- BreezeLBFGS.iterations()
    |
    +-- new AFTSurvivalRegressionModel(uid, coefficients, intercept, scale)
```

### データフロー図

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

DataFrame          train()
  (label=T,        +-- 打ち切り検証                  AFTSurvivalRegressionModel
   censor,         +-- 特徴量標準化                     (coefficients,
   features)       +-- ブロック化                        intercept,
                   +-- L-BFGS最適化                      scale)
                   +-- 逆変換

DataFrame          transform()
  (features)       +-- exp(Xw + b)               DataFrame
                   +-- quantile計算                 (prediction,
                                                     quantiles)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AFTSurvivalRegression.scala | `mllib/src/main/scala/org/apache/spark/ml/regression/AFTSurvivalRegression.scala` | ソース | Estimator/Model/Params の実装 |
| AFTBlockAggregator.scala | `mllib/src/main/scala/org/apache/spark/ml/optim/aggregator/` | ソース | AFT損失のブロック集約 |
| RDDLossFunction.scala | `mllib/src/main/scala/org/apache/spark/ml/optim/loss/` | ソース | RDD上の損失関数 |
| StandardScalerModel.scala | `mllib/src/main/scala/org/apache/spark/ml/feature/StandardScaler.scala` | ソース | 特徴量標準化 |
| InstanceBlock.scala | `mllib/src/main/scala/org/apache/spark/ml/feature/Instance.scala` | ソース | ブロック化データ構造 |
