一、定义
1.1 WOE(Weight of Evidence)定义与原理
WOE 是“Weight of Evidence”的缩写,直译为“证据权重”,用来衡量某个特征分箱中“坏人”与“好人”之间的分布差异性。
WOE 的基本定义如下:
W
O
E
i
=
ln
(
bad
i
/
total bad
good
i
/
total good
)
WOE_i = \ln \left( \frac{\text{bad}_i / \text{total bad}}{\text{good}_i / \text{total good}} \right)
WOEi=ln(goodi/total goodbadi/total bad)
其含义可以进一步展开为:
W O E i = ln ( bad i good i ) − ln ( total bad total good ) WOE_i = \ln \left( \frac{\text{bad}_i}{\text{good}_i} \right) - \ln \left( \frac{\text{total bad}}{\text{total good}} \right) WOEi=ln(goodibadi)−ln(total goodtotal bad)
即:每个分箱中的坏好比(Odds)相对于总体的坏好比之间的差异性。
换句话说,WOE 描述了每个分箱的观测结果相较于总体分布的“证据强度”差异。当 WOE 为正时,表示该分箱中坏人比重较大;为负时表示好人比重较大;接近 0 时说明该分箱与总体无明显差异。
1.2 IV(Information Value)定义与变换
IV 是“Information Value”的缩写,是在风控建模中用来度量特征对目标变量(如好/坏用户)预测能力的指标。
IV 的定义如下:
I
V
=
∑
i
=
1
n
(
bad_rate
i
−
good_rate
i
)
×
W
O
E
i
IV = \sum_{i=1}^{n} (\text{bad\_rate}_i - \text{good\_rate}_i) \times WOE_i
IV=i=1∑n(bad_ratei−good_ratei)×WOEi
其中:
- bad_rate i = bad i total bad \text{bad\_rate}_i = \frac{\text{bad}_i}{\text{total bad}} bad_ratei=total badbadi
-
good_rate
i
=
good
i
total good
\text{good\_rate}_i = \frac{\text{good}_i}{\text{total good}}
good_ratei=total goodgoodi
IV 本质上是 WOE 的加权和,其形式与信息论中的“相对熵”(KL散度)一致,表示总体坏好人分布在每个分箱上的差异程度。
IV 可以改写为:
I V = ∑ i = 1 n ( bad i total bad ) ln ( bad i / total bad good i / total good ) IV = \sum_{i=1}^{n} \left( \frac{\text{bad}_i}{\text{total bad}} \right) \ln \left( \frac{\text{bad}_i / \text{total bad}}{\text{good}_i / \text{total good}} \right) IV=i=1∑n(total badbadi)ln(goodi/total goodbadi/total bad)
这就将其与 WOE 的公式连接起来,进一步揭示了 IV 的信息含义:衡量每个分箱的坏人分布相对于好人分布的信息增益。分箱之间差异越大,IV 越高,说明该变量具有更强的区分能力。
二、计算步骤
-
分箱(Binning)
- 连续变量:等频、等距或基于业务自定义。
- 离散变量:合并稀疏类别。
-
统计分箱好坏数
- bin_good_i、bin_bad_i,及总体 good_total、bad_total。
-
计算边际占比
- d i s t _ g o o d i = b i n _ g o o d i / g o o d _ t o t a l dist\_good_i = bin\_good_i / good\_total dist_goodi=bin_goodi/good_total
- d i s t _ b a d i = b i n _ b a d i / b a d _ t o t a l dist\_bad_i = bin\_bad_i / bad\_total dist_badi=bin_badi/bad_total
-
计算 WOE
- W O E i = ln ( d i s t _ b a d i ) − ln ( d i s t _ g o o d i ) WOE_i = \ln(dist\_bad_i) - \ln(dist\_good_i) WOEi=ln(dist_badi)−ln(dist_goodi)
-
检查单调性与合并
- 若 WOE 曲线不单调,需调整分箱或合并相邻箱。
-
计算 IV
- I V = ∑ i ( d i s t _ b a d i − d i s t _ g o o d i ) × W O E i IV = \sum_i (dist\_bad_i - dist\_good_i) \times WOE_i IV=∑i(dist_badi−dist_goodi)×WOEi
-
跨集稳定性检验
- 在验证集/测试集上重复计算,确保单调性与IV值稳定。
三、公式来源与理论支撑
3.1 贝叶斯视角
从贝叶斯定理:
ln P ( Y = 1 ∣ X ) P ( Y = 0 ∣ X ) = ln P ( Y = 1 ) P ( Y = 0 ) + ln P ( X ∣ Y = 1 ) P ( X ∣ Y = 0 ) \ln\frac{P(Y=1 \mid X)}{P(Y=0 \mid X)} = \ln\frac{P(Y=1)}{P(Y=0)} + \ln\frac{P(X \mid Y=1)}{P(X \mid Y=0)} lnP(Y=0∣X)P(Y=1∣X)=lnP(Y=0)P(Y=1)+lnP(X∣Y=0)P(X∣Y=1)
- 先验项: ln P ( Y = 1 ) P ( Y = 0 ) \ln\frac{P(Y=1)}{P(Y=0)} lnP(Y=0)P(Y=1)
- 证据项(WOE):
ln
P
(
X
∣
Y
=
1
)
P
(
X
∣
Y
=
0
)
\ln\frac{P(X \mid Y=1)}{P(X \mid Y=0)}
lnP(X∣Y=0)P(X∣Y=1)
WOE 正是特征对先验 Odds 的信息增量。
3.2 信息论视角
IV 等价于两分布间的相对熵(KL 散度):
D
K
L
(
P
1
∥
P
0
)
=
∑
i
P
1
(
i
)
ln
P
1
(
i
)
P
0
(
i
)
D_{KL}(P_1 \parallel P_0) = \sum_i P_1(i) \ln \frac{P_1(i)}{P_0(i)}
DKL(P1∥P0)=i∑P1(i)lnP0(i)P1(i)
- 令 P 1 = P ( X ∣ Y = 1 ) P_1 = P(X\mid Y=1) P1=P(X∣Y=1), P 0 = P ( X ∣ Y = 0 ) P_0 = P(X\mid Y=0) P0=P(X∣Y=0),即可看出 IV 从信息量角度衡量分布差异。
四、与评分卡(Logistic 回归)的关系
- Logistic 回归模型:
ln P ( Y = 1 ∣ X ) P ( Y = 0 ∣ X ) = β 0 + ∑ j β j X j \ln\frac{P(Y=1\mid X)}{P(Y=0\mid X)} = \beta_0 + \sum_j \beta_j \, X_j lnP(Y=0∣X)P(Y=1∣X)=β0+j∑βjXj
- 若用 WOE 变量代替原始 X j X_j Xj,那么系数 β j \beta_j βj即衡量该分箱的证据权重与评分点的映射。
- 单调的 WOE 曲线可确保评分点随特征单调变化,提升可解释性与业务落地。
五、风控中的业务应用
- 缺失值与异常值:将 null 或极端值单独成箱,保证无信息丢失。
- 特征选择:利用 IV 快速筛除弱变量,降低维度。
- 稳健建模:WOE 变换后,对噪声与尺度敏感性弱,LR 收敛更快。
- 可解释报表:通过 WOE 曲线与 IV 分析,向业务部门展示变量效力。
六、Python 计算示例
import pandas as pd
import numpy as np
def compute_woe_iv(df, feature, target, bins=10):
# 分箱
df['bin'] = pd.qcut(df[feature], q=bins, duplicates='drop')
# 统计
grouped = df.groupby('bin')[target].agg(['count', 'sum'])
grouped.columns = ['total', 'bad']
grouped['good'] = grouped['total'] - grouped['bad']
# 总体
total_bad = grouped['bad'].sum()
total_good = grouped['good'].sum()
# 边际分布
grouped['dist_bad'] = grouped['bad'] / total_bad
grouped['dist_good'] = grouped['good'] / total_good
# WOE 与 IV
grouped['woe'] = np.log(grouped['dist_bad'] / grouped['dist_good'])
grouped['iv'] = (grouped['dist_bad'] - grouped['dist_good']) * grouped['woe']
# 返回
iv_value = grouped['iv'].sum()
return grouped[['total','bad','good','dist_bad','dist_good','woe','iv']], iv_value
# 示例用法
df = pd.read_csv('data.csv')
woe_table, iv = compute_woe_iv(df, feature='age', target='is_bad', bins=5)
print(woe_table)
print(f"IV = {iv:.4f}")