# -*- coding: utf-8 -*-
"""低評価(human_total_score < 60)の要注意サンプル一覧を生成する。"""
import os
import pandas as pd

BASE = r"C:\Users\NX023286.NEXYZ\Documents\開発しているもの\制作中\AIラーメン評価アルゴリズム分析"
FEATURES = os.path.join(BASE, "検証", "results", "downstream_model_comparison", "features.csv")
PREDS = os.path.join(BASE, "検証", "results", "downstream_model_comparison", "predictions.csv")
OUT_DIR = os.path.join(BASE, "精度改善_20260619", "03_low_score")
OUT = os.path.join(OUT_DIR, "low_score_under60.csv")

PREF_FEATURE_SET = "visual_plus_brix"
PREF_MODEL = "線形回帰"


def main():
    feats = pd.read_csv(FEATURES, encoding="utf-8-sig")
    preds = pd.read_csv(PREDS, encoding="utf-8-sig")

    total_n = len(feats)

    # --- total_score 予測誤差の取得 ---
    tp = preds[preds["target"] == "human_total_score"].copy()
    chosen_fs, chosen_model = PREF_FEATURE_SET, PREF_MODEL
    sub = tp[(tp["feature_set"] == PREF_FEATURE_SET) & (tp["model"] == PREF_MODEL)]
    if sub.empty:
        # 代表モデルへフォールバック
        chosen_fs = PREF_FEATURE_SET if PREF_FEATURE_SET in tp["feature_set"].unique() else tp["feature_set"].iloc[0]
        chosen_model = tp["model"].iloc[0]
        sub = tp[(tp["feature_set"] == chosen_fs) & (tp["model"] == chosen_model)]
    print(f"[info] 予測誤差結合: feature_set={chosen_fs}, model={chosen_model}, rows={len(sub)}")

    pred_map = sub[["sample_id", "prediction", "error"]].drop_duplicates("sample_id")
    pred_map = pred_map.rename(columns={"prediction": "total_pred", "error": "total_error"})

    # --- 低評価抽出 ---
    low = feats[feats["human_total_score"] < 60].copy()
    low["soup_under60"] = low["human_soup_score"] < 60

    low = low.merge(pred_map, on="sample_id", how="left")

    cols = [
        "sample_id", "video_path", "frame_path", "store", "slot",
        "human_total_score", "human_soup_score", "soup_under60",
        "total_pred", "total_error",
        "brix", "visual_density_num", "water_level", "oil_emulsification",
        "boiling_heat_state", "photo_quality", "image_condition_score",
        "assessable", "retake_recommended", "summary",
    ]
    for c in cols:
        if c not in low.columns:
            low[c] = pd.NA
    out = low[cols].copy()
    out["分類(通常/要注意/撮り直し推奨)"] = ""
    out["メモ"] = ""

    out = out.sort_values("human_total_score", ascending=True).reset_index(drop=True)

    os.makedirs(OUT_DIR, exist_ok=True)
    out.to_csv(OUT, index=False, encoding="utf-8-sig")

    # --- 統計サマリ ---
    n = len(out)
    s = out["human_total_score"]
    print(f"\n=== 統計サマリ ===")
    print(f"全件数: {total_n}")
    print(f"60点未満件数: {n} ({n/total_n*100:.1f}%)")
    print(f"human_total_score 分布: min={s.min()}, max={s.max()}, 平均={s.mean():.2f}")
    print(f"soup_under60 件数: {int(out['soup_under60'].sum())}")
    matched = out["total_error"].notna().sum()
    print(f"予測誤差結合済み: {matched}/{n}")
    if matched:
        e = out["total_error"].dropna()
        # error = prediction - actual と想定。過大評価 = 正の誤差
        print(f"total_error 平均: {e.mean():.2f}, 最大: {e.max():.2f}, 最小: {e.min():.2f}")
        over = e[e > 0]
        print(f"過大評価(error>0)件数: {len(over)}/{matched}, 過大評価分の平均: {over.mean() if len(over) else float('nan'):.2f}")
    print(f"\n出力: {OUT}")


if __name__ == "__main__":
    main()
