# 機能設計書 50-因子分解マシン分類

## 概要

本ドキュメントは、Apache Spark MLlibにおける因子分解マシン分類（Factorization Machine Classification）機能の設計を記述する。因子分解マシン（FM）による分類モデルの訓練と予測を提供する。

### 本機能の処理概要

因子分解マシン分類は、特徴量間のペアワイズ相互作用を潜在因子（ファクター）を介して効率的にモデル化する分類アルゴリズムであり、特に疎なデータに対して優れた性能を発揮する。

**業務上の目的・背景**：従来の線形モデルでは特徴量間の相互作用を捉えることが困難であり、明示的な特徴量交差を設計する必要があった。因子分解マシンは潜在因子ベクトルを用いて特徴量間の全ペアワイズ相互作用を効率的に学習でき、特にレコメンデーションシステムや広告予測等の疎データ環境で広く使用される。

**機能の利用シーン**：広告クリック予測、レコメンデーション、テキスト分類等の高次元疎データにおける二値分類タスクで使用される。

**主要な処理内容**：
1. 線形項（w_0 + w^T x）と相互作用項（sum of pairwise interactions）の学習
2. 勾配降下法またはAdamWソルバーによるパラメータ最適化
3. ロジスティック損失関数に基づく二値分類
4. L2正則化のサポート

**関連システム・外部連携**：Pipeline API。回帰版のFMRegressorとFactorizationMachinesトレイトを共有する。

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

## 関連画面

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

## 機能種別

計算処理 / 機械学習分類

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| featuresCol | String | Yes | 特徴量カラム名 | Vector型カラム |
| labelCol | String | Yes | ラベルカラム名 | 0または1 |
| factorSize | Int | No | 因子ベクトルの次元数、デフォルト8 | 正の整数 |
| fitIntercept | Boolean | No | 切片項（w_0）のフィット有無、デフォルトtrue | - |
| fitLinear | Boolean | No | 線形項（w^T x）のフィット有無、デフォルトtrue | - |
| regParam | Double | No | L2正則化パラメータ、デフォルト0.0 | 0以上 |
| miniBatchFraction | Double | No | ミニバッチフラクション、デフォルト1.0 | (0, 1] |
| initStd | Double | No | 係数初期化の標準偏差、デフォルト0.01 | 正の値 |
| maxIter | Int | No | 最大反復回数、デフォルト100 | 正の整数 |
| stepSize | Double | No | 学習率、デフォルト1.0 | 正の値 |
| tol | Double | No | 収束許容誤差、デフォルト1E-6 | 正の値 |
| solver | String | No | ソルバー、"gd"/"adamW"、デフォルト"adamW" | サポートされた値 |

### 入力データソース

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

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| FMClassificationModel | FMClassificationModel | 学習済みモデル（intercept、linear、factors） |
| prediction | Double | 予測クラスラベル |
| rawPrediction | Vector | raw予測値 |
| probability | Vector | 予測確率（ロジスティック関数変換） |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. train()メソッド
   └─ データ検証（ラベル・特徴量チェック）
   └─ 係数の初期化（initStdによるランダム初期化）
   └─ GD/AdamWソルバーによる最適化
       └─ 損失関数: ロジスティック損失 + L2正則化
       └─ FM予測値: w_0 + w^T x + sum_{i<j} <v_i, v_j> x_i x_j
   └─ FMClassificationModel構築

2. predict(features)
   └─ FM予測値計算
   └─ ロジスティック関数で確率に変換
   └─ threshold適用による分類
```

### フローチャート

```mermaid
flowchart TD
    A[train開始] --> B[データ検証]
    B --> C[係数初期化]
    C --> D{solver}
    D -->|adamW| E[AdamW最適化]
    D -->|gd| F[ミニバッチGD最適化]
    E --> G[ロジスティック損失最小化]
    F --> G
    G --> H[FMClassificationModel生成]
    H --> I[predict: FM値計算]
    I --> J[ロジスティック関数で確率変換]
    J --> K[threshold判定 → prediction]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-50-01 | 二値分類のみ | 多クラス分類はサポートされない | 常時 |
| BR-50-02 | 因子分解の効率化 | 相互作用項はO(kn)で計算（k: factorSize、n: 特徴量数） | 予測時 |
| BR-50-03 | 線形項制御 | fitLinear=falseで線形項を除外可能 | fitLinear設定時 |

### 計算ロジック

FM予測値:
```
y = w_0 + sum_i(w_i * x_i) + sum_i(sum_j>i(<v_i, v_j> * x_i * x_j))
```
ここで、相互作用項は以下の等価変換で効率的に計算:
```
sum_i(sum_j>i(<v_i, v_j> * x_i * x_j)) = 0.5 * sum_f(( sum_i(v_{i,f} * x_i) )^2 - sum_i(v_{i,f}^2 * x_i^2))
```
分類確率: `P(y=1) = sigmoid(y)`

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

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

## エラー処理

### エラーケース一覧

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

### リトライ仕様

特になし。

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

該当なし。

## パフォーマンス要件

- 相互作用項の計算がO(kn)で効率的（k: factorSize、n: 特徴量数）
- miniBatchFractionで各イテレーションのデータ量を制御

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

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

## 備考

- Spark 3.0.0で追加された機能
- S. Rendle "Factorization Machines" (2010) に基づく実装
- 回帰版のFMRegressorとFactorizationMachinesトレイトを共有

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | FMClassifier.scala | `mllib/src/main/scala/org/apache/spark/ml/classification/FMClassifier.scala` | FMClassifierParamsとFactorizationMachinesParamsのパラメータ定義を理解する |

**読解のコツ**: FMClassifierは`FactorizationMachines`トレイト（`ml.regression`パッケージ）を共有しており、パラメータ定義と訓練ロジックの大部分はそこに集約されている。FMClassifierParams（40-42行目）はProbabilisticClassifierParamsとFactorizationMachinesParamsを組み合わせている。

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

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

**主要処理フロー**:
1. **40-42行目**: FMClassifierParamsの定義
2. **49-51行目**: FM式のScaladoc説明
3. **75-78行目**: FMClassifierクラス定義（ProbabilisticClassifier + FactorizationMachines継承）
4. **81行目**: デフォルトUID "fmc"
5. **90行目**: `setFactorSize` - 因子ベクトル次元数設定
6. **99行目**: `setFitIntercept` - 切片項設定
7. **108行目**: `setFitLinear` - 線形項設定
8. **117行目**: `setRegParam` - L2正則化パラメータ
9. **126行目**: `setMiniBatchFraction` - ミニバッチフラクション
10. **135行目**: `setInitStd` - 初期化標準偏差

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

```
FMClassifier.train(dataset)
    |
    +-- FactorizationMachines.trainImpl(dataset)
    |       |
    |       +-- 係数初期化（intercept, linear, factors）
    |       +-- GD / AdamW ソルバー
    |       +-- FMの勾配計算
    |       +-- ロジスティック損失 + L2正則化
    |
    +-- FMClassificationModel(intercept, linear, factors)

FMClassificationModel.predict(features)
    |
    +-- FM予測値計算
    |       +-- w_0 (intercept)
    |       +-- w^T x (linear term)
    |       +-- 相互作用項 (factor interactions)
    |
    +-- sigmoid(prediction) → probability
    +-- threshold判定 → prediction
```

### データフロー図

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

Dataset ──────> 係数初期化
(label=0/1,      (initStdでランダム)
 features)       |
                 v
            GD/AdamW最適化
            (ロジスティック損失 + L2)
                 |
                 v
            FMClassificationModel ──> intercept (w_0)
                                       linear (w)
                                       factors (V: n x k)
                 |
                 v
            FM予測値 = w_0 + w^Tx + interactions
                 |
                 v
            sigmoid → probability
                 |
                 v
            (prediction, rawPrediction, probability)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| FMClassifier.scala | `mllib/src/main/scala/org/apache/spark/ml/classification/FMClassifier.scala` | ソース | FM分類の実装 |
| FactorizationMachines.scala | `mllib/src/main/scala/org/apache/spark/ml/regression/FactorizationMachines.scala` | ソース | FM共通パラメータ・訓練ロジック |
| FMRegressor.scala | `mllib/src/main/scala/org/apache/spark/ml/regression/FMRegressor.scala` | ソース | FM回帰版（共通トレイトを共有） |
| ProbabilisticClassifier.scala | `mllib/src/main/scala/org/apache/spark/ml/classification/ProbabilisticClassifier.scala` | ソース | 確率的分類器基底クラス |
