# 機能設計書 47-線形SVM

## 概要

本ドキュメントは、Apache Spark MLlibにおける線形SVM（Linear Support Vector Machine）機能の設計を記述する。線形サポートベクターマシンによる二値分類モデルの訓練と予測を提供する。

### 本機能の処理概要

線形SVMは、ヒンジ損失関数を最適化することでクラス間のマージンを最大化する線形二値分類器である。

**業務上の目的・背景**：SVMは統計的学習理論に基づく理論的に確立された分類手法であり、高次元データにおいても優れた汎化性能を発揮する。テキスト分類、画像認識のベースラインモデルとして広く使用される。

**機能の利用シーン**：二値分類問題において、特に高次元疎ベクトルデータ（テキスト分類等）での使用に適している。L2正則化をサポートし、過学習を防止する。

**主要な処理内容**：
1. 入力データの前処理（標準化、ブロック化）
2. OWLQN最適化アルゴリズムによるヒンジ損失の最小化
3. rawPredictionに対する閾値適用による二値分類
4. L2正則化のサポート

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

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

## 関連画面

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

## 機能種別

計算処理 / 機械学習分類

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| featuresCol | String | Yes | 特徴量カラム名 | Vector型カラム |
| labelCol | String | Yes | ラベルカラム名 | 0または1 |
| weightCol | String | No | 重みカラム名 | 非負の数値 |
| regParam | Double | No | L2正則化パラメータ、デフォルト0.0 | 0以上 |
| maxIter | Int | No | 最大反復回数、デフォルト100 | 正の整数 |
| fitIntercept | Boolean | No | 切片項のフィット有無、デフォルトtrue | - |
| tol | Double | No | 収束許容誤差、デフォルト1E-6 | 正の値 |
| standardization | Boolean | No | 特徴量の標準化有無、デフォルトtrue | - |
| threshold | Double | No | rawPredictionの閾値、デフォルト0.0 | 任意の実数 |
| aggregationDepth | Int | No | treeAggregate深度、デフォルト2 | 2以上 |
| maxBlockSizeInMB | Double | No | ブロックサイズ、デフォルト0.0 | 0以上 |

### 入力データソース

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

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| LinearSVCModel | LinearSVCModel | 学習済みモデル（係数ベクトル・切片） |
| prediction | Double | 予測クラスラベル（0.0または1.0） |
| rawPrediction | Vector | raw予測値（w^T x + b） |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. train()メソッド
   └─ データ検証（ラベル・重み・特徴量チェック）
   └─ 特徴量統計量計算（Summarizer）
   └─ 特徴量の標準化
   └─ OWLQN最適化によるヒンジ損失最小化
   └─ 係数の逆標準化
   └─ LinearSVCModel構築

2. predict(features)
   └─ rawPrediction = w^T x + b
   └─ rawPrediction > threshold → 1.0、それ以外 → 0.0
```

### フローチャート

```mermaid
flowchart TD
    A[train開始] --> B[データ検証]
    B --> C[特徴量統計量計算]
    C --> D{standardization?}
    D -->|Yes| E[特徴量標準化]
    D -->|No| F[そのまま]
    E --> G[OWLQN最適化]
    F --> G
    G --> H[ヒンジ損失最小化]
    H --> I[係数逆標準化]
    I --> J[LinearSVCModel生成]
    J --> K[predict: rawPrediction計算]
    K --> L{rawPrediction > threshold?}
    L -->|Yes| M[prediction = 1.0]
    L -->|No| N[prediction = 0.0]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-47-01 | ヒンジ損失 | max(0, 1 - y * (w^T x + b)) を最小化 | 訓練時 |
| BR-47-02 | 閾値適用 | rawPredictionに対して閾値を適用（確率ではない） | 予測時 |
| BR-47-03 | L2正則化のみ | 現在はL2正則化のみサポート | 正則化使用時 |
| BR-47-04 | 閾値の意味 | Infで全て0.0予測、-Infで全て1.0予測 | 閾値設定時 |

### 計算ロジック

- rawPrediction: `w^T x + b`
- ヒンジ損失: `max(0, 1 - y * rawPrediction)`
- 分類: `rawPrediction > threshold → 1.0`

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| SparkException | 計算エラー | 最適化が収束しない | maxIterを増やすかtolを緩める |

### リトライ仕様

特になし。

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

該当なし。

## パフォーマンス要件

- Spark 3.1.0以降、ブロックスタッキングとGEMVによる性能最適化をサポート

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

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

## 備考

- LinearSVCは確率出力を提供しない（Classifierを継承、ProbabilisticClassifierではない）
- 閾値はrawPredictionに適用され、確率に適用されるものではない

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | LinearSVC.scala | `mllib/src/main/scala/org/apache/spark/ml/classification/LinearSVC.scala` | LinearSVCParamsのパラメータ定義（48-66行目）、特にthresholdがrawPredictionに適用される点を理解する |

**読解のコツ**: LinearSVCのthresholdは通常の分類器とは異なり、確率ではなくrawPrediction値に対して適用される。デフォルト値0.0は、rawPrediction > 0でクラス1と予測する標準的なSVMの動作に対応する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | LinearSVC.scala | `mllib/src/main/scala/org/apache/spark/ml/classification/LinearSVC.scala` | LinearSVCクラス（81-150行目）のパラメータ設定メソッドを理解する |

**主要処理フロー**:
1. **48-66行目**: LinearSVCParams - threshold定義（rawPredictionに適用）
2. **64-65行目**: デフォルト値設定（regParam=0.0, maxIter=100等）
3. **81-84行目**: Classifierを継承（ProbabilisticClassifierではない）
4. **96行目**: `setRegParam`
5. **113-114行目**: `setFitIntercept`

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

```
LinearSVC.train(dataset)
    |
    +-- データ検証・前処理
    |       +-- checkClassificationLabels()
    |       +-- Summarizer（特徴量統計量）
    |
    +-- OWLQN最適化
    |       +-- HingeAggregator（ヒンジ損失集約）
    |       +-- L2Regularization（正則化項）
    |
    +-- LinearSVCModel生成
            +-- 係数ベクトル・切片

LinearSVCModel.predict(features)
    |
    +-- rawPrediction = coefficients.dot(features) + intercept
    +-- rawPrediction > threshold ? 1.0 : 0.0
```

### データフロー図

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

Dataset ──────> 特徴量統計量計算
(label=0/1,      |
 features,       v
 weight)    標準化(オプション)
                 |
                 v
            OWLQN最適化 ──────────> LinearSVCModel
            (ヒンジ損失 + L2)          (coefficients, intercept)
                                        |
                                        v
                                   rawPrediction = w^T x + b
                                        |
                                        v
                                   prediction (threshold判定)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| LinearSVC.scala | `mllib/src/main/scala/org/apache/spark/ml/classification/LinearSVC.scala` | ソース | 線形SVCの全実装 |
| Classifier.scala | `mllib/src/main/scala/org/apache/spark/ml/classification/Classifier.scala` | ソース | 分類器基底クラス |
| HingeAggregator.scala | `mllib/src/main/scala/org/apache/spark/ml/optim/aggregator/HingeAggregator.scala` | ソース | ヒンジ損失の集約計算 |
| RDDLossFunction.scala | `mllib/src/main/scala/org/apache/spark/ml/optim/loss/RDDLossFunction.scala` | ソース | 分散損失関数 |
