49 lines
1.7 KiB
Python
49 lines
1.7 KiB
Python
"""blinded paired pairwise 집계 수학. 실질 arm 관점: pair 의 첫 arm = "first", 둘째 = "second".
|
|
forward orientation 은 X=첫 arm, reversed 는 X=둘째 arm(뒤집힘). 단순평균 금지 — 순위 기반."""
|
|
from collections import Counter
|
|
|
|
|
|
def normalize(orientation, winner):
|
|
"""judge 의 X/Y 승자를 실질 arm 관점(first/second)으로 정규화. tie 는 그대로 tie."""
|
|
if winner == "tie":
|
|
return "tie"
|
|
if orientation == "forward":
|
|
return "first" if winner == "X" else "second"
|
|
return "second" if winner == "X" else "first" # reversed: X=둘째 arm
|
|
|
|
|
|
def stable(fwd_real, rev_real):
|
|
"""두 orientation 이 같은 실질 승자를 판정하는가."""
|
|
return fwd_real == rev_real
|
|
|
|
|
|
def preference_score(wins, ties, valid_stable):
|
|
"""(wins + 0.5*ties) / valid_stable. arm 의 우호도."""
|
|
if valid_stable <= 0:
|
|
return 0.0
|
|
return (wins + 0.5 * ties) / valid_stable
|
|
|
|
|
|
def panel_agreement(stable_verdicts):
|
|
"""최빈 판정이 차지하는 비중. 0.0 if empty."""
|
|
if not stable_verdicts:
|
|
return 0.0
|
|
top = Counter(stable_verdicts).most_common(1)[0][1]
|
|
return top / len(stable_verdicts)
|
|
|
|
|
|
def flip_consistency(paired):
|
|
"""paired: [{fwd, rev}...] 각 실질 arm 관점. fwd==rev 면 flip 일관성 유지."""
|
|
if not paired:
|
|
return 0.0
|
|
ok = sum(1 for p in paired if p["fwd"] == p["rev"])
|
|
return ok / len(paired)
|
|
|
|
|
|
def panel_verdict(stable_verdicts):
|
|
"""panel 의 최종 판정. unstable = 투표 일관성 부족."""
|
|
if len(stable_verdicts) < 2:
|
|
return "unstable"
|
|
verdict, cnt = Counter(stable_verdicts).most_common(1)[0]
|
|
return verdict if cnt >= 2 else "unstable"
|