원시 지표(PBR, ROE 등)를 서로 다른 스케일로 바로 결합하면 특정 팩터가 과대 반영됩니다. Z-Score 정규화 → 백분위(Percentile) 변환이 표준입니다.
python
import pandas as pd
import numpy as np
def factor_score(raw: pd.Series, higher_is_better: bool = True) -> pd.Series:
"""Z-Score → [0, 1] 백분위 변환"""
z = (raw - raw.mean()) / raw.std()
pct = z.rank(pct=True) # 0~1 백분위
return pct if higher_is_better else (1 - pct)
# 가치 팩터: 낮은 PBR이 좋음
value_score = factor_score(df['pbr'], higher_is_better=False)
# 모멘텀 팩터: 높은 수익률이 좋음
mom_score = factor_score(df['mom_11m'], higher_is_better=True)이상값 처리
스코어링 전 Winsorizing(상하위 2.5% 클리핑)을 반드시 적용하세요. 부도 직전 종목의 극단적 PBR이 전체 점수 분포를 왜곡합니다.