逻辑回归在信贷风控中的应用:从违约预测到评分卡实践
一个客户在APP上提交了借款申请系统要在几秒内决定批不批、批多少、利率怎么定。你可能会以为背后跑着的是某个深度学习模型但实际上大多数信贷机构真正跑在评分决策流里的还是那个看起来有点“过时”的逻辑回归。我在做个人贷款违约预测模型时也不例外——用逻辑回归做主干模型而且一用就是很长时间。逻辑回归在信贷风控里的地位有点像家常菜里的西红柿炒蛋不惊艳但顶用而且几乎人人都得学会做。原因不复杂个人贷款违约预测这件事核心不是“把精确率从98.1%提到98.2%”而是要一个稳定、可解释、能落地到审批策略里的概率打分。这篇文章我就用自己做过的个人贷款违约预测项目为例把逻辑回归从样本设计、特征工程、训练评估、评分卡换算到上线监控的完整链路拆开讲一遍。适合刚入行做风控建模的同学也适合想搞明白“为什么公司非要我用逻辑回归”的业务和算法朋友。1. 为什么做了这么多年风控违约预测还是绕不开逻辑回归1.1 可解释性是信贷决策的硬约束做信贷风控和做图像识别最大的区别在于图像识别判断错了顶多识别出一个猫信贷判断错了是真金白银的损失而且监管会来问“你为什么拒了这个人”。如果模型回答不了产品就得下架。逻辑回归的每个特征对应一个明确的系数正向还是负向、影响多大都能直接读出来。客户年龄增加一岁评分降低多少分这些是可以写进审批说明里的。我在某消费信贷项目里做过一个测试同样的样本跑了一个逻辑回归和一个梯度提升树模型树模型的AUC确实高一些但在一次业务评审会上业务方拿着某笔拒绝样本的决策链来问“为什么拒”树模型的shap值解释讲了大半天对方依然半信半疑而逻辑回归这边直接说“该客户近3个月征信查询次数过多权重占比15%单项减分30分”业务方反而立刻接受了。这就是现实不是树不好是逻辑回归的系数本身就是业务语言。1.2 逻辑回归输出的概率是可以直接当钱用的很多模型输出的是一个分类结果但信贷决策需要的是一个连续的违约概率或者一个评分。逻辑回归天然干这个事输入特征x输出违约概率p然后通过odds换算成分数。风控策略里的“一刀切拒绝线”“分层定价”“额度调整”全都是基于这个概率来设定的。另外一件很多人忽略的事是逻辑回归输出的概率相对可校准。树模型输出的“概率”其实是叶子节点的样本占比会有明显的离散化和偏移而逻辑回归基于极大似然估计输出与真实违约率之间通常只需要做一次简单的校正就能贴近。对信贷这种“概率直接对应损失”的场景来说这一点至关重要。1.3 再复杂的模型也需要一个逻辑回归当基线我给团队定了一条规矩任何新模型上线之前先跑一个逻辑回归做基线。不是因为逻辑回归最好而是它足够简单、稳健、不容易出错。如果树模型比逻辑回归只高0.5个点的AUC但上线后需要投入大量精力做监控、解释和调参那这笔账往往不合算。而如果连逻辑回归都没跑通说明样本或者特征本身就有问题这时候去跑复杂模型大概率是在折腾自己。逻辑回归像一把尺子量一量数据成色也量一量复杂模型的真实增益。2. 建模前最花时间的不是调参而是样本设计与时间窗口2.1 先搞清楚“违约”到底是谁个人贷款违约预测里最容易犯的错误就是没定义清楚目标变量。不是说“逾期了就是坏客户”而是要定一个口径观察期、表现期、逾期天数。我在项目里用的是比较通用的定义——表现期设为12个月客户在观察期比如申请前6个月的特征被提取出来之后12个月内只要出现逾期90天及以上的行为就标记为chuyue客户。剩下的客户在表现期内没有出现严重逾期才算是好客户。这里有个关键逻辑特征提取和表现期观察的时间窗口是不能重叠的。如果同一笔订单既拿去做特征又拿它后面的逾期结果做标签就变成了用未来预测现在等于作弊。数据上看起来模型很准上线后一定崩。这个坑我见过太多次很多人一开始没注意模型线下AUC做到0.75一上线就掉到0.6以下怎么找原因都找不到最后发现是时间窗口穿越了。2.2 训练集和验证集要按时间切不能随机切通用机器学习教程教你的都是随机切分训练集和测试集但在信贷场景里这么干是错的。客户的借贷行为、收入水平、征信状况都在随时间变化随机切分会让模型“偷看”到未来的信息分布。正确做法是按时间切用较早时间段的数据做训练用较晚时间段的数据做验证模拟模型上线后面对新客户的情况。我当时用某消费金融公司的申请数据选了2019年7月到2020年6月的客户做训练集2020年7月到2020年12月的客户做验证集这样的结果才能真实反映模型在未来数据上的表现。用随机切分测出来的AUC通常会偏高零点三到五个百分点别被这个虚高数字骗了。2.3 违约率太低了别乱下采样个人贷款的整体违约率一般在2%-5%之间好客户的样本量远大于坏客户。直接用原始样本训练逻辑回归会倾向于把所有客户都预测成“好”虽然准确率很高但一点用都没有。常见的做法是下采样把好客户抽一部分出来让好和坏的比例变成大概2:1或者3:1。但下采样之后有一个坑——模型输出的概率是训练样本里的概率不是真实违约率。如果你用下采样后的样本训练出p0.4真实违约率可能只有0.03。这时候千万别直接把0.5当阈值一定要做概率校准。校准公式其实不复杂假设原始好客户权重为w则调整后概率为p_adjusted p / (p (1-p) / w)其中w是下采样后坏样本占比除以原始坏样本占比。比如原始坏率3%采样后坏率33%那w大概是11。这一步不做你的评分卡所有分数都会系统性地偏掉。2.4 拒绝样本要不要管还有一个常被忽略的样本设计问题建模用的样本一般只包含历史审批通过的客户那些被拒掉的客户没有“表现期”我们永远不知道他们会不会违约。但现实是你上线后要评分的正是这些新申请客户其中包含了很多过去会被拒绝的人。这就是拒绝推断问题。我在项目里用的是一种比较实用的处理方式先用通过样本训练一个初步模型再用这个模型对拒绝样本做预测把其中概率比较高的部分样本回填进训练集给它们打上“预测坏”的标签。这种方法不完美但能减轻样本选择偏差。如果完全不管拒绝样本模型对高风险客户的区分能力会被系统性低估。3. 特征工程里的分箱、WOE与IV逻辑回归的灵魂步骤3.1 为什么不能用原始数值直接喂给逻辑回归逻辑回归本质上是一个线性模型输入特征的数值大小和方向会直接影响系数估计。信贷特征里很多变量和违约率并不是线性关系。比如年龄20多岁和50多岁违约风险都偏高30-45岁反而低这种倒U型关系用单一原始数值去拟合是拟合不出来的。解决方案就是分箱。分箱还有一个实用的好处能天然处理缺失值和异常值。在实际信贷数据里收入的缺失、征信查询次数的极端值都很常见。分箱之后缺失值单独成为一个箱异常值并入最高或最低的箱里模型中不会因为一个离群点被拉偏系数。这是把业务先验知识编码进模型的过程。3.2 WOE编码的核心思想分箱之后每个箱位不能直接用序号当数值因为箱位之间没有线性关系。常见做法是把每个箱位转换成WOE值Weight of Evidence证据权重。WOE的计算公式为WOE ln(好客户占比 / 坏客户占比)每个箱位的WOE值反映了“这个箱位里的客户在多大程度上是好人还是坏人”。WOE越高表明该箱位的好客户比例相对越高风险越低WOE越低甚至为负表明该箱位的坏客户比例越高风险越高。逻辑回归的系数直接和WOE对应所以最后的分数解释起来非常直观。我做分箱的时候有一条经验每个特征的WOE趋势要尽量单调或者至少符合业务常识。比如“近3个月征信查询次数”查询次数越多的箱位WOE应该逐渐下降说明风险在升高。如果某个箱位的WOE突然反弹多半是分箱太细导致样本太少噪声大这时候要手动合并箱位。逻辑回归不像树模型那样能自动处理非线性分箱质量决定了模型上限。3.3 IV值筛选哪些特征有资格进模型IV值Information Value是衡量特征预测能力的最常用指标和WOE紧密相关IV Σ(好客户占比 - 坏客户占比) × WOE我常用经验标准IV小于0.02的特征基本没有预测力不用0.02到0.1属于弱预测力可以结合业务意义决定是否保留0.1到0.3属于中等偏强重点保留大于0.3的特征预测力很强但也要小心个别IV极高的变量往往和违约定义有重叠可能引起逻辑回归共线性。还得做一个相关性检查和VIF检查。有些特征单独看IV很高但彼此高度相关同时放进模型会导致系数不稳定。比如“近6个月查询次数”和“近3个月查询次数”IV都很高实际上信息高度重叠。我在变量筛选阶段一般会先算一下相关系数矩阵相关系数超过0.6的只保留IV较高的那个。3.4 一个具体的分箱例子以“客户年龄”为例原始数据是20到60岁我先用等频分箱粗分再根据各箱WOE趋势手动调整最终分成了“20-25”、“26-30”、“31-40”、“41-50”、“50岁以上”这几个箱。结果符合业务直觉20-25岁客户收入不稳定WOE偏低31-40岁客户处于职业稳定期WOE最高50岁以上客户Work收入波动大WOE又回落。这样的变量进入模型后系数方向明确业务解释顺畅。另外一个典型的例子是“收入负债比”。这个变量很多人喜欢直接用数值但它在不同收入段的影响明显不同。分箱后能看出低负债比区间WOE基本平稳高负债比区间WOE急剧下降——这就说明负债比超过某个阈值后风险陡增逻辑回归的线性假设在这里直接失效只有分箱才能捕捉到这种非线性。4. 模型训练里容易翻车的地方从损失函数到KS值4.1 最大似然与正则化的取舍逻辑回归用最大似然估计来求解参数损失函数是交叉熵。这个学过统计的人都知道但在工程实践里真正影响模型效果的是正则化参数的选择。L1正则会把不重要特征的系数压到0起到特征选择作用L2正则把系数整体缩小防止过拟合。我在项目里偏好L2正则因为信贷特征经过WOE变换后本来就不算太多L2能让系数更稳定保留特征的可解释性。正则化强度C值我一般用网格搜索候选范围从0.01到10之间步进选验证集KS最高的那组。有些人喜欢调随机梯度下降的迭代次数其实逻辑回归收敛很快真正影响结果的是特征质量而不是迭代次数。4.2 KS和AUC到底看哪个信贷模型评估里最常用的两个指标是KS和AUC。AUC衡量整体排序能力你把所有客户按预测违约概率从高到低排序AUC表示随机抽一个坏客户比随机抽一个好客户排得更靠前的概率。KS则是把客户按违约概率分十等份计算每一等份累计好客户占比和累计坏客户占比的最大差值反映了模型在某个阈值附近的最大区分能力。如果AUC高但KS低说明模型整体排序不错但范围内区分能力不集中这对策略应用来说可能不够。如果KS特别高比如超过0.75反而要警惕是不是特征穿越或者目标泄漏了。正常信贷逻辑回归的KS在0.35到0.55之间就算相当不错。我在模型效果评审时一般同时看KS、AUC和Gini系数三者一致性才算模型稳健。这里还有一个小技巧评估的时候按预测分数分箱逐箱对比实际违约率与预测违约率。理想情况下分数越低的箱实际违约率越高而且违约率应单调递增。如果某个箱位实际违约率明显偏离说明这个分数段可能混入了特殊客户要回头检查特征不能只看整体指标就放行。4.3 阈值不是0.5是算出来的很多人拿到模型输出的概率之后直接默认大于0.5就是违约小于0.5就是好客户。但在贷款业务里0.5这个阈值几乎从来不是最优解因为违约事件很少真实违约率可能才3%模型输出的违约概率分布整体都偏低0.5阈值会拒绝掉几乎所有人。正确做法是画一张代价矩阵。把客户分成四类实际好预测好正确放行、实际坏预测坏正确拒绝、实际坏预测好漏放损失、实际好预测坏误拒损失。误拒损失可以理解为“本来可以赚的利息收入”漏放损失是“贷款本金损失”。两者不是等价的通常漏放的代价是误拒代价的数倍。所以阈值要选在使总期望损失最小的位置。我在某项目里做阈值选择时计算了不同阈值下的期望损失曲线发现最优阈值大约在0.08附近而不是0.5。这个数字意味着我们只把预测违约概率超过8%的客户拒绝掉剩下的客户进入人工审批或降低额度。业务方刚开始觉得8%太低直觉上认为“这等于在乱拒”但看到期望损失对比之后他们接受了——这就是数据说话的力量。4.4 概率校准怎么做才靠谱模型训练时用了下采样或者训练样本的违约率和线上真实违约率差得远概率输出就不能直接用要校准。除了前面提到的调整公式还有一种常用方式是做Platt Scaling在训练好的逻辑回归输出上再套一个逻辑回归用验证集拟合出真实违约率与原始分数之间的映射。简单说你有一个分数s真实违约率的估计就是1 / (1 exp(a b×s))其中a和b都是通过验证集估计的。我在实际项目里发现下采样校准后再用验证集做一次平滑调整线上KS几乎不掉而校准后的概率可以直接用于额度定价。这一步虽然额外花时间但属于“以后不会再翻车”的投资。忽略校准的模型上线后业务方发现10分和100分额度定价对应的实际违约率完全对不上那才是最头疼的事。5. 从模型到评分卡分数换算与业务落地5.1 一个公式把概率变成评分业务人员不习惯跟概率打交道他们更习惯看到一个300分到900分之间的分数分数越高风险越低。逻辑回归到标准评分卡有固定公式。把模型的线性输出记为ln(odds)其中odds是好客户概率与坏客户概率之比即p/(1-p)。设定两个业务参数基准分base当odds为某个设定值时对应的分数比如设置odds19即5%坏率时分数为600分PDOPoints to Double the Oddsodds翻倍对应分数增量一般设20或30意思是odds每翻一倍分数增加20分。这样每个客户的分值就是Score base factor × ln(odds)其中factor PDO / ln(2)。算出每个特征对应各WOE箱位的分数就是把回归系数乘以factor再乘以对应WOE最后全部加起来再加上基准分。标准化之后整个评分卡的每个分数都是一个具体可解释的业务动作依据客户经理一眼就能看出来“这个人在年龄上减了32分在征信查询上减了58分”。5.2 分数分箱后要跟策略联动评分卡通常不是直接用连续分数而是分档。我当时把模型输出的分数分成了A、B、C、D、E五档每档对应不同的审批策略评分档位分数范围策略动作A720以上自动通过标准定价B660-719自动通过降低额度C600-659拒贷或人工审批D540-599拒贷可复议E540以下直接拒绝这个分档不是拍脑袋定的是基于各分数段的实际违约率和客群价值测算出来的。比如720分以上客户群的年化违约率只有0.8%完全可以给低利率额度600分以下的客群违约率超过15%即使提高利率也很难覆盖损失最好不做。5.3 评分卡的局限和人工兜底评分卡只能给出一个量化判断但它不能覆盖所有情况。某些客户可能因为近期突发重大疾病、失业等特殊情况评分不高但未来还款意愿强烈。所以我的策略里通常保留一个复议通道客户被拒后可以提交补充材料人工审批员根据规则复核。这里要特别提醒人工复议的比例不能太高否则审批标准失去一致性评分卡形同虚设。我当时设定的复议占比上限是5%也就是说95%的申请完全由模型决策5%以内留给人工处理特殊情况。这样既保留了模型的客观性也给了业务必要的人性化空间。6. 上线不是终点PSI监控与模型衰退6.1 PSI是模型稳定性的体温计模型上线后最怕的不是准确率下降而是客群漂移。今天进来的客户和三个月前进来的客户如果特征分布已经悄悄变了模型再用旧数据训练时的决策逻辑来打分结果一定会失真。衡量这种分布漂移的标准指标是PSIPopulation Stability Index群体稳定性指标。PSI计算方式是把训练样本的分数分布当成预期分布把当前月线上客群的真实分数分布当成实际分布按分数分箱后计算累计差异。经验阈值是PSI小于0.1说明群体稳定0.1到0.25说明有漂移需要关注大于0.25说明群体结构显著变化模型必须重新训练或进行切换。6.2 线上监控要盯的不只是模型指标除了PSI我还会按月监控线上审批客群的实际逾期表现看训练时的违约率和线上实际违约率是否一致。如果线上LGD前几个月的累计违约率和模型预测的违约率偏离超过了1.5倍就要立刻排查原因是外部经济环境变化还是渠道调整引入了新客群或者系统取数逻辑出了bug。实际案例里最常见的原因往往不是模型本身变差了而是特征口径变了。比如某个月换了征信数据源某类字段从A库切到了B库导致WOE表现完全不同。我经历过的某次线上KS从0.45掉到0.32最后排查出来是因为数据供应商升级了接口一个字段的缺失表达方式变了大部分客户该字段被填充成一个默认值。这种事不亲自查一遍很难发现。6.3 模型重训不是越频繁越好对逻辑回归来说重训需要谨慎。频繁重训会导致决策标准不稳定今天能用这个客户明天因为重训后参数微调被拒了这会直接影响客户体验。实践中我一般设置3个月一次定期重训但如果PSI持续走高就提前触发重训。另外每次重训之后要保留旧评分卡和新评分卡在相同样本上的分数差异分析如果两类客户大量换挡说明模型结构已经发生了结构性变化要评估是不是某些特征的系数方向都翻转了。我习惯在每次上线前保存一份线下校准数据包括验证集的预测概率、真实标签和分数分箱用于下一次模型迭代时的对照组。这样一旦线上出现不同于预期的表现回头对比历史数据就能快速定位是特征偏移、数据质量问题还是模型本身衰退而不是从头猜。个人贷款违约预测模型用逻辑回归做到这里其实已经形成了一套完整的生命周期管理。相比那些追求新模型架构的做法我更愿意把精力花在样本窗口、特征分箱、概率校准和监控机制这些“看不见的地方”。这些环节才是真正决定模型能不能长期稳定赚钱的部分。如果你刚开始做这个方向我的建议很简单先把逻辑回归从头到尾做扎实它会教会你信贷风控里所有最重要的逻辑。