# 機能設計書 49-データ解析（Parsing Operations）

## 概要

本ドキュメントは、TensorFlowにおけるデータ解析（Parsing Operations）機能の設計を記述する。TFRecord・Example・CSV・JSON等のデータ形式のパース機能を提供する。

### 本機能の処理概要

本機能は、シリアライズされたデータ（Protocol Buffer形式のtf.train.Example/SequenceExample等）をテンソルに変換するパース操作を提供する。TFRecordファイルから読み込んだバイナリデータをモデルが処理可能なテンソルに変換する中核的な機能である。

**業務上の目的・背景**：機械学習のデータパイプラインでは、ストレージ効率と読込み速度の観点から、データをTFRecord/Protocol Buffer形式でシリアライズして保存することが一般的である。本パース機能は、これらのシリアライズされたデータを、密テンソル・スパーステンソル・ラグドテンソルとして効率的にデシリアライズする。バッチ処理にも対応し、大規模データの高速処理を可能にする。

**機能の利用シーン**：（1）TFRecordDatasetから読み込んだバイナリレコードをパースする場面、（2）バッチ単位でExampleを一括パースする場面、（3）SequenceExampleからコンテキスト特徴量と特徴量リストを分離パースする場面、（4）生バイト列を数値テンソルにデコードする場面。

**主要な処理内容**：
1. DecodeRaw: 生バイト列を指定型のテンソルにデコード
2. ParseExample/ParseExampleV2: tf.train.Exampleのバッチパース（密/スパース/ラグド特徴量対応）
3. ParseSingleExample: 単一Exampleのパース
4. ParseSequenceExample/V2: SequenceExampleのパース（コンテキスト+特徴量リスト）
5. DecodeCompressed: 圧縮バイト列の解凍
6. DecodePaddedRaw: 固定長パディング付きバイトデコード

**関連システム・外部連携**：tf.data.Dataset API（No.44）、TFRecordファイル（No.50）、tf.train.Example/SequenceExample Protocol Buffer。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面機能マッピングに本機能の関連画面なし |

## 機能種別

計算処理 / データ連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| serialized | string | Yes | シリアライズされたExampleバイト列 | 1次元ベクトル（V2ではスカラーも可） |
| names | string | No | デバッグ用のExample名 | serializedと同形状 |
| sparse_keys | string | Yes | スパース特徴量のキーリスト | V1ではNsparse個のスカラー、V2ではベクトル |
| dense_keys | string | Yes | 密特徴量のキーリスト | V1ではNdense個のスカラー、V2ではベクトル |
| ragged_keys | string | No | ラグド特徴量のキーリスト（V2のみ） | ベクトル |
| dense_defaults | Tdense | Yes | 密特徴量のデフォルト値 | 型リスト |
| bytes | string | Yes | DecodeRaw用の生バイト列 | 任意形状 |
| out_type | DType | Yes | DecodeRaw用の出力型 | half/float/double/int32/uint16等 |
| little_endian | bool | No | DecodeRawのエンディアン | デフォルトtrue |

### 入力データソース

TFRecordファイルから読み込んだバイナリレコード、またはシリアライズされたProtocol Bufferメッセージ。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| sparse_indices | int64 | スパース特徴量のインデックス（各キーごと） |
| sparse_values | sparse_types | スパース特徴量の値 |
| sparse_shapes | int64 | スパース特徴量の密形状 |
| dense_values | Tdense | 密特徴量の値（バッチ次元 + 特徴量次元） |
| ragged_values | ragged_value_types | ラグド特徴量の値（V2のみ） |
| ragged_row_splits | ragged_split_types | ラグド特徴量の行分割（V2のみ） |
| output | out_type | DecodeRawの出力テンソル |

### 出力先

tf.dataパイプラインの後続変換、またはモデルの入力テンソル。

## 処理フロー

### 処理シーケンス

```
1. シリアライズされたバイト列を受取
2. 特徴量キーに基づいてExample/SequenceExampleをパース
   └─ 密特徴量: 固定形状テンソルとして出力（デフォルト値で補完）
   └─ スパース特徴量: SparseTensor (indices, values, shapes)として出力
   └─ ラグド特徴量: RaggedTensor (values, row_splits)として出力
3. 形状推論
   └─ 密出力: バッチ次元 + dense_shapesで決定
   └─ スパース出力: indices=(?, rank), values=(?), shapes=(rank,)
   └─ ラグド出力: values=(?), row_splits=(batch+1,)
```

### フローチャート

```mermaid
flowchart TD
    A[シリアライズされたExample] --> B[ParseExampleV2 Op]
    B --> C{特徴量タイプ}
    C -->|dense| D[固定形状テンソルとして出力]
    C -->|sparse| E[SparseTensorとして出力]
    C -->|ragged| F[RaggedTensorとして出力]
    D --> G[モデル入力]
    E --> G
    F --> G
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-49-01 | V2スカラー対応 | ParseExampleV2ではserializedがスカラーまたはベクトル | ParseExampleV2 |
| BR-49-02 | 密形状指定 | 密特徴量はdense_shapesで形状を事前指定する必要がある | ParseExample/V2 |
| BR-49-03 | デフォルト値 | 密特徴量が欠損している場合、dense_defaultsで補完 | ParseExample/V2 |
| BR-49-04 | ラグドV2限定 | ラグド特徴量のパースはV2 Opでのみ利用可能 | ParseExampleV2/ParseSequenceExampleV2 |
| BR-49-05 | エンディアン | DecodeRawのデフォルトはリトルエンディアン | DecodeRaw |

### 計算ロジック

- **密出力形状**: batch_shape + dense_shape（例: [batch, feature_dim]）
- **スパースインデックス形状**: [nnz, rank]（nnzは非ゼロ要素数、rankは入力ランク+1）
- **DecodePaddedRaw出力幅**: fixed_length / sizeof(out_type)

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし |

### テーブル別操作詳細

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| InvalidArgumentError | パースエラー | ExampleのProtocol Bufferが不正 | 正しいフォーマットのデータを使用 |
| InvalidArgumentError | 形状エラー | shape_and_slicesの数がテンソル数と不一致 | 引数の整合性を確認 |

### リトライ仕様

リトライ不要。

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

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

## パフォーマンス要件

- ParseExampleV2はバッチ処理に最適化されており、大量のExampleを効率的にパースする
- 密特徴量のパースはメモリ連続配置で高速
- スパース/ラグド特徴量は動的サイズのため、オーバーヘッドがやや大きい

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

- 信頼できないProtocol Bufferデータのパースにはバッファオーバーフローのリスクがある
- DecodeRawは任意のバイト列を指定型として解釈するため、データの整合性に注意

## 備考

- ParseExampleV1とV2の主な違い: V2はスカラー入力対応、ラグド特徴量対応、キーをベクトルで渡す
- ParseSequenceExampleは時系列データ（FeatureList）のパースに特化

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | parsing_ops.cc | `tensorflow/core/ops/parsing_ops.cc` | パースOp登録とヘルパー関数 |

**読解のコツ**: ファイル先頭のヘルパー関数（AddDenseOutputShapes, AddSparseOutputShapes, AddRaggedOutputShapes）が、パース出力の形状推論ロジックを定義している。これらを理解すると、各OpのSetShapeFnの動作が明確になる。

#### Step 2: 基本的なパースOpを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | parsing_ops.cc | `tensorflow/core/ops/parsing_ops.cc` | DecodeRaw, ParseExample |

**主要処理フロー**:
1. **30-42行目**: AddDenseOutputShapes - prefix + dense_shapeで密出力形状を計算
2. **45-62行目**: AddSparseOutputShapes - スパースインデックス/値/形状の出力形状
3. **65-85行目**: AddRaggedOutputShapes - ラグド値/行分割の出力形状
4. **97-112行目**: DecodeRaw Op定義 - バイト列→指定型テンソル変換
5. **114-139行目**: DecodePaddedRaw - 固定長パディング付きデコード
6. **147-176行目**: ParseExample(V1) - serializedは1次元ベクトル限定
7. **186-227行目**: ParseExampleV2 - serializedはスカラーまたはベクトル、ラグド対応

#### Step 3: SequenceExampleパースを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | parsing_ops.cc | `tensorflow/core/ops/parsing_ops.cc` | ParseSequenceExample/V2 |

**主要処理フロー**:
- **256-310行目**: ParseSequenceExample(V1) - コンテキスト特徴量と特徴量リストの分離パース
- **321-399行目**: ParseSequenceExampleV2 - ラグド対応版

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

```
tf.io.parse_example(serialized, features)
    │
    └─ gen_parsing_ops.parse_example_v2(...)  (Python自動生成)
           │
           └─ ParseExampleV2 Op (C++)
                  ├─ ParseExampleAttrs::Init(c, op_version=2)
                  ├─ AddSparseOutputShapes()
                  ├─ AddDenseOutputShapes()
                  └─ AddRaggedOutputShapes()

tf.io.decode_raw(input_bytes, out_type)
    │
    └─ gen_parsing_ops.decode_raw(...)
           │
           └─ DecodeRaw Op (C++)
                  └─ バイト列→テンソル変換
```

### データフロー図

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

serialized ────────────▶ ParseExampleV2 ──────▶ dense_values (固定形状)
  (Protocol Buffer)           │                  sparse_indices/values/shapes
                              │                  ragged_values/row_splits
                              │
sparse_keys ─────────────────┤
dense_keys ──────────────────┤
ragged_keys ─────────────────┤
dense_defaults ──────────────┘

bytes ──────────────────▶ DecodeRaw ──────────▶ output (指定型テンソル)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| parsing_ops.cc | `tensorflow/core/ops/parsing_ops.cc` | ソース(C++) | パースOp登録と形状推論 |
| example_proto_helper.h | `tensorflow/core/util/example_proto_helper.h` | ヘッダ | ParseExampleAttrs等のヘルパー |
| gen_parsing_ops.py | `tensorflow/python/ops/gen_parsing_ops.py` | 自動生成 | PythonバインディングWrapper |
| common_shape_fns.h | `tensorflow/core/framework/common_shape_fns.h` | ヘッダ | 形状推論共通関数 |
