# ラーメン豚山 スープAI評価 — 検証プロジェクト計画書

## 0. ゴール
2つの方式を**同一データ・同一評価基準で公平に比較**し、社長へ「どの方式でどれだけ精度が出るか／ボトルネックはどこか」を報告する。

- **Track A（BytePlus提案方式）**: VLM(Seed 2.0 Pro)で4軸採点 → XGBoost等で合成。提案の再現＋後段モデル比較。**API課金あり**。
- **Track B（Claude提案方式）**: **LLMを使わず OpenCVの画像処理**で状態特徴（色/濁り/油膜/水位/豚崩れ/撮影品質）を抽出 → 非対称Brix補正 → 後段モデル。**API課金ゼロ・ローカル計算・完全説明可能**。

> **重要な設計思想**: 両方式は前半（画像→特徴スコア化）と後半（特徴→最終スコア合成）に分解できる。
> **後半（common/compare_models.py）は完全共有**し、違うのは前半の「特徴の作り方」だけ。
> Track A=VLM、Track B=古典画像処理。これで「**VLM方式 vs 画像処理方式（コスト vs 精度）**」を公平に比較できる。

---

## 1. 役割分担（タッグ）
| 担当 | 内容 |
|---|---|
| **あなた（垣花さん）** | データ提供（Base export CSV・動画 or 画像ファイル）、APIキーの送付、現場知見の確認 |
| **Claude（私）** | フォルダ設計・前処理・VLM呼び出し・モデル学習/比較・評価・レポート作成 |

---

## 2. BytePlus提案の要点（MD精読より）
| 項目 | 内容 |
|---|---|
| 前段 | Seed 2.0 Pro(VLM)で **4軸**を各独立採点：濃度30 / 水位25 / 油25 / 沸騰20 |
| 各呼び出し | 動画(fps=1) + **高/中/低の参照アンカー3枚** + Brix + 時間帯 を渡す |
| 後段 | **XGBoost dual head**（回帰=スコア / 分類=要確認フラグ）、特徴12個 |
| 実績 | **ρ=0.53 / MAE=11.7 / グレード一致74% / 異常検知44% / $0.02・30秒/本** |
| データ | 938本・人間採点684本 → train474/val68/**test137**（test厳守） |
| 重要発見 | 最重要特徴は**Brix(18.2%)** ＝ ドメイン知識 > 単一視覚信号 |
| 不採用 | 色/肉片/泡(旧PDF軸)は人間評価と**逆相関ρ=-0.16**で破棄 |

### 私の見立て（提案の妥当性）
- **方向性は妥当**。Brixが最重要という発見は、私のデータ分析（Brix目標未満で強く減点）と一致。
- **論点1**: 「色は無意味(1.3%)」は*絶対色*の話。豚骨は元々白いので「白=低得点」は誤りだが、**濁りの均一性・油膜の分布**など*相対的な見た目*は依然有効なはず（私のTrack Bで検証）。
- **論点2**: fps=1が最適＝ほぼ静止画。**私の「静止画でよい」という方針と整合**。動画である必然性は薄い。
- **論点3**: XGBoostでρ0.45→0.53は改善だが、test137件と小さく**過学習リスク**。だから後段モデル比較（線形/Ridge/RF/XGB/LightGBM/固定配点）が重要。
- **注意（公平性）**: 私のv1で出した「MAE9.8」は*評価コメントを特徴に使った値*で、運用時には使えない（カンニング）。**本検証では人間コメントを特徴に使わない**。視覚＋Brix＋時間帯のみで勝負する。

---

## 3. フォルダ構成
```
AIラーメン評価アルゴリズム分析/
├── PLAN.md                     ← 本書
├── README.md                   ← セットアップ手順
├── docs/
│   └── byteplus_proposal.md    ← BytePlus提案原文
├── data/
│   ├── raw_csv/                ← Base export (base_export.csv 配置済)
│   ├── videos/                 ← 【要提供】動画ファイル
│   ├── frames/                 ← 動画から抽出した代表フレーム(自動生成)
│   ├── anchors/                ← 高/中/低の参照アンカー画像(自動選定)
│   └── splits/                 ← train/val/test 固定分割(再現用・seed固定)
├── common/                     ← 両Track共通基盤
│   ├── config.example.yaml     ← 設定テンプレ(キーは secrets/ 参照)
│   ├── data_loader.py          ← CSV読込・正規化・分割
│   ├── extract_frames.py       ← 動画→代表フレーム/アンカー抽出
│   ├── vlm_client.py           ← VLM呼び出し(provider切替)
│   └── metrics.py              ← ρ/MAE/グレード一致/異常検知 を統一計算
├── trackA_byteplus/            ← 4軸VLM採点 + 後段モデル比較
├── trackB_claude/              ← 静止画状態評価 + 非対称Brix(scoring_prototype.py)
├── secrets/                    ← APIキー(.gitignore対象・外部送信しない)
├── reports/                    ← 社長向け最終比較レポート
└── analysis_v1/                ← 初期分析(再現可能スクリプト一式)
```

---

## 4. 検証フェーズ（工程）

### フェーズ0: セットアップ（私）
- フォルダ・共通基盤・設定テンプレ作成（本コミットで実施）。
- Pythonライブラリ確認（pandas/scikit-learn/xgboost/lightgbm/opencv/requests等）。

### フェーズ1: データ準備（私 ← あなたがデータ提供）
1. Base export を読み込み・正規化（Brix・時間帯・人間スコア・動画ファイル名・既存pred_score）。
2. 動画 → **代表フレーム抽出**（fps=1相当の中央付近フレーム、Track Bは1枚、Track Aは数枚）。
3. **アンカー選定**：人間スコア高(95-100)/中(60前後)/低(0-20)の代表画像を自動抽出。
4. **train/val/test を 70/10/20 で層別分割・seed固定**（BytePlusと同条件＝結果が比較可能）。test は最後まで触らない。

### フェーズ2: VLMによる特徴スコア化（私）
- **Track A**: 4軸（濃度/水位/油/沸騰）をVLMで採点。アンカー3枚同梱・Brix/時間帯付与。
- **Track B**: 私の軸（乳化/色・濁り/表面油/水位/豚崩れ/撮影品質）をVLMで採点。
- 両方とも**同じVLM・同じ画像入力**で実施し、プロンプト(軸定義)だけ変える＝公平比較。
- 結果はキャッシュ（再実行コスト削減。1本あたりの課金を記録）。

### フェーズ3: 後段モデルの作成と比較（私）
共通ハーネスで以下を**同一trainで学習・同一testで評価**：
- 固定配点 / 線形回帰 / Ridge / Random Forest / XGBoost / LightGBM
- Track Bは加えて「**非対称Brix補正＋説明可能式**」（scoring_prototype系）。
- 各モデルで ρ・MAE・グレード一致・異常検知recall を算出。

### フェーズ4: 画質・湯気の影響確認（私）
- 撮影品質スコア（白飛び/暗さ/被写体被覆）で全データ vs 良品質のみ を比較。
- 「除外で精度が上がるか」を両Trackで測定 → 前処理ゲートの要否を判断。

### フェーズ5: 評価とボトルネック切り分け（私）
- BytePlus公表値（ρ0.53/MAE11.7/一致74%/recall44%）を**基準線**として並置。
- 判断ロジック（あなたの検証doc準拠）：
  - 特定モデルだけ高 → それを採用候補
  - 全モデル横並び → ML不要かも（固定配点/軽量モデル優先）
  - 全モデル低 → 前段（VLM4軸 or 軸設計 or 人間評価ばらつき）に課題 → 方式見直し
  - 画質除外で改善 → 前処理ゲート導入

### フェーズ6: 社長向けレポート（私）
- 2方式 × 全モデルの比較表、画質影響、コスト、推奨方針、次アクションを `reports/` に。
- 日本語・意思決定者向け。図表付き。

---

## 5. 評価指標（全Track共通・BytePlusと同一定義）
| 指標 | 定義 | 備考 |
|---|---|---|
| **ρ (相関)** | スピアマン順位相関 | BytePlus主指標(0.53) |
| **MAE** | 平均絶対誤差(0-100) | BytePlus 11.7 |
| **グレード一致率** | A/B/C/D の一致 | A:80-100 B:60-79 C:21-59 D:0-20 |
| **異常検知recall** | C+D を正しく拾えた率 | BytePlus 44%・理論上限~67% |
- **すべてtest137件相当（学習・調整に未使用）で報告**。リーク厳禁。

---

## 6. 【要提供】あなたにお願いするもの
1. **動画ファイル**（Base の `添付ファイル` 列名と対応するもの）。
   - 提供形態は要相談（後述の質問参照）。全687本が理想だが、まず**50〜100本**でも着手可。
2. **APIキー**（`secrets/` に置く。チャットに貼らず、ファイルで共有 or 安全な方法で）。
   - BytePlus（Seed 2.0 Pro / VeFaaS）アクセス情報 ※Track A再現用
   - 代替VLM（Claude / Gemini / OpenAI のいずれか）※Track B・クロスチェック用
3. **Base export の最新版**（既に `base_export.csv` 配置済。更新あれば差し替え）。
   - 旧グリッド10 export は `data/raw_csv/legacy_ai_request_grid_10.csv` に保管。

---

## 7. リスクと前提
- **test件数が小さい(137)**ため、モデル間の差はノイズの可能性。→ 交差検証も併用し過信しない。
- **人間評価のばらつき・評価者バイアス**（1評価者=1店舗で交絡）は両方式共通の上限要因。
- **コメントを特徴に使わない**（運用で得られないため）。v1のMAE9.8とは前提が違う点を社長報告で明記。
- VLM課金：687本×複数軸×モデル試行。キャッシュ＆段階実行でコスト管理。

---

## 8. 決定事項（2026-06-15 確定）
- **Track A = BytePlus Seed VLM**（提案方式の再現）。**Track B = OpenCVのみ（LLM不使用）** → API課金はTrack Aだけ。
- **後段モデルは共通**（固定配点/線形/Ridge/RF/XGBoost/LightGBM）。前半の特徴作りだけが両Trackの違い。
- **入力 = 動画(.MOV)**。動画から Track A=数フレーム / Track B=代表1枚＋品質指標 を自動抽出。動画は御社で用意。
- **着手規模 = まず50〜100本でE2E確認** → コスト/精度の当たりを掴んでから全686本。
- **費用 = Track Aのみ**。検証実費 約¥0.8万〜¥1.6万、稟議枠 **¥31,000（$200）** 推奨（reports/コスト試算.md）。

## 9. 次のアクション（直近）
- [x] 私：フォルダ・共通基盤（data_loader/metrics/extract_frames/vlm_client/compare_models）実装・動作確認
- [x] 私：Track A/B のプロンプト・採点スクリプト・モデル比較ハーネス実装（ダミーデータでE2E確認済）
- [ ] **あなた：動画 .MOV を 50〜100本**（data/videos/ に置ける形で共有）
- [ ] **あなた：BytePlus の ①APIキー ②エンドポイントURL ③Seedモデル名** を secrets/ 経由で共有
- [ ] 私：受領後、フレーム抽出 → アンカー選定 → VLM採点 → 6モデル比較 → 画質ablation → レポート
