# 機能設計書 63-LDA（トピックモデル）

## 概要

本ドキュメントは、Apache Spark MLlibにおけるLDA（Latent Dirichlet Allocation）機能の設計を記述する。文書集合からトピック（潜在的な話題）を自動抽出するトピックモデリング手法の訓練・推論処理を対象とする。

### 本機能の処理概要

**業務上の目的・背景**：大量のテキストデータから潜在的なトピック構造を発見するために使用される。LDAは生成確率モデルであり、各文書がトピックの混合として表現され、各トピックが単語の確率分布として表現される。テキストマイニング、文書分類、推薦システムの基盤技術として広く利用されている。

**機能の利用シーン**：ニュース記事のトピック分類、顧客レビューのテーマ分析、学術論文のトピック抽出、文書の自動タグ付け、コンテンツ推薦システムなど。非構造化テキストデータから構造的な洞察を得るために利用される。

**主要な処理内容**：
1. 文書-単語頻度行列（Bag of Words）を入力として受け取る
2. オンラインLDAまたはEM（期待値最大化）アルゴリズムでモデルを訓練
3. 各トピックの単語分布と各文書のトピック分布を推定
4. 学習済みモデルによる新規文書のトピック推論

**関連システム・外部連携**：Spark DataFrame APIおよびPipeline APIと統合。mllib.clustering.LDAに処理を委譲する。OnlineLDAOptimizerとEMLDAOptimizerの2つの最適化手法を提供する。

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

## 関連画面

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

## 機能種別

計算処理（機械学習アルゴリズム - トピックモデリング）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| k | Int | No | トピック数（デフォルト: 10） | >= 1 |
| maxIter | Int | No | 最大反復回数（デフォルト: 20） | > 0 |
| featuresCol | String | No | 特徴量カラム名（デフォルト: "features"） | Vector型カラム |
| seed | Long | No | 乱数シード | - |
| checkpointInterval | Int | No | チェックポイント間隔（デフォルト: 10） | >= 1 |
| optimizer | String | No | 最適化手法（"online" or "em"、デフォルト: "online"） | "online" or "em" |
| docConcentration | Array[Double] | No | 文書-トピック分布のDirichlet事前分布パラメータ | - |
| topicConcentration | Double | No | トピック-単語分布のDirichlet事前分布パラメータ | - |
| learningOffset | Double | No | オンラインLDAの学習率オフセット（デフォルト: 1024） | > 0 |
| learningDecay | Double | No | オンラインLDAの学習率減衰（デフォルト: 0.51） | (0.5, 1.0] |
| subsamplingRate | Double | No | オンラインLDAのサブサンプリング率（デフォルト: 0.05） | (0, 1] |
| keepLastCheckpoint | Boolean | No | 最終チェックポイントを保持するか（デフォルト: true） | - |
| topicDistributionCol | String | No | トピック分布出力カラム名（デフォルト: "topicDistribution"） | - |

### 入力データソース

Spark DataFrame。featuresColカラムにVector型の単語頻度ベクトル（Bag of Words）を含む。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| topicDistribution | Vector | 各文書のトピック分布ベクトル |
| topicsMatrix | Matrix | トピック-単語分布行列 |
| logLikelihood | Double | 訓練データの対数尤度 |
| logPerplexity | Double | 訓練データの対数パープレキシティ |

### 出力先

入力DataFrameにtopicDistributionカラムを追加したDataFrame。モデルは永続化可能。

## 処理フロー

### 処理シーケンス

```
1. スキーマバリデーション
   └─ featuresColがVector互換カラムか検証
2. データのRDD変換
   └─ VectorをOldVectorに変換し、インデックス付きRDDを生成
3. オプティマイザの選択
   └─ "online"またはemに基づきオプティマイザを設定
4. mllib LDAの設定と実行
   └─ k, maxIter, docConcentration, topicConcentration等を設定して実行
5. LDAModelの生成
   └─ LocalLDAModelまたはDistributedLDAModelを生成
6. ml LDAModelへのラッピング
   └─ mllib LDAModelをml API互換のモデルに変換
```

### フローチャート

```mermaid
flowchart TD
    A[開始: fit呼び出し] --> B[スキーマ検証]
    B --> C[RDD変換]
    C --> D{optimizer}
    D -->|online| E[OnlineLDAOptimizer設定]
    D -->|em| F[EMLDAOptimizer設定]
    E --> G[mllib LDA実行]
    F --> G
    G --> H{モデル種別}
    H -->|Online| I[LocalLDAModel生成]
    H -->|EM| J[DistributedLDAModel生成]
    I --> K[ml LDAModel返却]
    J --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-63-01 | トピック数制約 | kは1以上でなければならない | 常時 |
| BR-63-02 | オプティマイザ選択 | "online"はOnlineLDAOptimizer、"em"はEMLDAOptimizerを使用 | 訓練時 |
| BR-63-03 | モデル種別 | OnlineLDAはLocalLDAModel、EMLDAはDistributedLDAModelを生成 | 訓練後 |
| BR-63-04 | Dirichlet事前分布 | docConcentration未指定時はオプティマイザのデフォルト値を使用 | 訓練時 |

### 計算ロジック

LDA: 各文書dのトピック分布theta_dとトピックtの単語分布beta_tを推定。
- Online LDA: ミニバッチ確率変分推論による逐次的パラメータ更新
- EM LDA: 変分EMアルゴリズムによるバッチ処理

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| IllegalArgumentException | パラメータ検証エラー | optimizer値が不正 | "online"または"em"を指定 |
| IllegalArgumentException | パラメータ検証エラー | k < 1 | kを1以上に設定 |
| SparkException | 数値エラー | 空の特徴量ベクトル | 入力データを前処理 |

### リトライ仕様

チェックポイント機能により中間状態を保存可能。障害時はチェックポイントから復旧。

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

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

## パフォーマンス要件

Online LDAはミニバッチ処理のためメモリ効率が良い。EM LDAはGraphXを使用するため大規模データで高い計算コスト。

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

特段のセキュリティ制御なし。

## 備考

- Spark 1.6.0でml API版が導入
- Online LDAは大規模データに適し、EM LDAはより正確な推定が可能
- topicsMatrix()で各トピックの単語分布を取得可能
- describeTopics()で上位単語を取得可能

---

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

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

### 推奨読解順序

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

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

**読解のコツ**: LDAは他のクラスタリングアルゴリズムと比較してパラメータが多い。特にoptimizerパラメータにより処理フローが大きく変わる点に注意。

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

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

**主要処理フロー**:
1. パラメータ検証とデータ変換
2. optimizer設定によるLDA最適化手法の選択
3. mllib.clustering.LDAの実行
4. LDAModelの生成とラッピング

#### Step 3: モデルの推論処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | LDA.scala | `mllib/src/main/scala/org/apache/spark/ml/clustering/LDA.scala` | LDAModelのtransform(), topicsMatrix(), describeTopics() |

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

```
LDA.fit(dataset)
    |
    +-- transformSchema(schema)
    |
    +-- dataset → RDD[Vector]変換
    |
    +-- optimizer選択
    |       +-- "online" → OnlineLDAOptimizer
    |       +-- "em" → EMLDAOptimizer
    |
    +-- mllib.clustering.LDA.run()
    |       +-- OnlineLDA: ミニバッチ変分推論
    |       +-- EM LDA: GraphXベース変分EM
    |
    +-- LDAModel(LocalLDAModel or DistributedLDAModel)
```

### データフロー図

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

DataFrame           LDA.fit()                      LDAModel
(features:      --> mllib LDA実行              --> (topicsMatrix,
 Bag-of-Words)      Online/EM最適化                  describeTopics,
                                                     logLikelihood)

DataFrame           LDAModel.transform()           DataFrame
(features)     --> トピック分布推論            --> (features +
                                                    topicDistribution)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| LDA.scala | `mllib/src/main/scala/org/apache/spark/ml/clustering/LDA.scala` | ソース | ml API層のEstimator/Model定義 |
| LDA.scala | `mllib/src/main/scala/org/apache/spark/mllib/clustering/LDA.scala` | ソース | MLlib層のLDAアルゴリズム |
| LDAModel.scala | `mllib/src/main/scala/org/apache/spark/mllib/clustering/LDAModel.scala` | ソース | MLlib層のLDAモデル |
| OnlineLDAOptimizer.scala | `mllib/src/main/scala/org/apache/spark/mllib/clustering/LDAOptimizer.scala` | ソース | Online LDA最適化実装 |
| EMLDAOptimizer.scala | `mllib/src/main/scala/org/apache/spark/mllib/clustering/LDAOptimizer.scala` | ソース | EM LDA最適化実装 |
