# 診断ロジック仕様 (Diagnosis Logic Specification)

診断結果は現行実装と一致させる．本仕様は現行コード（`org/src`）の解析結果を正とする．

## 処理パイプライン (Pipeline)

```text
ROI 平均 RGB → (1) 多項式変換で XYZ → (2) Lab 変換 → (3) SVM 分類 → 5 色スコア・上位 2 色
```

### (0) ROI 平均色

- クリック点ごとに 51×51 px の矩形 ROI の平均 BGR を算出
- 複数点クリック時は各 ROI 平均の平均（全クリックの合算 ÷ クリック数）を診断に使用

### (1) RGB → XYZ（多項式回帰）

変換行列 CSV の係数 `a[0..16], b[0..16], c[0..16]` を用い，R, G, B の 3 次までの多項式（17 項: 1 次 3 項 + 2 次クロス 3 項 + 2 乗 3 項 + 3 次 7 項 + 定数項）で X, Y, Z を計算する．負値は 0 にクリップする．

```text
X = a0*R + a1*G + a2*B
  + a3*R*G + a4*R*B + a5*G*B
  + a6*R^2 + a7*G^2 + a8*B^2
  + a9*R^2*B + a10*R^2*G + a11*G^2*R + a12*G^2*B + a13*B^2*R + a14*B^2*G
  + a15*R*G*B
  + a16
（Y, Z も係数 b, c で同形）
```

### (2) XYZ → L\*a\*b\*

白色点 Xn=102.07, Yn=100.0, Zn=79.41（固定）とし，立方根で算出する:

- L\* = 116 (Y/Yn)^(1/3) − 16
- a\* = 500 ((X/Xn)^(1/3) − (Y/Yn)^(1/3))
- b\* = 200 ((Y/Yn)^(1/3) − (Z/Zn)^(1/3))

※ CIE 標準の低輝度側条件分岐（t ≤ (6/29)³ のときの線形近似）は現行実装に無いため**意図的に実装しない**（結果同一性優先）．

### (3) SVM 分類

- 学習データ: `data.csv` の 84 サンプル（入力: L\*a\*b\* 3 次元，出力: 190 列 = 医師 38 名 × 5 色の 0/1 評価）
- 出力 190 列それぞれについて 2 クラス SVM を**診断のたびに学習**し，入力 Lab を予測する（正例が 2 未満の列は学習せずスコア 0）
- SVM パラメータ: C_SVC / RBF カーネル，γ=0.011，C=12.0，終了条件 EPS 1000 回・FLT_EPSILON
- 色ごとに 38 医師分の予測値を平均 → 5 色の一致率（0〜1）を百分率で表示する
- スコア降順で上位 2 色を主要ラベルとする

## 診断失敗の判定 (Failure Detection)

5 色スコア（% 整数）が特定の組（淡紅 11・紅 5・暗赤 0・紫 42・淡白 3）と完全一致した場合，現行実装は「Diagnosis failed」と表示する．

※ これは「学習不能時に SVM が返す既知の出力パターン」をマジックナンバーで検出する現行のワークアラウンド．新実装では**学習不能・予測失敗を直接検出**して失敗表示する（表示仕様は現行と同じ）．

## データファイル形式 (Data File Formats)

### 変換行列 CSV（ユーザーが診断時に選択）

- 17 行 × 3 列（ヘッダなし）．各行が `a[i], b[i], c[i]`（X, Y, Z 用係数）
- 撮影環境（カメラ・照明）ごとのキャリブレーション結果として作成されるファイル

### data.csv（学習データ．リポジトリの `data/` に同梱予定）

- 1 行目: ヘッダ（`L,a,b,紫,暗赤,紅,淡紅,淡白,…` の繰り返し）
- 2 行目以降: 84 サンプル．列 1〜3 が L\*a\*b\*，列 4〜193 が医師 38 名 × 5 色の 0/1（各医師 5 列の one-hot）
- ※ 実ファイルは 198 列（医師ブロック 39 個分）あるが，末尾の 39 番目のブロック 5 列は全サンプルで全 0 の未使用列である（有効な評価データは上記の 38 名分＝193 列）
- ※ 旧実装の読込列数は **193 列で確定**（ステップ 2 で `org/src` を確認済み: `EXP_OUTPUT_DIM = 190` = 38 名 × 5 色で，`CsvRead` は cols=193 で読み 194 列目以降にアクセスしない．ヘッダの「医師の数39」コメントは誤記）．新実装（`core/csv_io.py`）も先頭 193 列のみを読む
