# 機能設計書 137-混同行列計算

## 概要

本ドキュメントは、TensorFlowの混同行列（Confusion Matrix）計算機能の機能設計について記載する。

### 本機能の処理概要

混同行列計算は、分類モデルの予測結果と正解ラベルから混同行列を生成する機能を提供する。

**業務上の目的・背景**：分類モデルの性能評価において、混同行列は最も基本的な評価ツールである。各クラスの正解・誤分類のパターンを一目で把握でき、Precision、Recall、F1スコアなどの評価指標の算出基盤となる。

**機能の利用シーン**：分類モデルの評価フェーズで、テストデータに対する予測結果の分析に使用される。多クラス分類、二値分類のいずれにも対応する。

**主要な処理内容**：
1. `tf.math.confusion_matrix`：正解ラベルと予測ラベルから混同行列を計算
2. `remove_squeezable_dimensions`：ラベルと予測のランク差を自動調整
3. 重み付き混同行列の計算（各予測に異なる重みを付与）
4. クラス数の自動推論（num_classes未指定時）

**関連システム・外部連携**：評価指標（No.41）、損失関数（No.40）と連携する。

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

## 関連画面

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

## 機能種別

計算処理 / 評価・分析

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| labels | Tensor | Yes | 正解ラベル（1Dテンソル） | 非負整数、predictionsと同じ形状 |
| predictions | Tensor | Yes | 予測ラベル（1Dテンソル） | 非負整数、labelsと同じ形状 |
| num_classes | int | No | クラス数（Noneで自動推論） | 正整数 |
| weights | Tensor | No | 各予測の重み | predictionsと同じ形状 |
| dtype | DType | No | 出力のデータ型（デフォルト: int32） | TensorFlowデータ型 |
| name | str | No | 操作のスコープ名 | 文字列 |

### 入力データソース

モデルの予測結果と正解ラベル。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| confusion_matrix | Tensor[n, n] | n x n の混同行列（行=正解ラベル、列=予測ラベル） |

### 出力先

計算グラフ内の後続オペレーションへの入力、またはNumPy配列として評価結果の表示。

## 処理フロー

### 処理シーケンス

```
1. 入力の前処理
   └─ remove_squeezable_dimensions でランク差を調整
   └─ labels, predictions を int64 にキャスト

2. 入力バリデーション
   └─ labels >= 0 のassert
   └─ predictions >= 0 のassert
   └─ num_classes指定時: labels < num_classes, predictions < num_classes のassert

3. num_classesの決定
   └─ 指定時: そのまま使用
   └─ 未指定時: max(max(predictions), max(labels)) + 1

4. 混同行列の計算
   └─ indices = stack([labels, predictions], axis=1)
   └─ values = ones_like(predictions) または weights
   └─ scatter_nd(indices, values, [num_classes, num_classes])
```

### フローチャート

```mermaid
flowchart TD
    A[labels, predictions入力] --> B[remove_squeezable_dimensions]
    B --> C[int64にキャスト]
    C --> D[非負値assert]
    D --> E{num_classes指定?}
    E -->|Yes| F[範囲チェックassert]
    E -->|No| G[max labels,predictions + 1]
    F --> H[indices = stack labels predictions]
    G --> H
    H --> I{weights指定?}
    I -->|Yes| J[values = weights]
    I -->|No| K[values = ones_like]
    J --> L[scatter_nd indices values shape]
    K --> L
    L --> M[混同行列 n x n]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-137-01 | 非負整数制約 | labels/predictionsは非負整数でなければならない | 常時 |
| BR-137-02 | 形状一致 | labels/predictionsは同じ形状（1D）でなければならない | 常時 |
| BR-137-03 | 自動クラス数推論 | num_classes未指定時はmax(labels, predictions) + 1 | num_classes=None時 |
| BR-137-04 | 行列の解釈 | 行が正解ラベル、列が予測ラベルを表す | 常時 |

### 計算ロジック

混同行列 `C` の各要素: `C[i][j]` = 正解がクラス `i` で予測がクラス `j` であるサンプル数（または重み合計）。`scatter_nd`オペレーションを使用して、(labels, predictions)のペアをインデックスとして行列に値を散布する。

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| InvalidArgumentError | アサーション失敗 | labelsに負の値が含まれる | 非負整数に修正 |
| InvalidArgumentError | アサーション失敗 | predictionsに負の値が含まれる | 非負整数に修正 |
| InvalidArgumentError | アサーション失敗 | labels/predictionsがnum_classes以上 | num_classesを増やすか値を修正 |
| ValueError | 形状エラー | labels/predictionsの形状不一致 | 同一形状にする |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

scatter_ndオペレーションによる効率的な行列構築。大量のサンプルに対してもメモリ使用量はO(num_classes^2)に抑えられる。

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

- 負の値によるメモリ破壊を防止するためのassertチェックが実装されている（confusion_matrix.py 159-167行目）

## 備考

- `remove_squeezable_dimensions`はラベルと予測のランク差が1の場合に自動的にsqueezeを行う。これにより、one-hot形式と整数ラベル形式の両方に対応可能
- v1 APIでは`tf.confusion_matrix`としても公開されている

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | confusion_matrix.py | `tensorflow/python/ops/confusion_matrix.py` | 混同行列のデータ構造（n x n テンソル） |

**読解のコツ**: 混同行列は`scatter_nd`を使用して構築される。(labels, predictions)ペアを2D行列のインデックスとして使用する点が核心。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | confusion_matrix.py | `tensorflow/python/ops/confusion_matrix.py` | confusion_matrix関数（92-196行目） |

**主要処理フロー**:
1. **92-93行目**: `@tf_export('math.confusion_matrix', v1=[])` - API公開定義
2. **150-155行目**: remove_squeezable_dimensionsでランク調整、int64キャスト
3. **159-167行目**: 非負値アサーション（メモリ破壊防止）
4. **169-182行目**: num_classesの決定と範囲チェック
5. **189-196行目**: scatter_ndによる混同行列の構築

#### Step 3: 補助関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | confusion_matrix.py | `tensorflow/python/ops/confusion_matrix.py` | remove_squeezable_dimensions（30-89行目） |

**主要処理フロー**:
- **30-55行目**: docstring - expected_rank_diffに基づくsqueeze判定の説明
- **56-89行目**: 静的ランクと動的ランクの両方に対応した実装

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

```
tf.math.confusion_matrix (confusion_matrix.py:92)
    |
    +-- remove_squeezable_dimensions (confusion_matrix.py:30)
    |       +-- array_ops.squeeze
    |       +-- cond.cond (動的ランク判定)
    |
    +-- math_ops.cast (int64変換)
    +-- check_ops.assert_non_negative (非負チェック)
    +-- check_ops.assert_less (範囲チェック)
    +-- array_ops_stack.stack (インデックス構築)
    +-- array_ops.scatter_nd (混同行列生成)
```

### データフロー図

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

labels (1D int)     ---> remove_squeezable_dimensions
predictions (1D int)     |
                    ---> cast to int64
                    ---> assert_non_negative
                    ---> stack([labels, predictions])  ---> indices (N, 2)
weights (optional)  ---> ones_like or weights          ---> values (N,)
num_classes         ---> scatter_nd(indices, values,    ---> confusion_matrix
                         [num_classes, num_classes])         (num_classes, num_classes)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| confusion_matrix.py | `tensorflow/python/ops/confusion_matrix.py` | ソース | confusion_matrix関数とremove_squeezable_dimensions |
| array_ops.py | `tensorflow/python/ops/array_ops.py` | ソース | scatter_nd, squeeze等の配列操作 |
| check_ops.py | `tensorflow/python/ops/check_ops.py` | ソース | assert_non_negative, assert_less |
| math_ops.py | `tensorflow/python/ops/math_ops.py` | ソース | cast, reduce_max |
