4. 模型开发实战:使用Python进行数据划分、训练逻辑回归模型、生成Score值

本章将进入Collection Score模型开发的核心环节。我们将使用Python的scikit-learn库,完成从数据准备、模型训练到Score值生成的全流程。通过本实战,您将掌握逻辑回归在催收评分卡中的标准实现方法。

4.1 数据划分:训练集与测试集

在建模前,必须将数据集划分为训练集和测试集。训练集用于拟合模型参数,测试集用于评估模型在未见数据上的表现,防止过拟合。

划分原则:通常按70%训练集、30%测试集的比例划分,并保持目标变量(逾期/非逾期)在两组中的分布一致(分层抽样)。
import pandas as pd
from sklearn.model_selection import train_test_split

# 加载已处理的特征数据(假设已包含WOE转换后的特征)
df = pd.read_csv('collection_features_woe.csv')

# 定义特征列和目标列
feature_cols = [col for col in df.columns if col.startswith('WOE_')]
X = df[feature_cols]
y = df['target']  # 1=逾期,0=非逾期

# 划分数据集:70%训练,30%测试,stratify保证类别平衡
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42, stratify=y
)

print(f"训练集样本数: {X_train.shape[0]}")
print(f"测试集样本数: {X_test.shape[0]}")
print(f"训练集逾期比例: {y_train.mean():.2%}")
print(f"测试集逾期比例: {y_test.mean():.2%}")
输出示例:训练集样本数: 7000,测试集样本数: 3000,逾期比例均约为15%,说明分层抽样有效。

4.2 训练逻辑回归模型

逻辑回归是评分卡建模的经典算法,具有可解释性强、输出概率可校准、训练速度快等优点。我们使用LogisticRegression并设置class_weight='balanced'来处理样本不平衡问题。

from sklearn.linear_model import LogisticRegression

# 初始化逻辑回归模型
model = LogisticRegression(
    penalty='l2',          # L2正则化防止过拟合
    C=1.0,                 # 正则化强度的倒数
    class_weight='balanced',  # 自动平衡类别权重
    solver='lbfgs',        # 优化算法
    max_iter=1000,         # 最大迭代次数
    random_state=42
)

# 在训练集上训练模型
model.fit(X_train, y_train)

# 输出模型系数
coef_df = pd.DataFrame({
    'feature': feature_cols,
    'coefficient': model.coef_[0]
})
print(coef_df.sort_values('coefficient', ascending=False))
特征名称 系数值 解释
WOE_逾期天数 1.85 逾期天数越长,逾期概率越高
WOE_历史催收次数 0.92 历史催收次数越多,风险越高
WOE_收入水平 -0.76 收入越高,逾期概率越低
WOE_年龄 -0.34 年龄越大,还款意愿相对更强
注意:系数符号必须与业务逻辑一致。若出现WOE_收入水平系数为正(收入越高越容易逾期),需检查特征工程或数据质量问题。

4.3 生成Score值

逻辑回归输出的是逾期概率p,我们需要将其转换为整数Score值,便于催收策略的分层使用。转换公式基于评分卡标准刻度:

Score = Offset + Factor × ln(odds)

其中odds = p / (1 - p)。通常设定:
- 当odds = 1:1时,Score = 600
- 当odds翻倍时,Score增加20(即PDO=20)

import numpy as np

# 获取逾期概率
y_prob_train = model.predict_proba(X_train)[:, 1]
y_prob_test = model.predict_proba(X_test)[:, 1]

# 评分卡刻度参数
target_odds = 1.0      # odds=1:1时
target_score = 600     # 对应分数
pdo = 20               # odds翻倍时分数增量

# 计算Offset和Factor
factor = pdo / np.log(2)
offset = target_score - factor * np.log(target_odds)

# 将概率转换为Score
def prob_to_score(prob, offset, factor):
    odds = prob / (1 - prob)
    score = offset + factor * np.log(odds)
    return np.round(score).astype(int)

# 生成训练集和测试集的Score
train_score = prob_to_score(y_prob_train, offset, factor)
test_score = prob_to_score(y_prob_test, offset, factor)

# 将Score添加到DataFrame
df_train = X_train.copy()
df_train['score'] = train_score
df_train['target'] = y_train.values

df_test = X_test.copy()
df_test['score'] = test_score
df_test['target'] = y_test.values

print(f"训练集Score范围: {train_score.min()} ~ {train_score.max()}")
print(f"测试集Score范围: {test_score.min()} ~ {test_score.max()}")
Score含义:Score越高,代表客户信用越好、逾期概率越低;Score越低,代表客户风险越高、需要优先催收。通常Score在300~800之间分布。

4.4 模型评估与Score分布验证

生成Score后,必须验证其区分能力和单调性。我们使用KS值和AUC作为核心指标。

from sklearn.metrics import roc_auc_score, roc_curve

# 计算AUC
auc_train = roc_auc_score(y_train, y_prob_train)
auc_test = roc_auc_score(y_test, y_prob_test)

# 计算KS值
def ks_score(y_true, y_prob):
    fpr, tpr, thresholds = roc_curve(y_true, y_prob)
    return max(tpr - fpr)

ks_train = ks_score(y_train, y_prob_train)
ks_test = ks_score(y_test, y_prob_test)

print(f"训练集 AUC: {auc_train:.4f}, KS: {ks_train:.4f}")
print(f"测试集 AUC: {auc_test:.4f}, KS: {ks_test:.4f}")
指标 训练集 测试集 合格标准
AUC 0.782 0.771 ≥0.70
KS 0.435 0.418 ≥0.30
训练/测试差异 - ΔAUC=0.011 ≤0.05
解读:训练集与测试集AUC差异仅0.011,说明模型没有过拟合;KS值超过0.40,表明模型对好坏客户的区分能力良好,可用于催收策略分层。

4.5 Score分箱与策略映射

最后,将连续Score划分为若干风险等级,每个等级对应不同的催收触达策略。

# 定义Score分箱边界
score_bins = [300, 400, 500, 600, 700, 800]
score_labels = ['高风险', '中高风险', '中风险', '中低风险', '低风险']

# 对测试集进行分箱
df_test['risk_level'] = pd.cut(
    df_test['score'], 
    bins=score_bins, 
    labels=score_labels, 
    right=False
)

# 统计各风险等级的逾期率
risk_stats = df_test.groupby('risk_level', observed=False).agg(
    客户数=('target', 'count'),
    逾期率=('target', 'mean')
).reset_index()

print(risk_stats)
Collection Score 模型开发与策略映射流程 数据划分 70%训练 / 30%测试 逻辑回归训练 L2正则 + 平衡权重 逾期概率 p 0~1 连续值 Score转换 Offset + Factor × ln(odds) 模型评估 AUC / KS 验证 风险等级分箱 5级风险分层 催收触达策略映射 高风险→电话催收 / 低风险→短信提醒 关键输出:Score值 + 风险等级 → 直接驱动催收触达策略的自动化决策

4.6 本章小结

通过本章实战,您已完成:

  • 数据划分:使用分层抽样保证训练/测试集分布一致
  • 逻辑回归训练:掌握L2正则化与类别平衡设置
  • Score生成:基于标准评分卡刻度将概率转换为可解释的整数分数
  • 模型评估:使用AUC和KS验证模型区分能力
  • 风险分箱:将连续Score映射为5级风险等级,为催收策略提供决策依据
生产环境注意事项:实际部署时,需将Offset和Factor参数持久化保存,确保线上Score计算与线下开发一致;同时建议每月监控Score分布漂移,及时触发模型重训练。