# 機能設計書 65-ALS推薦

## 概要

本ドキュメントは、Apache Spark MLlibにおけるALS（Alternating Least Squares）推薦機能の設計を記述する。交互最小二乗法に基づく協調フィルタリングによる推薦モデルの訓練・予測処理を対象とする。

### 本機能の処理概要

**業務上の目的・背景**：ALS推薦は、ユーザーとアイテムの相互作用データ（評価値や暗黙的フィードバック）から、ユーザーの嗜好を予測する協調フィルタリング手法である。ユーザー-アイテム行列を低ランク行列の積に分解することで、未観測のユーザー-アイテムペアの評価値を予測する。ECサイトの商品推薦、音楽・動画の推薦、広告ターゲティングなどの推薦システムの基盤技術として広く利用されている。

**機能の利用シーン**：ECサイトの商品推薦、音楽ストリーミングサービスの楽曲推薦、動画配信プラットフォームのコンテンツ推薦、ソーシャルメディアの友人推薦、広告ターゲティングなど。明示的評価（レーティング）と暗黙的フィードバック（閲覧履歴、購入履歴）の両方に対応する。

**主要な処理内容**：
1. ユーザー-アイテム-評価値の3つ組データを入力として受け取る
2. 交互最小二乗法（ALS）により行列分解を実行
3. ユーザー因子行列とアイテム因子行列を算出
4. 学習済みモデルによるレーティング予測
5. 上位N推薦アイテム/ユーザーの生成

**関連システム・外部連携**：Spark DataFrame APIおよびPipeline APIと統合。分散行列分解をBlockedRDDベースで実装し、大規模データに対応する。

**権限による制御**：特になし。Sparkアプリケーション実行権限に依存する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 該当なし | - | MLlib機能はWeb UIに専用画面を持たない |

## 機能種別

計算処理（機械学習アルゴリズム - 推薦システム）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| rank | Int | No | 因子行列のランク（デフォルト: 10） | > 0 |
| maxIter | Int | No | 最大反復回数（デフォルト: 10） | > 0 |
| regParam | Double | No | 正則化パラメータ（デフォルト: 0.1） | >= 0 |
| numUserBlocks | Int | No | ユーザーブロック数（デフォルト: 10） | > 0 |
| numItemBlocks | Int | No | アイテムブロック数（デフォルト: 10） | > 0 |
| implicitPrefs | Boolean | No | 暗黙的フィードバックモードか（デフォルト: false） | - |
| alpha | Double | No | 暗黙的フィードバックの信頼度パラメータ（デフォルト: 1.0） | >= 0 |
| userCol | String | No | ユーザーIDカラム名（デフォルト: "user"） | 整数型 |
| itemCol | String | No | アイテムIDカラム名（デフォルト: "item"） | 整数型 |
| ratingCol | String | No | 評価値カラム名（デフォルト: "rating"） | 数値型 |
| predictionCol | String | No | 予測カラム名（デフォルト: "prediction"） | - |
| nonnegative | Boolean | No | 非負制約（デフォルト: false） | - |
| checkpointInterval | Int | No | チェックポイント間隔（デフォルト: 10） | >= 1 |
| seed | Long | No | 乱数シード | - |
| intermediateStorageLevel | String | No | 中間RDDのストレージレベル（デフォルト: "MEMORY_AND_DISK"） | - |
| finalStorageLevel | String | No | 最終RDDのストレージレベル（デフォルト: "MEMORY_AND_DISK"） | - |
| coldStartStrategy | String | No | 未知ユーザー/アイテムの処理戦略（デフォルト: "nan"） | "nan" or "drop" |
| blockSize | Int | No | ブロックサイズ（デフォルト: 4096） | > 0 |

### 入力データソース

Spark DataFrame。(userCol, itemCol, ratingCol)カラムを持つ。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| prediction | Float | 予測評価値 |
| userFactors | DataFrame | ユーザー因子行列（id, features） |
| itemFactors | DataFrame | アイテム因子行列（id, features） |
| recommendForAllUsers | DataFrame | 全ユーザーへの上位N推薦アイテム |
| recommendForAllItems | DataFrame | 全アイテムへの上位Nユーザー |

### 出力先

入力DataFrameにpredictionカラムを追加したDataFrame。userFactors/itemFactorsはDataFrameとしてアクセス可能。

## 処理フロー

### 処理シーケンス

```
1. スキーマバリデーション
   └─ user/item/ratingカラムの型検証
2. データのブロック分割
   └─ ユーザーとアイテムをブロックに分割しBlockedRDD生成
3. ALS反復実行
   └─ ユーザー因子固定→アイテム因子更新→アイテム因子固定→ユーザー因子更新
4. ALSModelの生成
   └─ ユーザー因子・アイテム因子のDataFrameを生成
5. 予測処理
   └─ ユーザー因子とアイテム因子の内積で評価値を予測
```

### フローチャート

```mermaid
flowchart TD
    A[開始: fit呼び出し] --> B[スキーマ検証]
    B --> C[データのブロック分割]
    C --> D[初期化: アイテム因子ランダム生成]
    D --> E[ユーザー因子更新]
    E --> F[アイテム因子更新]
    F --> G{収束/最大反復?}
    G -->|No| E
    G -->|Yes| H[ALSModel生成]
    H --> I[userFactors/itemFactors DataFrame生成]
    I --> J[モデル返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-65-01 | 明示的/暗黙的 | implicitPrefs=trueで暗黙的フィードバックモード | 訓練時 |
| BR-65-02 | コールドスタート | coldStartStrategy="nan"で未知ペアにNaN、"drop"で除外 | 予測時 |
| BR-65-03 | 非負制約 | nonnegative=trueで因子値を非負に制約 | 訓練時 |
| BR-65-04 | ブロック分割 | numUserBlocks/numItemBlocksでデータをブロック分割して処理 | 訓練時 |

### 計算ロジック

ALS行列分解：R ≈ U * V^T
- Uはユーザー因子行列（m x rank）、Vはアイテム因子行列（n x rank）
- ユーザー因子固定時: V = argmin ||R - U*V^T||^2 + lambda*||V||^2
- アイテム因子固定時: U = argmin ||R - U*V^T||^2 + lambda*||U||^2
- 暗黙的フィードバック時: 信頼度 c_ui = 1 + alpha * r_ui を使用

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

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし（インメモリ処理） |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| IllegalArgumentException | パラメータ検証エラー | rank <= 0 | rankを正の値に設定 |
| IllegalArgumentException | 型エラー | user/itemカラムが整数型でない | IntegerType/LongTypeカラムを使用 |
| SparkException | データエラー | 評価値にNaN含有 | 入力データを前処理 |

### リトライ仕様

チェックポイント機能により中間因子行列を保存可能。

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

トランザクション管理なし。分散RDD処理によるインメモリ計算。

## パフォーマンス要件

numUserBlocks/numItemBlocksにより並列度を制御。intermediateStorageLevel/finalStorageLevelでメモリ管理を最適化可能。blockSizeパラメータでBLAS演算の効率を調整。

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

ユーザーの評価データ・行動データを扱うため、個人情報保護の観点からデータアクセス制御に注意が必要。

## 備考

- Spark 1.3.0でml API版が導入
- Hu et al., "Collaborative Filtering for Implicit Feedback Datasets" に基づく暗黙的フィードバック対応
- recommendForAllUsers()/recommendForAllItems()で上位N推薦を生成可能
- coldStartStrategyでコールドスタート問題に対応

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ALS.scala | `mllib/src/main/scala/org/apache/spark/ml/recommendation/ALS.scala` | ALSParamsトレイトでパラメータ定義を確認 |

**読解のコツ**: ALSは非常に多くのパラメータを持つ。明示的/暗黙的フィードバックの切り替え（implicitPrefs）とコールドスタート戦略（coldStartStrategy）が重要な分岐点。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ALS.scala | `mllib/src/main/scala/org/apache/spark/ml/recommendation/ALS.scala` | ALSクラスのfit()メソッド |

**主要処理フロー**:
1. パラメータ検証とデータ変換
2. ALS.train()の呼び出し（コンパニオンオブジェクト内）
3. 交互最小二乗法の反復実行
4. ALSModelの生成

#### Step 3: モデルの予測処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ALS.scala | `mllib/src/main/scala/org/apache/spark/ml/recommendation/ALS.scala` | ALSModelのtransform(), recommendForAllUsers(), recommendForAllItems() |

**主要処理フロー**:
- transform(): ユーザー因子とアイテム因子の内積で予測
- recommendForAllUsers(): 全ユーザーに対する上位N推薦アイテムを算出
- coldStartStrategy: 未知ユーザー/アイテムへの対応

#### Step 4: ALS訓練アルゴリズムを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ALS.scala | `mllib/src/main/scala/org/apache/spark/ml/recommendation/ALS.scala` | ALSコンパニオンオブジェクトのtrain()メソッド |

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

```
ALS.fit(dataset)
    |
    +-- transformSchema(schema)
    |
    +-- データ前処理（user/item ID変換）
    |
    +-- ALS.train()
    |       +-- ブロック分割（BlockedRDD生成）
    |       +-- 反復処理
    |       |       +-- ユーザー因子更新（最小二乗法）
    |       |       +-- アイテム因子更新（最小二乗法）
    |       +-- 因子行列の収集
    |
    +-- ALSModel(uid, rank, userFactors, itemFactors)
```

### データフロー図

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

DataFrame           ALS.fit()                      ALSModel
(user, item,    --> ALS交互最小二乗法          --> (userFactors,
 rating)            行列分解実行                     itemFactors,
                                                     rank)

DataFrame           ALSModel.transform()           DataFrame
(user, item)   --> 因子内積計算               --> (user, item,
                    coldStartStrategy適用            prediction)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ALS.scala | `mllib/src/main/scala/org/apache/spark/ml/recommendation/ALS.scala` | ソース | ml API層のEstimator/Model/アルゴリズム実装 |
| ALSModel.scala | `mllib/src/main/scala/org/apache/spark/ml/recommendation/ALS.scala` | ソース | ALSモデル（同一ファイル内） |
