2. 模型收益基础:量化指标与收益曲线

在风控模型的生命周期中,收益是衡量模型商业价值的最终标尺。阈值漂移直接导致收益衰退,因此必须先建立一套统一的收益量化语言。本节将系统讲解四个核心量化指标(AUC、KS、Lift、利润曲线)以及收益曲线的绘制方法。

2.1 核心量化指标矩阵

下表从区分能力、排序能力、提升倍数和实际利润四个维度,对比四个指标的本质与适用场景:

指标 衡量维度 取值范围 对阈值漂移的敏感度 业务含义
AUC 全局排序能力 [0.5, 1.0] 低(整体排序不变则稳定) 随机抽取正样本得分高于负样本的概率
KS 最大区分差距 [0, 1] 中(阈值移动时最大差距点可能偏移) 模型在某个分数段上区分好坏样本的最大能力
Lift 提升倍数 [1, +∞) 高(阈值变化直接影响通过率与坏账率) 模型筛选后坏账率相比随机筛选的降低倍数
利润曲线 实际净利润 (-∞, +∞) 极高(直接反映阈值变动对利润的影响) 在给定阈值下,扣除坏账损失后的净收益
实践要点: AUC 和 KS 是模型技术性能指标,Lift 和利润曲线是业务收益指标。阈值漂移对后者的冲击远大于前者——即使 AUC 保持不变,利润也可能腰斩。

2.2 指标详解与计算逻辑

2.2.1 AUC(Area Under the ROC Curve)

AUC 通过 ROC 曲线下的面积衡量模型对正负样本的全局排序能力。计算时,将所有样本按预测分数排序,统计正样本排在负样本之前的比例。

# AUC 的简化计算逻辑(Python 伪代码)
def auc_simple(y_true, y_score):
    # 按分数降序排列
    order = np.argsort(-y_score)
    y_true_sorted = y_true[order]
    pos_count = np.sum(y_true_sorted)
    neg_count = len(y_true_sorted) - pos_count
    # 计算所有正样本的秩和
    rank_sum = np.sum(np.where(y_true_sorted == 1)[0] + 1)
    # 计算 AUC
    auc = (rank_sum - pos_count * (pos_count + 1) / 2) / (pos_count * neg_count)
    return auc

2.2.2 KS(Kolmogorov-Smirnov)

KS 统计量是累积好样本率与累积坏样本率之间的最大差值。KS 值越高,模型在某个分数段上的区分能力越强。

# KS 计算逻辑
def ks_statistic(y_true, y_score):
    df = pd.DataFrame({'score': y_score, 'label': y_true})
    df = df.sort_values('score', ascending=False)
    df['cum_bad'] = df['label'].cumsum() / df['label'].sum()
    df['cum_good'] = (1 - df['label']).cumsum() / (1 - df['label']).sum()
    ks = np.max(np.abs(df['cum_bad'] - df['cum_good']))
    return ks

2.2.3 Lift(提升系数)

Lift 表示模型筛选后的坏账率相对于随机筛选的改善倍数。通常按分数从高到低分箱计算,Lift 越高说明模型在拒绝高风险样本方面越有效。

# Lift 计算(按分箱)
def lift_by_bin(y_true, y_score, bins=10):
    df = pd.DataFrame({'score': y_score, 'label': y_true})
    df['bin'] = pd.qcut(df['score'], bins, labels=False, duplicates='drop')
    bin_stats = df.groupby('bin').agg(
        total=('label', 'count'),
        bad=('label', 'sum')
    )
    bin_stats['bad_rate'] = bin_stats['bad'] / bin_stats['total']
    overall_bad_rate = df['label'].mean()
    bin_stats['lift'] = bin_stats['bad_rate'] / overall_bad_rate
    return bin_stats

2.2.4 利润曲线(Profit Curve)

利润曲线将模型输出直接映射为商业利润。核心公式为:

# 利润计算函数
def profit_at_threshold(y_true, y_score, threshold,
                        loan_amount=10000, interest_rate=0.15,
                        loss_rate=0.6, cost_rate=0.02):
    # 预测通过
    approved = y_score >= threshold
    # 通过客户数
    n_approved = np.sum(approved)
    # 坏账客户数
    n_bad_approved = np.sum(y_true[approved] == 1)
    # 利息收入
    interest_income = n_approved * loan_amount * interest_rate
    # 坏账损失
    bad_loss = n_bad_approved * loan_amount * loss_rate
    # 运营成本
    operation_cost = n_approved * loan_amount * cost_rate
    # 净利润
    profit = interest_income - bad_loss - operation_cost
    return profit

2.3 收益曲线的绘制方法

收益曲线是阈值决策的可视化工具。通过遍历所有可能的阈值,计算每个阈值下的利润,绘制出阈值-利润曲线,从而找到最优决策点。

绘制步骤:
  1. 排序:将样本按模型预测分数从高到低排序。
  2. 遍历阈值:以每个样本的分数作为候选阈值,计算通过率、坏账率。
  3. 计算利润:代入利润公式,得到每个阈值下的净利润。
  4. 绘制曲线:横轴为阈值(或通过率),纵轴为净利润,连接各点。
  5. 标注最优阈值:曲线最高点对应的阈值即为当前利润最大化阈值。

下面是一个完整的收益曲线绘制示例(Python):

import numpy as np
import matplotlib.pyplot as plt

def plot_profit_curve(y_true, y_score, loan_amount=10000,
                      interest_rate=0.15, loss_rate=0.6, cost_rate=0.02):
    # 按分数降序排列
    order = np.argsort(-y_score)
    y_true_sorted = y_true[order]
    y_score_sorted = y_score[order]

    thresholds = y_score_sorted
    profits = []

    for thresh in thresholds:
        approved = y_score_sorted >= thresh
        n_approved = np.sum(approved)
        n_bad = np.sum(y_true_sorted[approved] == 1)

        interest = n_approved * loan_amount * interest_rate
        loss = n_bad * loan_amount * loss_rate
        cost = n_approved * loan_amount * cost_rate
        profit = interest - loss - cost
        profits.append(profit)

    # 找到最优阈值
    best_idx = np.argmax(profits)
    best_thresh = thresholds[best_idx]
    best_profit = profits[best_idx]

    plt.figure(figsize=(10, 6))
    plt.plot(thresholds, profits, 'b-', linewidth=2)
    plt.axvline(x=best_thresh, color='r', linestyle='--',
                label=f'最优阈值: {best_thresh:.4f}')
    plt.scatter([best_thresh], [best_profit], color='red', s=100, zorder=5)
    plt.xlabel('阈值 (Threshold)')
    plt.ylabel('净利润 (Profit)')
    plt.title('阈值-利润曲线')
    plt.legend()
    plt.grid(True, alpha=0.3)
    plt.tight_layout()
    return best_thresh, best_profit

2.4 收益曲线与指标联动分析

下图展示了四个指标在阈值变化时的联动关系,帮助理解阈值漂移如何传导至收益衰退:

阈值漂移与收益指标联动关系图 阈值漂移 通过率变化 坏账率变化 客群结构偏移 AUC / KS 波动 Lift 下降 利润曲线偏移 模型收益衰退 说明:阈值漂移通过通过率、坏账率和客群结构三个渠道传导,最终导致利润曲线整体下移,即收益衰退。

2.5 收益曲线在阈值漂移监控中的应用

在实际风控系统中,收益曲线不仅是静态优化工具,更是动态监控仪表盘的核心组件。建议按以下频率更新:

  • 日频:监控实时利润曲线,对比当日与昨日最优阈值位置。
  • 周频:计算 Lift 分箱变化,识别客群质量是否发生结构性偏移。
  • 月频:重新计算 AUC/KS,评估模型整体区分能力是否衰退。
  • 季度频:结合外部经济指标,校准利润曲线中的损失率参数。
常见误区:很多团队只关注 AUC 和 KS,认为这两个指标稳定模型就安全。但阈值漂移往往先通过 Lift 和利润曲线暴露问题——当利润曲线最高点向左或向右移动超过 5% 时,即使 AUC 不变,也应立即启动阈值校准流程。