# 機能設計書 136-カウント操作

## 概要

本ドキュメントは、TensorFlowのテンソル要素カウント操作（bincount等）の機能設計について記載する。

### 本機能の処理概要

カウント操作は、テンソル内の整数要素の出現回数を数え上げる（bincount）機能を提供する。密テンソル、スパーステンソル、RaggedTensorの各形式に対応する。

**業務上の目的・背景**：データ分析・機械学習において、カテゴリカルデータの頻度分布の計算は基本的な前処理操作である。bincountは特徴量エンジニアリング、ヒストグラム計算、one-hotエンコーディングの基盤として広く使用される。

**機能の利用シーン**：整数配列内の各値の出現回数のカウント、重み付きカウント（加重ヒストグラム）、バイナリ出力（存在/不在のフラグ化）、行ごとの独立したbincount（axis指定）など。

**主要な処理内容**：
1. `tf.math.bincount`：密テンソルの要素カウント（Python API）
2. `DenseCountSparseOutput`：密テンソル入力からスパース出力でのカウント（C++ Op）
3. `SparseCountSparseOutput`：スパーステンソル入力からのカウント（C++ Op）
4. `RaggedCountSparseOutput`：RaggedTensor入力からのカウント（C++ Op）
5. 重み付きカウント、minlength/maxlengthによる出力範囲制御
6. binary_outputによるバイナリフラグ出力

**関連システム・外部連携**：スパーステンソル操作（No.57）、RaggedTensor操作（No.59）、数学演算（No.2）と連携する。

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

## 関連画面

本機能は画面機能マッピングにおいて直接的な関連画面は定義されていない。

## 機能種別

計算処理 / 集約演算

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| arr / values | Tensor[int32/int64] | Yes | カウント対象の整数テンソル | int32またはint64 |
| weights | Tensor | No | 重みテンソル（arrと同じ形状） | arrと互換形状 |
| minlength | int | No | 出力の最小長（デフォルト: -1=制限なし） | -1以上 |
| maxlength | int | No | 出力の最大長（デフォルト: -1=制限なし） | -1以上 |
| dtype | DType | No | 出力のデータ型（デフォルト: int32） | int32/int64/float/double |
| axis | int | No | カウントを行う軸（Noneで全体フラット化） | None or -1 |
| binary_output | bool | No | バイナリ出力モード（デフォルト: False） | ブール値 |
| indices | Tensor[int64] | Yes（Sparse） | スパーステンソルのインデックス | 2Dテンソル |
| dense_shape | Tensor[int64] | Yes（Sparse） | スパーステンソルの密形状 | 1Dテンソル |
| splits | Tensor[int64] | Yes（Ragged） | RaggedTensorの分割点 | 1Dテンソル |

### 入力データソース

Pythonコードからの直接呼び出し、またはデータ前処理パイプライン内での使用。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result (dense) | Tensor | 各値の出現回数（密テンソルとして） |
| output_indices | Tensor[int64] | スパース出力のインデックス |
| output_values | Tensor[output_type] | スパース出力の値 |
| output_dense_shape | Tensor[int64] | スパース出力の密形状 |

### 出力先

計算グラフ内の後続オペレーションへの入力。

## 処理フロー

### 処理シーケンス

```
1. 入力テンソルの型・形状検証
   └─ int32/int64であることを確認

2. 重みテンソルの検証
   └─ 形状がvaluesと一致することを確認
   └─ 重みなしの場合、カウント=1で加算

3. カウント処理
   └─ 各整数値の出現回数（または重み合計）を計算
   └─ minlength/maxlengthで出力範囲を制限

4. 出力生成
   └─ スパース形式（indices, values, dense_shape）で出力
```

### フローチャート

```mermaid
flowchart TD
    A[入力テンソル] --> B{テンソル形式}
    B -->|Dense| C[DenseCountSparseOutput]
    B -->|Sparse| D[SparseCountSparseOutput]
    B -->|Ragged| E[RaggedCountSparseOutput]
    C --> F[スパース出力 indices, values, dense_shape]
    D --> F
    E --> F
    F --> G{binary_output?}
    G -->|Yes| H[値を0/1に変換]
    G -->|No| I[カウント値をそのまま出力]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-136-01 | 入力型制約 | values入力はint32またはint64のみ | 常時 |
| BR-136-02 | 出力型選択 | output_typeはint32/int64/float/doubleから選択 | 常時 |
| BR-136-03 | 重みとの等価性 | 重み付きbincountはunsorted_segment_sumと等価 | weights指定時 |
| BR-136-04 | GPU制限 | GPUでのweights付きbincountはXLA有効時のみサポート | GPU環境 |

### 計算ロジック

- 重みなし: `output[v] = count(values == v)`
- 重みあり: `output[v] = sum(weights[i] for i where values[i] == v)`
- binary_output: `output[v] = 1 if any(values == v) else 0`

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

本機能にデータベース操作はない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| TypeError | 型エラー | 入力がint32/int64以外の場合 | 整数型にキャストする |
| ValueError | 形状エラー | weightsの形状がvaluesと不一致 | 形状を一致させる |
| InvalidArgumentError | 値エラー | 負の値が含まれる場合 | 非負整数のみを入力する |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

GPU上での重み付きbincountはXLA（jit_compile=True）が必要。XLAなしのGPU環境ではunsorted_segment_sumを代替として使用可能。

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

特段のセキュリティ考慮事項はない。

## 備考

- `tf.math.bincount`はv1 APIでは`tf.math.bincount`および`tf.bincount`として公開
- axisパラメータにより行ごとの独立したbincount（2D入力時）が可能
- スパース出力形式を使用することで、大きなmaxlength時のメモリ効率を向上

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | count_ops.cc | `tensorflow/core/ops/count_ops.cc` | C++ Op定義（DenseCount, SparseCount, RaggedCount） |

**読解のコツ**: 3つのOp全てがスパース出力（indices, values, dense_shape）を返す点に注目。入力形式が異なるだけで出力形式は統一されている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | bincount_ops.py | `tensorflow/python/ops/bincount_ops.py` | Python APIエントリーポイント `tf.math.bincount` |

**主要処理フロー**:
- **29-38行目**: `bincount`関数の定義（@tf_export, @dispatch.add_dispatch_support）
- **39-100行目**: docstring - 使用例（基本、重み付き、行ごと、バイナリ出力）

#### Step 3: C++ Op定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | count_ops.cc | `tensorflow/core/ops/count_ops.cc` | Op登録とShapeFn定義 |

**主要処理フロー**:
- **25-41行目**: DenseCountSparseOutputShapeFn - 密テンソル入力のシェイプ推論
- **43-52行目**: SparseCountSparseOutputShapeFn - スパーステンソル入力のシェイプ推論
- **54-64行目**: RaggedCountSparseOutputShapeFn - RaggedTensor入力のシェイプ推論
- **66-77行目**: DenseCountSparseOutput Op登録
- **79-92行目**: SparseCountSparseOutput Op登録
- **94-106行目**: RaggedCountSparseOutput Op登録

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

```
tf.math.bincount (bincount_ops.py:29)
    |
    +-- [Dense入力]
    |       +-- gen_math_ops.dense_count_sparse_output
    |               +-- DenseCountSparseOutput (count_ops.cc:66)
    |
    +-- [Sparse入力]
    |       +-- gen_math_ops.sparse_count_sparse_output
    |               +-- SparseCountSparseOutput (count_ops.cc:79)
    |
    +-- [Ragged入力]
            +-- gen_math_ops.ragged_count_sparse_output
                    +-- RaggedCountSparseOutput (count_ops.cc:94)
```

### データフロー図

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

values (int32/64)   ---> DenseCountSparseOutput    ---> (indices, values, dense_shape)
weights (optional)       |
minlength/maxlength      +-> カウント計算
binary_output            +-> バイナリ変換（optional）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| count_ops.cc | `tensorflow/core/ops/count_ops.cc` | ソース | C++ Op定義とShapeFn |
| bincount_ops.py | `tensorflow/python/ops/bincount_ops.py` | ソース | Python API（tf.math.bincount） |
| gen_math_ops.py | `tensorflow/python/ops/gen_math_ops.py` | 生成ファイル | 自動生成されたOp呼び出しラッパー |
