4. 策略效果量化工具:Python/Pandas/Sklearn 实现指标计算,自定义评估函数

在风控策略的 Champion/Challenger 测试中,量化指标是判断策略优劣的唯一标准。本章将聚焦于如何使用 Python 生态中的 Pandas 与 Scikit-learn(Sklearn)库,高效计算核心风控指标,并构建可复用的自定义评估函数,为后续的 Champion 选择提供数据支撑。

4.1 核心风控指标的计算逻辑

风控策略的效果通常从 区分度、稳定性 和 业务收益 三个维度衡量。下表列出了最常用的量化指标及其计算方式:

指标类别 指标名称 计算公式 / 说明 评估方向
区分度 KS (Kolmogorov-Smirnov) max(TPR - FPR),衡量好坏样本累计分布的最大差异 越高越好(通常 >0.3 为有效)
区分度 Gini 系数 2 * AUC - 1,衡量模型排序能力 越高越好(通常 >0.6 为有效)
区分度 IV (Information Value) ∑( (坏占比 - 好占比) * ln(坏占比/好占比) ) 越高越好(>0.3 为强预测力)
稳定性 PSI (Population Stability Index) ∑( (实际占比 - 预期占比) * ln(实际占比/预期占比) ) 越低越好(<0.1 为稳定)
业务收益 通过率 (Pass Rate) 通过订单数 / 总申请订单数 结合坏账率综合评估
业务收益 坏账率 (Bad Rate) 逾期订单数 / 通过订单数 越低越好
实战提示:在 Champion 选择中,KS 和通过率通常是首要权衡指标。一个策略如果 KS 很高但通过率极低,可能意味着过度拒绝,导致业务规模萎缩。

4.2 使用 Pandas 进行指标计算

Pandas 是数据清洗与聚合的核心工具。以下代码演示如何基于策略评分结果,快速计算通过率与坏账率:

import pandas as pd

# 假设 df 包含策略评分、实际标签和通过状态
df = pd.DataFrame({
    'score': [0.1, 0.4, 0.7, 0.9, 0.3, 0.8],
    'is_bad': [1, 0, 0, 1, 1, 0],  # 1=坏客户
    'is_approved': [0, 1, 1, 0, 0, 1]  # 1=通过
})

# 计算通过率
pass_rate = df['is_approved'].mean()
print(f"通过率: {pass_rate:.2%}")

# 计算坏账率(仅针对通过客户)
approved_df = df[df['is_approved'] == 1]
bad_rate = approved_df['is_bad'].mean()
print(f"坏账率: {bad_rate:.2%}")

# 按评分分箱计算坏账率
df['score_bin'] = pd.cut(df['score'], bins=5, labels=['极低','低','中','高','极高'])
bin_stats = df.groupby('score_bin').agg(
    申请量=('is_approved', 'count'),
    通过率=('is_approved', 'mean'),
    坏账率=('is_bad', lambda x: x[df.loc[x.index, 'is_approved']==1].mean())
)
print(bin_stats)

4.3 使用 Sklearn 计算区分度指标

Scikit-learn 提供了成熟的分类评估工具,可直接用于计算 KS 和 AUC:

from sklearn.metrics import roc_auc_score, roc_curve
import numpy as np

# 真实标签与策略评分
y_true = [1, 0, 0, 1, 1, 0]
y_score = [0.1, 0.4, 0.7, 0.9, 0.3, 0.8]

# 计算 AUC
auc = roc_auc_score(y_true, y_score)
print(f"AUC: {auc:.4f}")

# 计算 KS
fpr, tpr, thresholds = roc_curve(y_true, y_score)
ks = max(tpr - fpr)
print(f"KS: {ks:.4f}")

# 计算 Gini 系数
gini = 2 * auc - 1
print(f"Gini: {gini:.4f}")
注意:Sklearn 的 roc_curve 默认使用概率或决策函数作为输入。如果策略输出的是拒绝/通过标签(0/1),则无法直接计算 KS,需要先转换为连续评分。

4.4 自定义评估函数:一键量化策略

为了在 Champion 测试中快速对比多个策略,建议封装一个统一的评估函数。该函数接收评分、标签和通过状态,返回所有核心指标:

def evaluate_strategy(y_true, y_score, y_approved):
    """
    风控策略效果量化评估函数
    
    参数:
        y_true: 真实标签 (0=好, 1=坏)
        y_score: 策略评分 (连续值,越高风险越大)
        y_approved: 是否通过 (0=拒绝, 1=通过)
    
    返回:
        dict: 包含所有核心指标的字典
    """
    from sklearn.metrics import roc_auc_score, roc_curve
    
    # 区分度指标
    auc = roc_auc_score(y_true, y_score)
    fpr, tpr, _ = roc_curve(y_true, y_score)
    ks = max(tpr - fpr)
    gini = 2 * auc - 1
    
    # 业务指标
    pass_rate = np.mean(y_approved)
    approved_mask = y_approved == 1
    bad_rate = np.mean(y_true[approved_mask]) if approved_mask.sum() > 0 else 0
    
    return {
        'AUC': round(auc, 4),
        'KS': round(ks, 4),
        'Gini': round(gini, 4),
        '通过率': round(pass_rate, 4),
        '坏账率': round(bad_rate, 4)
    }

# 使用示例
result = evaluate_strategy(y_true, y_score, [0,1,1,0,0,1])
print(result)

4.5 策略评估流程架构

下图展示了从原始数据到最终指标输出的完整量化流程:

策略效果量化流程架构 原始数据 策略评分 Pandas 聚合 Sklearn 计算 业务指标 区分度指标 综合评估报告

4.6 实战:批量对比 Champion 策略

在实际工作中,我们通常需要同时评估多个策略版本。以下代码演示如何批量计算并生成对比表格:

# 模拟三个策略的评分数据
strategies = {
    'Champion': [0.2, 0.5, 0.6, 0.8, 0.4, 0.7],
    'Challenger_A': [0.3, 0.4, 0.7, 0.9, 0.5, 0.8],
    'Challenger_B': [0.1, 0.6, 0.5, 0.7, 0.3, 0.6]
}

y_true = [1, 0, 0, 1, 1, 0]
y_approved = [0, 1, 1, 0, 0, 1]

results = []
for name, scores in strategies.items():
    metrics = evaluate_strategy(y_true, scores, y_approved)
    metrics['策略名称'] = name
    results.append(metrics)

# 生成对比 DataFrame
comparison_df = pd.DataFrame(results).set_index('策略名称')
print(comparison_df)
输出示例:
              AUC     KS    Gini   通过率   坏账率
策略名称                                        
Champion     0.7500  0.5000  0.5000  0.5000  0.3333
Challenger_A  0.8333  0.6667  0.6667  0.5000  0.3333
Challenger_B  0.6667  0.3333  0.3333  0.5000  0.3333