콘텐츠로 이동

Source: report/version6/exp-expert/v6_baseline_reference.md

v6 Baseline Reference for v7 Smoke Sanity Review

⚠️ 의무 경고 (critic M3 대응, cycle 2/2 2026-04-19)

본 reference는 'Gate 판정 근거'로 사용 금지. smoke 해석 시 오직 "수치 규모 sanity (order-of-magnitude)"로만 참고할 것.

근거: - 표본은 N=1 seed (seed=42) 단일 run. IQR/분산/bootstrap 계산 원천 불가. - cycle 1 revision에서 제안한 ±5 tolerance 밴드는 통계 근거 부재로 본 cycle 2/2 에서 철회한다. - v7 smoke의 "합리성" 판정은 v7 내부 3-seed paired 분산으로만 수행. - smoke_analysis.py는 자동 footer로 본 경고를 verdict 보고서에 삽입한다.

허용된 참고 용도 (only): - "B0 Apt6 PAPE가 0 이나 100 이 나왔다면 파이프라인 이상" 수준의 trip-wire. - v7 B0 수치가 v6 수치의 0.3x ~ 3x 범위 밖이면 학습 파이프라인 재조사 트리거.

금지 용도: - ❌ "v7 B0가 44.8 ~ 54.8 범위 안이므로 smoke PASS 판정" (Gate 근거 금지) - ❌ "v6 대비 X% 개선" 의 CI 논증 (N=1 이므로 CI 불가) - ❌ smoke verdict의 bullet point로 본 수치를 열거

목적

v7 단계 0.5 smoke 결과의 수치 규모 sanity (order-of-magnitude trip-wire) 해석을 위한 reference. 단계 0.5 Gate 1~6 판정 (report/version7/exp-expert/v7_stage05_gate_criteria.md)과는 독립이며, Gate FAIL/PASS 직접 근거로는 사용 금지.

재계산 방법론

  • 공용 모듈: peak_analysis.v7.metrics (PAPE_v7, HR_v7, Q_PERCENTILE=90, HR_K=12)
  • v6 run이 metric 로깅 시점에 사용한 PAPE 정의는 v7 정의와 다를 수 있다. → v6 기록된 metric을 그대로 쓰지 않고, y_true/y_pred artifact를 로드해 v7 공용 함수로 재계산 한다.
  • Q90: 각 가구의 train+val split 90 percentile (v7 split, TRAIN=0.7 VAL=0.1) → v6 split과 동일하지는 않을 수 있으나 (train_ratio / val_ratio 설정이 v6에서도 동일했음을 확인: peak_analysis.community.load_apartment_hourly 공용 split 호출).

출처 Run 인벤토리

v6 MLflow 전수 탐색 결과, y_true / y_pred artifact를 보유한 run은 track-e-fl-baseline-bench의 단일 run뿐이다:

Experiment Run ID Run name Seed FL methods with y_pred
track-e-fl-baseline-bench a5e7b646fac042ca958eba827d1aa341 bench_R1_E5_b0_b1_fedrep_ditto_seed42 42 b0 (Local), b1 (FedAvg), fedrep, ditto

부재 데이터: - FedProx (B2 대응): v7 smoke 대상에 포함되지만 v6에서 y_pred 미보유. FedLearning-Phase2-fedprox run은 metric만 기록, artifact 없음. - FedPM (v6 proposed, A3 대응): FeDPM-Original-Phase3/3b 모두 y_pred 미보유. track-e-tier0 6 runs도 y_pred 미보유. - 추가 seed: 위 단일 run만 존재 → per-seed IQR 계산 불가 (N=1 sample).

v6 Baseline 수치 (v7 공용 metric 재계산)

Per-household PAPE (%) — seed=42 single run

Method Apt6 Apt15 Apt30 Apt51 Apt88 avg
B0 Local 49.809 46.611 34.153 25.044 42.486 39.621
B1 FedAvg 51.807 45.951 34.434 24.147 42.901 39.848
FedRep 49.766 45.594 34.049 25.270 43.212 39.578
Ditto 49.824 45.837 32.669 24.344 42.776 39.090

Per-household HR — seed=42 single run

Method Apt6 Apt15 Apt30 Apt51 Apt88 avg
B0 Local 0.723 0.579 0.580 0.613 0.634 0.626
B1 FedAvg 0.720 0.578 0.599 0.633 0.635 0.633
FedRep 0.717 0.583 0.597 0.610 0.636 0.629
Ditto 0.725 0.585 0.578 0.612 0.635 0.627

MSE / MAE — seed=42 single run (B0 Local만 상세, 나머지도 위 스크립트 재계산 가능)

Method Metric Apt6 Apt15 Apt30 Apt51 Apt88 avg
B0 Local MSE 0.7747 0.1564 0.0879 0.6248 0.9121 0.5112
B0 Local MAE 0.6167 0.2866 0.2241 0.5494 0.6874 0.4728
B1 FedAvg MSE 0.7870 0.1517 0.0838 0.5856 0.9249 0.5066
B1 FedAvg MAE 0.6249 0.2827 0.2193 0.5272 0.6889 0.4686
FedRep MSE 0.7791 0.1541 0.0855 0.6446 0.9167 0.5160
FedRep MAE 0.6228 0.2845 0.2223 0.5505 0.6902 0.4741
Ditto MSE 0.7744 0.1550 0.0884 0.6224 0.9113 0.5103
Ditto MAE 0.6162 0.2855 0.2251 0.5554 0.6863 0.4737

집계 통계

  • N=1 seed (seed=42) — IQR / min-max / bootstrap 계산 불가.
  • Cross-method range (avg PAPE): 39.09 ~ 39.85 (폭 0.76 percentage points).
  • Cross-household range (B0): 25.04 ~ 49.81 (폭 24.77 pp; Apt51 가장 낮음, Apt6/Apt88 가장 높음).

Trip-wire 용도 (v2 critic cycle 2 철회 후 재정의)

Gate 근거가 아닌, "파이프라인 자체가 고장났는지 여부"만 판단하는 극단 범위 트립와이어로만 사용. 좁은 tolerance 밴드는 모두 철회됨.

지표 v6 단일 seed 참고값 극단 Trip-wire (pipeline 오류 의심)
B0 Local PAPE Apt6 49.8 < 15 또는 > 150 → 파이프라인 조사
B0 Local PAPE Apt88 42.5 < 12 또는 > 130 → 파이프라인 조사
B0 Local HR avg 0.626 < 0.2 → 학습/평가 코드 점검
A3 proposed PAPE avg (v6 reference 없음) 절대값 비교 금지 — B0 대비 변화만 확인

주의: - 위 trip-wire는 "이 값 벗어나면 연구 중단/재실험 트리거"가 아니라 "exp-expert가 코드 점검을 해봐야 한다"의 의미. - Gate 판정은 smoke_analysis.py의 Gate 1~6 결과만 사용한다. - v7 내부 3-seed 분산이 있다면 그것이 유일한 공식 분산 근거.

Caveats (재사용 전 반드시 고지)

  • 표본 크기 제한: N=1 seed. 분산/편차 근거 없음. "거의 같다"는 주장 불가.
  • v6-v7 scaler space 미검증: v6 run에서 normalization을 v7과 동일하게 적용했는지 명시적 확인 못 함. scaler_space_v6 != scaler_space_v7일 가능성 있음. y_true/y_pred가 이미 inverse-transformed 상태로 저장된 것으로 보이나 (값의 크기 범위가 원시 kW-level로 해석되어), 재학습 없이는 엄격 보증 어렵다.
  • FedProx / FedPM reference 공백: v6 비교에서 B2 / A3 reference가 없다. v7 smoke에서 이들의 "합리성" 판정은 B0/B1 대비 상대 변화로만 가능.
  • Q90 재계산의 암묵적 가정: v7의 Q90은 load_household_split이 리턴하는 (train, val) 분포 기준. v6 run이 동일 split을 썼다고 가정한 상태. Q90 값 자체가 다르면 PAPE mask 시점이 달라져 절대값 비교 불공정해질 수 있음.
  • track-e-tier0 의 t0_codebook_seed42 (954ae57099): Apt6만, y_pred 없음 — avg PAPE param 기록은 있으나 (0.0~47 range의 scalar 단일값), 재계산 불가라 이 reference에서 배제.

재현 코드 스니펫

import numpy as np, mlflow
from mlflow.tracking import MlflowClient
from peak_analysis.v7.metrics import compute_pape_v7, compute_hr_v7, load_household_split, HR_K

client = MlflowClient()
run_id = "a5e7b646fac042ca958eba827d1aa341"
methods = ["b0", "b1", "fedrep", "ditto"]
hhs = ["Apt6", "Apt15", "Apt30", "Apt51", "Apt88"]
for method in methods:
    for hh in hhs:
        yt = np.load(client.download_artifacts(run_id, f"predictions/{method}_{hh}_y_true.npy")).squeeze(-1)
        yp = np.load(client.download_artifacts(run_id, f"predictions/{method}_{hh}_y_pred.npy")).squeeze(-1)
        _, _, _, q90 = load_household_split(hh, "2016")
        print(method, hh, compute_pape_v7(yt, yp, q90), compute_hr_v7(yt, yp, k=HR_K))

결론 (간단)

  • v7 smoke의 B0 Local 수치만이 v6 reference (a5e7b646, seed=42)와 직접 비교 가능. B2는 FedProx 부재 공백으로 FedAvg 기반 간접 비교, A3는 절대값 비교 공백 → 상대 개선 관점만.
  • 표본 N=1 seed 한계로 "CI / IQR" 논증은 이 reference만으로 불가. 단계 1(5-seed paired) 완료 후 v7 내부에서 IQR 재산정 필요.