# 機能設計書 66-特徴量変換

## 概要

本ドキュメントは、Apache Spark MLlibにおける特徴量変換機能の設計を記述する。ml.featureパッケージに含まれる40以上の変換器（Transformer/Estimator）により、機械学習パイプラインにおけるデータ前処理を実現する機能を対象とする。

### 本機能の処理概要

**業務上の目的・背景**：機械学習モデルの訓練前には、生データを適切な特徴量に変換する前処理が不可欠である。文字列のインデックス化、ベクトルの正規化・標準化、特徴量の選択・結合、テキストのトークン化など、多種多様な前処理操作を標準化されたAPIで提供する。Pipeline APIと組み合わせることで、再現可能なデータ前処理ワークフローを構築できる。

**機能の利用シーン**：機械学習パイプラインの構築時に、生データからモデルが扱える特徴量形式への変換処理として利用される。具体的には、カテゴリ変数のエンコーディング、数値特徴量のスケーリング、テキストの前処理、複数特徴量の結合、次元削減などの場面で使用される。

**主要な処理内容**：
1. **カテゴリ変換**: StringIndexer（文字列→インデックス）、IndexToString（逆変換）、OneHotEncoder（ワンホット化）
2. **数値変換**: StandardScaler（標準化）、MinMaxScaler（最小最大正規化）、Normalizer（L1/L2正規化）、MaxAbsScaler
3. **特徴量結合・選択**: VectorAssembler（複数カラム結合）、VectorSlicer（部分選択）、ChiSqSelector
4. **テキスト処理**: Tokenizer/RegexTokenizer（トークン化）、StopWordsRemover、HashingTF、IDF、Word2Vec、CountVectorizer
5. **変換処理**: Binarizer（二値化）、Bucketizer（バケット化）、QuantileDiscretizer、SQLTransformer
6. **次元変換**: PCA（主成分分析）、PolynomialExpansion

**関連システム・外部連携**：Spark DataFrame APIおよびPipeline APIと統合。各変換器はTransformerまたはEstimator[Model]パターンに従い、統一的なインターフェースを提供する。

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

## 関連画面

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

## 機能種別

計算処理（データ前処理 - 特徴量エンジニアリング）

## 入力仕様

### 入力パラメータ

主要な変換器のパラメータを以下に示す。

#### VectorAssembler
| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| inputCols | Array[String] | Yes | 入力カラム名配列 | 各カラムが数値型/Vector型 |
| outputCol | String | Yes | 出力カラム名 | - |
| handleInvalid | String | No | 無効データ処理（"error"/"skip"/"keep"、デフォルト: "error"） | - |

#### StandardScaler
| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| inputCol | String | Yes | 入力カラム名 | Vector型カラム |
| outputCol | String | Yes | 出力カラム名 | - |
| withMean | Boolean | No | 平均中心化するか（デフォルト: false） | - |
| withStd | Boolean | No | 標準偏差でスケーリングするか（デフォルト: true） | - |

#### StringIndexer
| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| inputCol(s) | String/Array[String] | Yes | 入力カラム名 | - |
| outputCol(s) | String/Array[String] | Yes | 出力カラム名 | - |
| handleInvalid | String | No | 未知ラベル処理（"error"/"skip"/"keep"、デフォルト: "error"） | - |
| stringOrderType | String | No | ラベル順序（"frequencyDesc"/"frequencyAsc"/"alphabetDesc"/"alphabetAsc"、デフォルト: "frequencyDesc"） | - |

### 入力データソース

Spark DataFrame。各変換器が要求するカラム型に従った入力データ。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| outputCol | 変換器依存 | 変換結果カラム（Vector型、Double型等） |

### 出力先

入力DataFrameにoutputColカラムを追加したDataFrame。

## 処理フロー

### 処理シーケンス

```
1. スキーマバリデーション
   └─ 入力カラムの型チェック
2. Estimatorの場合: fit()でモデル学習
   └─ 例: StandardScaler → 平均・標準偏差を算出
   └─ 例: StringIndexer → ラベルインデックス対応を学習
3. transform()でデータ変換
   └─ 学習済みパラメータを使って各行を変換
4. 出力DataFrameの生成
   └─ 入力DataFrameにoutputColを追加
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{Estimator or Transformer?}
    B -->|Estimator| C[fit: 統計量学習]
    C --> D[Model生成]
    D --> E[transform: データ変換]
    B -->|Transformer| E
    E --> F[出力DataFrame]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-66-01 | handleInvalid | "error"で例外、"skip"で除外、"keep"で特殊値 | 不正データ検出時 |
| BR-66-02 | StringIndexer順序 | frequencyDescは頻度降順でインデックス割当 | StringIndexer使用時 |
| BR-66-03 | StandardScaler疎データ | withMean=trueは密ベクトルを出力（疎入力注意） | StandardScaler使用時 |
| BR-66-04 | VectorAssembler結合 | 入力カラムを順序通りに結合してVector化 | VectorAssembler使用時 |

### 計算ロジック

- StandardScaler: x' = (x - mean) / std （withMean/withStdに依存）
- MinMaxScaler: x' = (x - min) / (max - min) * (max_range - min_range) + min_range
- Normalizer: x' = x / ||x||_p （pはL1/L2/Linf）
- TF-IDF: tfidf(t,d) = tf(t,d) * log((|D|+1) / (df(t)+1))

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| SparkException | 型不一致 | 入力カラムが期待する型と異なる | 正しい型のカラムを指定 |
| IllegalArgumentException | 未知ラベル | handleInvalid="error"で未知ラベル出現 | handleInvalid="keep"または"skip" |
| SparkException | NULL値 | handleInvalid="error"でNULL出現 | データ前処理またはhandleInvalid変更 |

### リトライ仕様

リトライ機構は組み込まれていない。

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

トランザクション管理なし。

## パフォーマンス要件

各変換器は1パスまたは2パスでデータを処理。VectorAssemblerはVectorSizeHintを前段に配置することでパフォーマンスを改善可能。

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

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

## 備考

- 40以上の変換器を提供
- Pipeline APIと組み合わせて変換パイプラインを構築可能
- 各変換器はMLWritable/MLReadableで永続化・復元可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | VectorAssembler.scala | `mllib/src/main/scala/org/apache/spark/ml/feature/VectorAssembler.scala` | Transformerパターンの基本形 |
| 1-2 | StandardScaler.scala | `mllib/src/main/scala/org/apache/spark/ml/feature/StandardScaler.scala` | Estimator/Modelパターンの基本形 |

**読解のコツ**: 特徴量変換器は大きく2つのパターンに分類される。(1) Transformer: 学習不要で直接変換（VectorAssembler, Binarizer等）、(2) Estimator[Model]: fit()で統計量を学習→Model.transform()で変換（StandardScaler, StringIndexer等）。

#### Step 2: 代表的なTransformerを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | VectorAssembler.scala | `mllib/src/main/scala/org/apache/spark/ml/feature/VectorAssembler.scala` | **44-46行目**: クラス定義、HasInputCols/HasOutputCol/HasHandleInvalidを継承 |

**主要処理フロー**:
1. **85-86行目**: transform()のエントリーポイント
2. **90-92行目**: 入力カラムとフィールドの取得
3. **94-96行目**: Vector型カラムの検出
4. **97-98行目**: Vector長の取得

#### Step 3: 代表的なEstimatorを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | StandardScaler.scala | `mllib/src/main/scala/org/apache/spark/ml/feature/StandardScaler.scala` | **38-73行目**: StandardScalerParamsでwithMean/withStdパラメータ定義 |
| 3-2 | StringIndexer.scala | `mllib/src/main/scala/org/apache/spark/ml/feature/StringIndexer.scala` | **42-99行目**: StringIndexerBaseで複数カラム対応パラメータ定義 |

#### Step 4: カテゴリ変換を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | StringIndexer.scala | `mllib/src/main/scala/org/apache/spark/ml/feature/StringIndexer.scala` | stringOrderTypeによるラベル順序制御 |

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

```
[Transformerパターン]
VectorAssembler.transform(dataset)
    |
    +-- transformSchema(schema)
    +-- 入力カラム取得・Vector長取得
    +-- UDFでベクトル結合
    +-- outputCol追加

[Estimatorパターン]
StandardScaler.fit(dataset)
    |
    +-- Summarizer.metrics("mean", "std")で統計量計算
    +-- StandardScalerModel(mean, std)生成
    |
StandardScalerModel.transform(dataset)
    +-- UDFで標準化変換
    +-- outputCol追加
```

### データフロー図

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

DataFrame           VectorAssembler                DataFrame
(col1, col2,    --> .transform()               --> (col1, col2, ...,
 col3, ...)         複数カラムをVector結合            features: Vector)

DataFrame           StandardScaler                 StandardScalerModel
(features:      --> .fit()                     --> (mean, std)
 Vector)            統計量算出

DataFrame           StandardScalerModel            DataFrame
(features)     --> .transform()               --> (features,
                    (x-mean)/std                    scaledFeatures)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| VectorAssembler.scala | `mllib/src/main/scala/org/apache/spark/ml/feature/VectorAssembler.scala` | ソース | 特徴量ベクトル結合 |
| StandardScaler.scala | `mllib/src/main/scala/org/apache/spark/ml/feature/StandardScaler.scala` | ソース | 標準化スケーリング |
| StringIndexer.scala | `mllib/src/main/scala/org/apache/spark/ml/feature/StringIndexer.scala` | ソース | 文字列インデックス化 |
| OneHotEncoder.scala | `mllib/src/main/scala/org/apache/spark/ml/feature/OneHotEncoder.scala` | ソース | ワンホットエンコーディング |
| Tokenizer.scala | `mllib/src/main/scala/org/apache/spark/ml/feature/Tokenizer.scala` | ソース | テキストトークン化 |
| HashingTF.scala | `mllib/src/main/scala/org/apache/spark/ml/feature/HashingTF.scala` | ソース | ハッシュTF |
| IDF.scala | `mllib/src/main/scala/org/apache/spark/ml/feature/IDF.scala` | ソース | IDF変換 |
| Word2Vec.scala | `mllib/src/main/scala/org/apache/spark/ml/feature/Word2Vec.scala` | ソース | Word2Vec |
| PCA.scala | `mllib/src/main/scala/org/apache/spark/ml/feature/PCA.scala` | ソース | 主成分分析 |
| Normalizer.scala | `mllib/src/main/scala/org/apache/spark/ml/feature/Normalizer.scala` | ソース | ベクトル正規化 |
| MinMaxScaler.scala | `mllib/src/main/scala/org/apache/spark/ml/feature/MinMaxScaler.scala` | ソース | 最小最大スケーリング |
| Binarizer.scala | `mllib/src/main/scala/org/apache/spark/ml/feature/Binarizer.scala` | ソース | 二値化 |
| Bucketizer.scala | `mllib/src/main/scala/org/apache/spark/ml/feature/Bucketizer.scala` | ソース | バケット化 |
| CountVectorizer.scala | `mllib/src/main/scala/org/apache/spark/ml/feature/CountVectorizer.scala` | ソース | カウントベクトル化 |
