# 機能設計書 52-線形回帰

## 概要

本ドキュメントは、Apache Spark MLlibが提供する線形回帰（LinearRegression）機能の設計を記述する。本機能は、L1/L2正則化（Lasso, Ridge, Elastic Net）に対応した線形回帰モデルの訓練と予測を提供する。

### 本機能の処理概要

線形回帰は、目的変数と説明変数の間の線形関係をモデル化する回帰分析手法である。正則化パラメータにより過学習を防止し、損失関数として二乗誤差（squaredError）とHuber損失を選択可能である。

**業務上の目的・背景**：連続値の予測は多くのビジネスシーンで必要とされる。住宅価格予測、売上予測、需要予測など、入力特徴量から連続値を推定する際に利用される。線形回帰は解釈性が高く、特徴量の寄与度を係数として直接把握できる。

**機能の利用シーン**：数値予測タスク全般。特にモデルの解釈性が求められる場面、統計的推論（p値、t値、信頼区間等）が必要な場面で利用される。

**主要な処理内容**：
1. 入力データの標準化とブロック化によるGEMV最適化
2. ソルバー選択（auto/normal/l-bfgs）に基づく最適化実行
3. L1/L2/ElasticNet正則化による過学習防止
4. 訓練サマリー（R^2、RMSE、t値、p値等）の自動計算

**関連システム・外部連携**：WeightedLeastSquaresソルバー、Breezeライブラリ（LBFGS/OWLQN/LBFGSB）、PMML形式でのモデルエクスポートに対応。

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

## 関連画面

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

## 機能種別

計算処理（機械学習 - 回帰分析）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| regParam | Double | No | 正則化パラメータ（デフォルト: 0.0） | >= 0 |
| elasticNetParam | Double | No | ElasticNetミキシングパラメータ（デフォルト: 0.0） | [0, 1] |
| maxIter | Int | No | 最大反復回数（デフォルト: 100） | >= 0 |
| tol | Double | No | 収束判定閾値（デフォルト: 1E-6） | >= 0 |
| fitIntercept | Boolean | No | 切片を推定するか（デフォルト: true） | - |
| standardization | Boolean | No | 特徴量を標準化するか（デフォルト: true） | - |
| solver | String | No | 最適化ソルバー（デフォルト: "auto"） | "auto", "normal", "l-bfgs" |
| loss | String | No | 損失関数（デフォルト: "squaredError"） | "squaredError", "huber" |
| epsilon | Double | No | Huber損失のロバストネスパラメータ（デフォルト: 1.35） | > 1.0 |
| weightCol | String | No | 重み列名 | - |
| aggregationDepth | Int | No | treeAggregate深度（デフォルト: 2） | >= 2 |
| maxBlockSizeInMB | Double | No | ブロックサイズ（デフォルト: 0.0=自動1MB） | >= 0 |

### 入力データソース

DataFrame形式。ラベル列はDouble型、特徴量列はVector型。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| prediction | Double | 予測値（coefficients・features + intercept） |
| coefficients | Vector | 回帰係数ベクトル |
| intercept | Double | 切片 |
| scale | Double | Huber損失のスケールパラメータ（squaredErrorの場合は1.0） |

### 出力先

入力DataFrameに予測列を追加。モデルはinternal形式またはPMML形式で永続化可能。

## 処理フロー

### 処理シーケンス

```
1. 入力検証
   └─ スキーマ検証、Huber損失時の制約チェック（normalソルバー不可、elasticNetParam==0必須）
2. 特徴量数の取得
3. ソルバー選択
   └─ auto: 特徴量数がMAX_FEATURES_FOR_NORMAL_SOLVER以下ならnormal、超過ならl-bfgs
   └─ normal: WeightedLeastSquares使用（1パス）
   └─ l-bfgs: LBFGS/OWLQN/LBFGSB使用（反復法）
4. データ標準化・ブロック化
   └─ 特徴量の逆標準偏差でスケーリング
   └─ InstanceBlockにブロック化してキャッシュ
5. 最適化実行
   └─ コスト関数（LeastSquaresBlockAggregator / HuberBlockAggregator）構築
   └─ オプティマイザで反復最適化
6. 係数の逆変換
   └─ スケーリングされた空間の解を元の空間に変換
7. サマリー生成
   └─ R^2、RMSE、MAE等の評価指標計算
```

### フローチャート

```mermaid
flowchart TD
    A[開始: train] --> B{損失関数とソルバー確認}
    B -->|squaredError + normal/auto| C[WeightedLeastSquares]
    B -->|l-bfgs/huber| D[データ標準化]
    C --> J[モデル生成]
    D --> E{標準偏差==0?}
    E -->|Yes + fitIntercept| F[定数ラベル処理]
    E -->|No| G[ブロック化・キャッシュ]
    F --> J
    G --> H[LBFGS/OWLQN最適化]
    H --> I[係数の逆変換]
    I --> J
    J --> K[サマリー生成]
    K --> L[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-52-01 | Huber損失制約 | Huber損失はnormalソルバーをサポートしない | loss=="huber"時 |
| BR-52-02 | Huber正則化制約 | Huber損失はL2正則化のみサポート（elasticNetParam==0） | loss=="huber"時 |
| BR-52-03 | normalソルバー特徴量制限 | normalソルバーはMAX_FEATURES_FOR_NORMAL_SOLVER以下のみ | solver=="normal"時 |
| BR-52-04 | 自動ソルバー選択 | auto時、特徴量数が閾値以下ならnormal、超過ならl-bfgs | solver=="auto"時 |

### 計算ロジック

- 二乗誤差目的関数: `1/(2n) * sum((Xw - y)^2) + lambda * [(1-alpha)/2 * ||w||_2^2 + alpha * ||w||_1]`
- Huber目的関数: `1/(2n) * sum(sigma + H_m((Xw-y)/sigma)*sigma) + 1/2 * lambda * ||w||_2^2`
- 予測: `dot(features, coefficients) + intercept`

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | IllegalArgumentException | Huber損失+normalソルバー | ソルバーをautoまたはl-bfgsに変更 |
| - | IllegalArgumentException | Huber損失+elasticNetParam!=0 | elasticNetParamを0に設定 |
| - | SparkException | 最適化が収束しない | maxIterを増やす、tolを緩める |

### リトライ仕様

特になし。最適化の収束はmaxIterとtolで制御。

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

Sparkの遅延評価に基づく。

## パフォーマンス要件

- normalソルバーは1パスで完了（低次元データに効率的）
- l-bfgsはブロック化によりGEMV最適化（Spark 3.1.0以降）
- ブロックサイズはデフォルト1MB

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

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

## 備考

- Spark 1.3.0で導入
- PMML形式でのエクスポートに対応
- normalソルバー使用時のみ、t値・p値・標準誤差が利用可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | LinearRegression.scala | `mllib/src/main/scala/org/apache/spark/ml/regression/LinearRegression.scala` | LinearRegressionParams（58-128行目）でパラメータ定義と制約を確認 |
| 1-2 | LinearRegression.scala | 同上 | LinearModelData（834-851行目）で永続化データ構造を確認 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | LinearRegression.scala | 同上 | train()（329-438行目）が訓練のエントリーポイント |

**主要処理フロー**:
1. **343行目**: 特徴量数取得
2. **353-356行目**: normalソルバー判定と分岐
3. **358-359行目**: サマライザーでラベル・特徴量の統計量を取得
4. **416-417行目**: オプティマイザ生成
5. **427-429行目**: trainImplで最適化実行
6. **435-437行目**: モデル生成とサマリー作成

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | LinearRegression.scala | 同上 | trainImpl()（529-610行目）でブロック化・標準化・最適化の詳細 |
| 3-2 | LinearRegression.scala | 同上 | createOptimizer()（494-527行目）でオプティマイザの選択ロジック |

#### Step 4: 訓練サマリーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | LinearRegression.scala | 同上 | LinearRegressionSummary（996-1162行目）でR^2, RMSE, t値, p値等の計算 |

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

```
LinearRegression.train(dataset)
    |
    +-- getNumFeatures(dataset)
    |
    +-- [分岐: ソルバー選択]
    |   +-- trainWithNormal()
    |   |       +-- WeightedLeastSquares.fit()
    |   |
    |   +-- trainImpl()
    |           +-- StandardScalerModel.getTransformFunc()
    |           +-- InstanceBlock.blokifyWithMaxMemUsage()
    |           +-- RDDLossFunction (LeastSquaresBlockAggregator/HuberBlockAggregator)
    |           +-- BreezeLBFGS/BreezeOWLQN/BreezeLBFGSB.iterations()
    |
    +-- createModel(parameters)
    +-- model.createSummary()
```

### データフロー図

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

DataFrame          train()
  (label,          +-- 統計量計算 (mean, std)     LinearRegressionModel
   features,       +-- 標準化                       (coefficients,
   weight)         +-- ブロック化                     intercept,
                   +-- 最適化(LBFGS/WLS)              scale)
                   +-- 逆変換
                                                  LinearRegressionSummary
                                                    (R^2, RMSE, MAE,
                                                     tValues, pValues)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| LinearRegression.scala | `mllib/src/main/scala/org/apache/spark/ml/regression/LinearRegression.scala` | ソース | Estimator/Model/Summary全体の実装 |
| WeightedLeastSquares.scala | `mllib/src/main/scala/org/apache/spark/ml/optim/WeightedLeastSquares.scala` | ソース | normalソルバーの実装 |
| LeastSquaresBlockAggregator.scala | `mllib/src/main/scala/org/apache/spark/ml/optim/aggregator/` | ソース | 二乗誤差のブロック集約 |
| HuberBlockAggregator.scala | `mllib/src/main/scala/org/apache/spark/ml/optim/aggregator/` | ソース | Huber損失のブロック集約 |
| RDDLossFunction.scala | `mllib/src/main/scala/org/apache/spark/ml/optim/loss/` | ソース | RDD上の損失関数 |
