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