Skip to main content

智能风控:Python 金融风险管理与评分卡建模 - 梅子行/毛鑫宇

<Img src="https://cosmos-x.oss-cn-hangzhou.aliyuncs.com/s33648744.jpg" alt="s33648744" width=300 />

本书基于 Python 讲解了信用风险管理和评分卡建模,从风险业务、统计分析方法、机器学习模型 3 个维度展开,详细讲解了信用风险量化相关的数据分析与建模手段。

关于作者

梅子行/毛鑫宇 是金融科技风控领域专家:

  • 风控从业者:在金融机构从事风险管理工作多年
  • 技术实践者:专注于机器学习在风控领域的应用
  • 知识分享者:在知乎、GitHub 等平台分享风控技术文章
  • 开源贡献者:参与风控相关开源项目开发

作者团队以其"实战导向、代码驱动"的写作风格著称,他们将信贷风控的实战经验与 Python 技术相结合,提供了大量可落地的代码和案例。

经典摘录

风控的核心不是拒绝风险,而是识别、定价和管理风险。

评分卡是将用户特征转化为信用分数的数学模型。

好的风控模型是在准确率和稳定性之间找到平衡。

特征工程的质量决定了模型效果的上限。

风控模型不仅要预测准确,还要可解释、可追溯。

数据是风控的燃料,算法是风控的引擎。

风控是金融业务的生命线。

核心内容

1. 信用风险管理基础

信用风险概述

1. 信用风险定义
- 借款人违约导致损失的风险
- 金融机构面临的主要风险
- 巴塞尔协议核心关注点

2. 风险类型

违约风险 (Default Risk):
- 借款人无法按时还款
- 最直接的信用风险

敞口风险 (Exposure Risk):
- 风险暴露的大小
- 贷款金额、剩余期限

回收风险 (Recovery Risk):
- 违约后能收回多少
- 抵押物、追偿能力

3. 风险管理流程

贷前:
- 反欺诈
- 信用评估
- 授信审批
- 定额定价

贷中:
- 放款审核
- 用信监控
- 行为评分

贷后:
- 还款监控
- 逾期管理
- 催收
- 资产处置

4. 关键指标

不良率 (NPL Ratio):
- 不良贷款/总贷款
- 衡量资产质量

逾期率 (Delinquency Rate):
- 逾期贷款/总贷款
- 早期预警指标

核销率 (Charge-off Rate):
- 核销金额/平均贷款余额
- 实际损失

回收率 (Recovery Rate):
- 收回金额/违约金额
- 催收效果

2. 评分卡模型

评分卡类型

1. 申请评分卡 (A 卡)

用途:
- 贷前审批
- 新客户信用评估
- 决定是否放款

数据源:
- 申请表信息
- 征信报告
- 外部数据

特点:
- 样本量大
- 特征稳定
- 要求高准确率

2. 行为评分卡 (B 卡)

用途:
- 贷中管理
- 存量客户评估
- 提额、定价依据

数据源:
- 还款历史
- 用信行为
- 账户变动

特点:
- 数据丰富
- 时效性强
- 可频繁更新

3. 催收评分卡 (C 卡)

用途:
- 贷后管理
- 逾期客户评估
- 催收策略制定

数据源:
- 逾期信息
- 催收记录
- 还款承诺

特点:
- 针对逾期客户
- 预测还款概率
- 优化催收资源

4. 反欺诈评分卡 (F 卡)

用途:
- 识别欺诈申请
- 第一道防线
- 拒绝明显欺诈

数据源:
- 设备指纹
- 行为数据
- 黑名单
- 关联网络

特点:
- 实时性要求高
- 规则 + 模型
- 宁错杀不放过

3. 特征工程

特征处理流程

1. 数据探索

缺失值分析:
```python
import pandas as pd
import numpy as np

# 缺失值统计
missing = df.isnull().sum()
missing_ratio = df.isnull().sum() / len(df)

# 缺失值可视化
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 6))
missing_ratio.sort_values(ascending=False).head(20).plot.bar()
plt.title('Top 20 Features with Missing Values')
plt.ylabel('Missing Ratio')

异常值检测:

# 箱线图检测异常值
plt.boxplot(df['amount'])

# 3σ原则
mean = df['amount'].mean()
std = df['amount'].std()
outliers = df[(df['amount'] \< mean - 3*std) |
(df['amount'] > mean + 3*std)]
  1. 特征选择

    过滤法:

    from sklearn.feature_selection import VarianceThreshold

    # 低方差过滤
    vt = VarianceThreshold(threshold=0.01)
    X_filtered = vt.fit_transform(X)

    # 相关系数过滤
    corr_matrix = df.corr()
    # 删除高相关特征

    包装法:

    from sklearn.feature_selection import RFE
    from sklearn.linear_model import LogisticRegression

    # 递归特征消除
    model = LogisticRegression()
    rfe = RFE(estimator=model, n_features_to_select=10)
    rfe.fit(X, y)

    嵌入法:

    from sklearn.ensemble import RandomForestClassifier

    # 特征重要性
    rf = RandomForestClassifier()
    rf.fit(X, y)
    importances = rf.feature_importances_
  2. 特征转换

    分箱 (Binning):

    # 等宽分箱
    df['age_bin'] = pd.cut(df['age'], bins=5)

    # 等频分箱
    df['income_bin'] = pd.qcut(df['income'], q=5)

    # 自定义分箱
    bins = [0, 18, 25, 35, 45, 55, 60, 100]
    labels = ['\<18', '18-25', '25-35', '35-45', '45-55', '55-60', '60+']
    df['age_bin'] = pd.cut(df['age'], bins=bins, labels=labels)

    编码:

    # Label Encoding
    from sklearn.preprocessing import LabelEncoder
    le = LabelEncoder()
    df['city_encoded'] = le.fit_transform(df['city'])

    # One-Hot Encoding
    df = pd.get_dummies(df, columns=['city'])
  3. WOE 编码

    定义:

    def calculate_woe(df, feature, target):
    """计算特征的 WOE 值"""
    grouped = df.groupby(feature)[target].agg(['sum', 'count'])
    grouped['good'] = grouped['count'] - grouped['sum']

    total_bad = df[target].sum()
    total_good = len(df) - total_bad

    grouped['bad_dist'] = grouped['sum'] / total_bad
    grouped['good_dist'] = grouped['good'] / total_good

    # WOE = ln(good_dist / bad_dist)
    grouped['woe'] = np.log(grouped['good_dist'] / grouped['bad_dist'])

    return grouped['woe'].to_dict()

### 4. 模型评估指标

评估指标体系

  1. 混淆矩阵

    from sklearn.metrics import confusion_matrix

    # 混淆矩阵
    cm = confusion_matrix(y_true, y_pred)

    # 可视化
    import seaborn as sns
    sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')
  2. 基础指标

    准确率 (Accuracy):

    from sklearn.metrics import accuracy_score
    accuracy = accuracy_score(y_true, y_pred)

    精确率 (Precision):

    from sklearn.metrics import precision_score
    precision = precision_score(y_true, y_pred)
    # 预测为坏客户中,真正的坏客户比例

    召回率 (Recall):

    from sklearn.metrics import recall_score
    recall = recall_score(y_true, y_pred)
    # 真正的坏客户中,被预测出来的比例

    F1 分数:

    from sklearn.metrics import f1_score
    f1 = f1_score(y_true, y_pred)
    # 精确率和召回率的调和平均
  3. KS 统计量

    定义:

    def calculate_ks(y_true, y_score):
    """计算 KS 统计量"""
    from sklearn.metrics import roc_curve
    fpr, tpr, thresholds = roc_curve(y_true, y_score)
    ks = max(tpr - fpr)
    return ks

    解读:

    • KS < 0.2: 模型效果差
    • 0.2 <= KS < 0.3: 一般
    • 0.3 <= KS < 0.4: 良好
    • KS >= 0.4: 优秀
  4. AUC-ROC 曲线

    from sklearn.metrics import roc_curve, auc
    import matplotlib.pyplot as plt

    fpr, tpr, thresholds = roc_curve(y_true, y_score)
    roc_auc = auc(fpr, tpr)

    plt.figure(figsize=(8, 6))
    plt.plot(fpr, tpr, label=f'AUC = {roc_auc:.3f}')
    plt.plot([0, 1], [0, 1], 'k--')
    plt.xlabel('False Positive Rate')
    plt.ylabel('True Positive Rate')
    plt.title('ROC Curve')
    plt.legend()
  5. PSI 稳定性指标

    def calculate_psi(expected, actual):
    """计算 PSI (Population Stability Index)"""
    def get_bins(data):
    return np.histogram(data, bins=10, density=True)[0]

    expected_dist = get_bins(expected)
    actual_dist = get_bins(actual)

    psi = np.sum((actual_dist - expected_dist) *
    np.log(actual_dist / expected_dist))
    return psi

    解读:

    • PSI < 0.1: 稳定
    • 0.1 <= PSI < 0.25: 轻微变化
    • PSI >= 0.25: 显著变化

5. 机器学习模型

常用风控模型

  1. 逻辑回归 (Logistic Regression)

    优点:

    • 可解释性强
    • 输出概率
    • 评分卡基础
    from sklearn.linear_model import LogisticRegression

    model = LogisticRegression(
    C=1.0,
    penalty='l2',
    class_weight='balanced',
    max_iter=1000
    )
    model.fit(X_train, y_train)

    # 特征系数
    coef = pd.DataFrame({
    'feature': feature_names,
    'coefficient': model.coef_[0]
    })
  2. 决策树 (Decision Tree)

    优点:

    • 易于理解
    • 可处理非线性
    • 不需要特征缩放
    from sklearn.tree import DecisionTreeClassifier

    model = DecisionTreeClassifier(
    max_depth=5,
    min_samples_split=100,
    min_samples_leaf=50,
    class_weight='balanced'
    )
    model.fit(X_train, y_train)
  3. 随机森林 (Random Forest)

    优点:

    • 准确率高
    • 不易过拟合
    • 特征重要性
    from sklearn.ensemble import RandomForestClassifier

    model = RandomForestClassifier(
    n_estimators=100,
    max_depth=10,
    min_samples_split=100,
    class_weight='balanced',
    n_jobs=-1
    )
    model.fit(X_train, y_train)
  4. XGBoost

    优点:

    • 高性能
    • 处理缺失值
    • 正则化防止过拟合
    import xgboost as xgb

    model = xgb.XGBClassifier(
    n_estimators=100,
    max_depth=5,
    learning_rate=0.1,
    subsample=0.8,
    colsample_bytree=0.8,
    scale_pos_weight=1 # 处理样本不平衡
    )
    model.fit(X_train, y_train)
  5. LightGBM

    优点:

    • 训练速度快
    • 内存占用低
    • 准确率高
    import lightgbm as lgb

    model = lgb.LGBMClassifier(
    n_estimators=100,
    max_depth=5,
    learning_rate=0.1,
    subsample=0.8,
    colsample_bytree=0.8,
    scale_pos_weight=1
    )
    model.fit(X_train, y_train)

### 6. 模型部署与监控

模型部署

  1. 模型保存

    import joblib

    # 保存模型
    joblib.dump(model, 'credit_model.pkl')

    # 保存预处理
    joblib.dump(scaler, 'scaler.pkl')
  2. 模型加载与预测

    import joblib

    # 加载模型
    model = joblib.load('credit_model.pkl')
    scaler = joblib.load('scaler.pkl')

    # 预测
    X_scaled = scaler.transform(X_new)
    y_pred = model.predict(X_scaled)
    y_prob = model.predict_proba(X_scaled)[:, 1]
  3. API 服务

    from flask import Flask, request, jsonify

    app = Flask(__name__)

    @app.route('/predict', methods=['POST'])
    def predict():
    data = request.json
    X = pd.DataFrame([data])
    X_scaled = scaler.transform(X)
    prob = model.predict_proba(X_scaled)[0, 1]
    return jsonify({'probability': float(prob)})

    if __name__ == '__main__':
    app.run()

模型监控

  1. 性能监控

    监控指标:

    • 每日 KS、AUC
    • 逾期率追踪
    • 通过率监控
    # 每日性能追踪
    daily_metrics = df.groupby('date').apply(
    lambda x: {
    'ks': calculate_ks(x['y_true'], x['y_score']),
    'auc': roc_auc_score(x['y_true'], x['y_score'])
    }
    )
  2. 稳定性监控

    PSI 监控:

    # 每月计算 PSI
    psi_values = []
    for month in months:
    psi = calculate_psi(train_score, month_score)
    psi_values.append(psi)

    # 绘制 PSI 趋势
    plt.plot(psi_values)
    plt.axhline(y=0.1, color='y', linestyle='--', label='Warning')
    plt.axhline(y=0.25, color='r', linestyle='--', label='Critical')
  3. 特征监控

    特征分布监控:

    # 监控特征均值变化
    feature_means = df.groupby('date')[feature_cols].mean()

    # 控制图
    for col in feature_cols:
    mean = feature_means[col].mean()
    std = feature_means[col].std()
    plt.plot(feature_means.index, feature_means[col])
    plt.axhline(y=mean, color='b')
    plt.axhline(y=mean+3*std, color='r', linestyle='--')
    plt.axhline(y=mean-3*std, color='r', linestyle='--')
  4. 模型更新

    更新策略:

    • 定期重训练(季度/半年)
    • PSI 超阈值时
    • 业务变化时

## 读书心得

《智能风控:Python 金融风险管理与评分卡建模》是一本实用的风控技术书籍。它将信贷风控的业务知识与 Python 技术实现相结合,提供了大量可落地的代码。

**评分卡体系**的讲解很系统。A 卡(申请评分卡)用于贷前审批,B 卡(行为评分卡)用于贷中管理,C 卡(催收评分卡)用于贷后管理。不同类型的评分卡服务于不同的业务场景。

**特征工程**是风控建模的核心。WOE 编码、分箱、特征选择,这些技术直接影响模型效果。书中提供了详细的代码实现,可以直接应用到项目中。

**模型评估指标**体系很完整。KS 统计量、AUC、PSI 等指标是风控模型的标配。理解这些指标的含义和计算方法,对于模型开发和监控都很重要。

**机器学习模型**的应用很实用。逻辑回归是评分卡的基础,树模型(随机森林、XGBoost、LightGBM)在风控中也越来越常用。书中对比了各模型的优缺点。

对于从事风控工作的同行,这本书提供了:
- 完整的业务知识框架
- 实用的 Python 代码
- 可落地的建模流程
- 模型监控方法

推荐给所有对风控建模感兴趣的同行。