# 機能設計書 41-評価指標（Metrics）

## 概要

本ドキュメントは、TensorFlow/Kerasにおける評価指標（Metrics）機能の設計を記述する。モデルの学習・評価時に予測精度や性能を定量的に測定するためのメトリクスクラス群を提供する。

### 本機能の処理概要

本機能は、ニューラルネットワークモデルの訓練および評価において、予測結果と正解ラベルを比較し、モデル性能を数値指標として算出する機能である。Accuracy、Precision、Recall、AUCなど多様な評価指標を提供する。

**業務上の目的・背景**：機械学習モデルの品質を客観的に評価するためには、定量的な指標が不可欠である。モデルの学習進行状況のモニタリング、ハイパーパラメータチューニングの判断基準、異なるモデル間の比較に利用される。特に分類・回帰タスクにおいて、適切なメトリクスを選択することが、モデルの実運用品質を左右する。

**機能の利用シーン**：（1）`model.compile()`でメトリクスを指定し訓練中に性能を追跡する場面、（2）`model.evaluate()`でテストデータに対する最終性能を計測する場面、（3）カスタムトレーニングループ内で`update_state()`/`result()`を呼び出して逐次的に評価する場面。

**主要な処理内容**：
1. Metricベースクラスによる状態変数管理（add_weight）とステートフルな統計集計
2. update_state()による予測値・正解値の逐次蓄積
3. result()による最終指標値の算出
4. reset_state()によるエポック間でのメトリクス状態のリセット
5. 混同行列ベースの指標（Precision、Recall、AUC等）の効率的な計算
6. サンプル重み付けによる不均衡データへの対応

**関連システム・外部連携**：Kerasのmodel.compile()API、Kerasコールバック（ModelCheckpoint等）、TensorBoardによるメトリクス可視化、分散学習時のレプリカ間メトリクス集約。

**権限による制御**：特になし。全てのユーザが利用可能。

## 関連画面

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

## 機能種別

計算処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| y_true | Tensor | Yes | 正解ラベル | 形状がy_predと互換であること |
| y_pred | Tensor | Yes | モデルの予測値 | 形状がy_trueと互換であること |
| sample_weight | Tensor | No | サンプルごとの重み | None可。スカラーまたはy_trueと同形状 |
| name | string | No | メトリクスインスタンスの名前 | None可 |
| dtype | DType | No | メトリクス結果のデータ型 | None可。デフォルトはfloatx() |
| thresholds | float/list | No | 閾値（分類メトリクス用） | [0,1]の範囲。デフォルト0.5 |
| top_k | int | No | Top-K精度計算用のK値 | 正の整数 |
| class_id | int | No | 特定クラスのバイナリメトリクス用 | [0, num_classes)の範囲 |

### 入力データソース

Kerasモデルの訓練ループ（model.fit）、評価ループ（model.evaluate）、またはユーザのカスタムトレーニングループからの予測値と正解ラベル。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| metric_value | Tensor (scalar) | 算出された評価指標値（0.0〜1.0等） |

### 出力先

Kerasのトレーニングログ（History）、TensorBoardサマリー、コンソール出力（verbose設定による）。

## 処理フロー

### 処理シーケンス

```
1. メトリクスインスタンス生成（__init__）
   └─ 状態変数（total, count, accumulator等）をadd_weight()で生成
2. ミニバッチごとのupdate_state()呼び出し
   └─ y_true, y_predの型変換、sample_weightのブロードキャスト
   └─ 統計量の累積（assign_add）
3. result()呼び出し
   └─ 蓄積された統計量から最終指標値を算出（例: total / count）
4. エポック完了時のreset_state()呼び出し
   └─ 全状態変数を0にリセット
```

### フローチャート

```mermaid
flowchart TD
    A[メトリクスインスタンス生成] --> B[状態変数の初期化]
    B --> C{ミニバッチ処理}
    C --> D[update_state: y_true, y_pred受取]
    D --> E[型変換・次元調整]
    E --> F[sample_weight適用]
    F --> G[統計量累積 assign_add]
    G --> C
    C -->|エポック終了| H[result: 指標値算出]
    H --> I[reset_state: 状態リセット]
    I --> C
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-41-01 | ステートフル集計 | メトリクスはミニバッチ間で状態を保持し、エポック全体の指標を算出する | 常時 |
| BR-41-02 | サンプル重み付け | sample_weightがNoneの場合、全サンプルの重みは1.0とする | update_state呼び出し時 |
| BR-41-03 | 閾値ベース分類 | 分類メトリクスでは予測値を閾値と比較してtrue/falseに二値化する | Precision/Recall等の呼び出し時 |
| BR-41-04 | エポック間リセット | 各エポック開始時にメトリクス状態がリセットされる | model.fit内部 |

### 計算ロジック

- **Accuracy**: `mean(y_true == argmax(y_pred))`
- **Precision**: `true_positives / (true_positives + false_positives)`
- **Recall**: `true_positives / (true_positives + false_negatives)`
- **AUC**: 台形則による曲線下面積の近似計算
- **Mean**: `total / count`（重み付き平均）

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

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

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

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

該当なし。全ての計算はテンソル操作としてインメモリで実行される。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ValueError | 入力エラー | y_trueとy_predの形状が不一致 | 入力テンソルの形状を確認 |
| RuntimeError | 出力エラー | メトリクス関数が複数テンソルを返す | 単一テンソルを返すよう修正 |
| TypeError | 型エラー | メトリクスの直列化時にget_config未実装 | get_configメソッドを実装 |

### リトライ仕様

リトライ不要。エラー発生時は即座に例外が送出される。

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

トランザクション管理なし。メトリクスの状態更新はテンソル変数のassign_addで行われ、制御依存性（control_dependencies）により順序が保証される。

## パフォーマンス要件

- ミニバッチごとのupdate_stateは低オーバーヘッドであること（メインの学習計算に対して無視できる程度）
- AUC等のビニングベースメトリクスは、閾値数（デフォルト200）に比例する計算コスト
- 分散学習時はレプリカ間でのON_READ集約が必要

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

特になし。入力データに対する特別なセキュリティ制約はない。

## 備考

- カスタムメトリクスはMetricベースクラスを継承し、`__init__`、`update_state`、`result`の3メソッドを実装する
- `MeanMetricWrapper`を使用すると、関数ベースのメトリクスを簡単にステートフル化できる
- 分散学習時、メトリクス変数はVariableSynchronization.ON_READで同期される

---

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

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

### 推奨読解順序

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

メトリクスの基本構造として、Metricベースクラスの状態管理パターンを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | metrics.py | `tensorflow/python/keras/metrics.py` | Metricクラスの定義と状態変数管理 |
| 1-2 | metrics_utils.py | `tensorflow/python/keras/utils/metrics_utils.py` | Reduction列挙型、混同行列ユーティリティ |

**読解のコツ**: Metricクラスはbase_layer.Layerを継承しているため、add_weight()でtf.Variableを生成する仕組みはLayerと共通。`stateful = True`により、保存・復元の対象となる。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | metrics.py | `tensorflow/python/keras/metrics.py` | Metric.__new__()でupdate_stateとresultをラップ |

**主要処理フロー**:
1. **74-189行目**: Metricクラスの定義。`__new__`でupdate_state/resultをtf.functionでラップ
2. **146-154行目**: `__init__`で状態変数の初期化、dtypeの設定
3. **191-230行目**: `__call__`でupdate_stateとresultを連続実行（分散学習対応）
4. **256-273行目**: `update_state`抽象メソッド定義
5. **275-282行目**: `result`抽象メソッド定義
6. **286-313行目**: `add_weight`メソッドで状態変数を追加（TPU対応含む）

#### Step 3: 集約メトリクス層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | metrics.py | `tensorflow/python/keras/metrics.py` | Reduceクラス（Sum/Mean/WeightedMeanの共通実装） |

**主要処理フロー**:
- **354-449行目**: Reduceクラス。total/countの2変数による集約パターン
- **373-437行目**: update_stateでsample_weightの適用とreductionタイプ別の累積処理
- **439-449行目**: resultで集約結果を算出（SUM / WEIGHTED_MEAN / SUM_OVER_BATCH_SIZE）

#### Step 4: 具体的なメトリクス実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | metrics.py | `tensorflow/python/keras/metrics.py` | MeanMetricWrapper、Accuracy、Precision等 |

**主要処理フロー**:
- **608-694行目**: MeanMetricWrapperによる関数ベースメトリクスのラッピング
- **697-735行目**: Accuracyクラス（MeanMetricWrapper経由でaccuracy関数を利用）
- **958-1025行目**: _ConfusionMatrixConditionCount（混同行列ベースメトリクスの基底クラス）
- **1220-1299行目**: Precisionクラス（true_positives / (true_positives + false_positives)）

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

```
model.compile(metrics=[...])
    │
    ├─ Metric.__init__()
    │      └─ add_weight() → tf.Variable生成
    │
    ├─ model.fit() / model.evaluate()
    │      │
    │      ├─ Metric.__call__()
    │      │      ├─ update_state(y_true, y_pred, sample_weight)
    │      │      │      ├─ [Reduce] → 型変換 → sample_weight適用 → total.assign_add()
    │      │      │      └─ [ConfusionMatrix] → metrics_utils.update_confusion_matrix_variables()
    │      │      └─ result()
    │      │             ├─ [Reduce] → total / count
    │      │             └─ [ConfusionMatrix] → accumulator値返却
    │      │
    │      └─ reset_state()
    │             └─ batch_set_value([(v, 0) for v in variables])
    │
    └─ distributed_training_utils.call_replica_local_fn()
           └─ レプリカローカルな更新・集約
```

### データフロー図

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

y_true (正解)  ──────┐
                     ├──▶ Metric.update_state()  ──▶ 状態変数更新
y_pred (予測)  ──────┤        │                         │
                     │        ▼                         ▼
sample_weight ───────┘   型変換・次元調整          Metric.result()
                              │                         │
                              ▼                         ▼
                         統計量累積              メトリクス値 (scalar Tensor)
                         (assign_add)                   │
                                                        ▼
                                                History / TensorBoard
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| metrics.py | `tensorflow/python/keras/metrics.py` | ソース | メトリクスクラス群の主要実装 |
| metrics_utils.py | `tensorflow/python/keras/utils/metrics_utils.py` | ソース | 混同行列更新、閾値パース等のユーティリティ |
| losses_utils.py | `tensorflow/python/keras/utils/losses_utils.py` | ソース | 次元調整、ブロードキャストユーティリティ |
| base_layer.py | `tensorflow/python/keras/engine/base_layer.py` | ソース | Metricの親クラスLayerの実装 |
| confusion_matrix.py | `tensorflow/python/ops/confusion_matrix.py` | ソース | 混同行列計算 |
| metric_serialization.py | `tensorflow/python/keras/saving/saved_model/metric_serialization.py` | ソース | メトリクスのSavedModel保存対応 |
