Tae Hyun Kim (Lowell)

Policy Trees

3분 읽기 #decision-making#ope#causal-forest

정의

**정책 트리(policy tree)**는 Athey & Wager (2021)가 제안한 해석 가능한 정책 학습(policy learning) 방법이다. 개인 수준의 처치효과(treatment effect) 추정값(estimate)을 입력으로 받아, 결정 트리 형태의 명시적 정책 규칙을 학습한다.

π(x)=argmaxaE[Y(a)X=x]\pi^*(x) = \arg\max_a E[Y(a) | X = x]

규칙을 트리로 표현하므로 “왜 이 고객에게 이 행동을 취하는가?”를 설명할 수 있다.

직관적 이해

Causal Forest는 개인별 효과를 추정하지만 그 결과는 “블랙박스”다.

반면 정책 트리는 “소득이 5만 이상이고 충성도가 0.7 이상이면 고가격 티어, 그렇지 않고 나이가 30 미만이면 저가격 티어”처럼 명시적 규칙을 내놓는다.

그래서 비즈니스 이해관계자에게 설명하기 쉽고, 규제 준수를 검증하기도 쉽다.

핵심 성질

Causal Forest와의 관계

  1. Causal Forest: τ^(x)\hat{\tau}(x) 추정 (개인별 효과)
  2. Policy Tree: τ^(x)\hat{\tau}(x)를 기반으로 π(x)\pi(x) 학습 (정책 규칙)

목적 함수

정책 트리는 정책 가치(policy value)를 최대화한다.

V(π)=E[τ(X)1[π(X)=1]]V(\pi) = E[\tau(X) \cdot \mathbf{1}[\pi(X) = 1]]

  • 긍정적 효과가 있는 사람에게는 처치를 주고
  • 부정적 효과가 있는 사람에게는 처치를 주지 않는다

해석 가능성 vs 성능 트레이드오프

방법해석 가능성성능
Policy Tree (depth=2)매우 높음중간
Policy Tree (depth=5)중간높음
Causal Forest 직접 사용낮음매우 높음

예시

EconML 구현

from econml.policy import PolicyTree
from econml.dml import CausalForestDML

# Step 1: CATE 추정
forest = CausalForestDML(
    model_y=GradientBoostingRegressor(),
    model_t=GradientBoostingRegressor(),
    n_estimators=500
)
forest.fit(Y, T, X=X, W=W)

# CATE 추정치
cate_estimates = forest.effect(X)

# Step 2: Policy Tree 학습
policy_tree = PolicyTree(
    max_depth=3,           # 깊이 제한 → 해석 가능성
    min_samples_leaf=100   # 최소 리프 크기
)
policy_tree.fit(X, cate_estimates)

# 정책 규칙 출력
print(policy_tree.export_text(feature_names=X.columns.tolist()))

출력 예시:

|--- income <= 50000.00
|   |--- age <= 30.00
|   |   |--- class: low_price
|   |--- age > 30.00
|   |   |--- class: medium_price
|--- income > 50000.00
|   |--- loyalty <= 0.70
|   |   |--- class: medium_price
|   |--- loyalty > 0.70
|   |   |--- class: high_price

다중 가격 수준 정책

from econml.policy import PolicyTree

# 여러 가격 수준에 대한 효과 추정
price_levels = [10, 15, 20, 25, 30]
effects = {}

for price in price_levels:
    # 이진화된 처리로 각 가격 효과 추정
    T_binary = (T == price).astype(int)
    model = CausalForestDML(...)
    model.fit(Y, T_binary, X=X, W=W)
    effects[price] = model.effect(X)

# 각 개인에게 최적 가격 결정
best_prices = pd.DataFrame(effects).idxmax(axis=1)

# Policy Tree로 규칙 학습
policy_tree = PolicyTree(max_depth=3)
policy_tree.fit(X, best_prices)

정책 평가

def evaluate_policy(policy_tree, X, Y, T, true_effects):
    """
    학습된 정책의 가치 평가
    """
    # 정책 예측
    recommended_treatment = policy_tree.predict(X)

    # 정책을 따랐을 때의 기대 이익
    # (실제로는 counterfactual이므로 AIPW 등 사용)
    policy_value = np.mean(true_effects[recommended_treatment == 1])

    # 무작위 정책 대비 개선
    random_value = np.mean(true_effects) * 0.5  # 50% 처리
    lift = (policy_value - random_value) / abs(random_value)

    return {
        'policy_value': policy_value,
        'random_value': random_value,
        'lift': lift
    }

시각화

from sklearn.tree import plot_tree
import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(20, 10))
plot_tree(
    policy_tree.tree_,
    feature_names=X.columns.tolist(),
    class_names=['No Treatment', 'Treatment'],
    filled=True,
    rounded=True,
    fontsize=10,
    ax=ax
)
plt.title('Pricing Policy Tree')
plt.tight_layout()
plt.savefig('policy_tree.png', dpi=150)

관련 개념

참고 문헌

  • Athey, S., & Wager, S. (2021). “Policy Learning with Observational Data.”
  • Zhou, Z., Athey, S., & Wager, S. (2023). “Offline Multi-Action Policy Learning.”
  • Comprehensive Personalized Pricing Guide, Part IX, §26.1

연결 그래프