ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

小额贷款信用风险评估:Logistic与Probit组合模型实战解析

小额贷款信用风险评估:Logistic与Probit组合模型实战解析 简介小额贷款公司的客户多为难以从传统金融机构获得贷款的个人和组织信用风险评估因而成为其核心风控环节也使得建立适配自身业务的信用评分体系尤为重要。这份PDF研究以Logistic与Probit组合模型为框架面向小额贷款公司风控人员、金融专业研究者及信贷审批人士系统对比了KMV等复杂模型与信用打分模型的适用性并明确提出采用二者组合提升评估稳定性。资源包仅含1个PDF文档大小1.88MB正文涵盖模型原理、组合模型建立流程、实证案例及结论结构完整。已有156人学习下载读者可从中学习小额贷款公司信用评价体系的构建路径了解定量与定性数据如何共同进入评分模型以及组合模型在真实案例中约70%识别准确率下的实际应用效果。文中同时强调信贷控制人员职业操守与判断能力对模型落地的影响适合作为风险建模、农村金融和小额信贷业务场景中的参考研究。1. 小额贷款个人信用风险评估为什么是Logistic和Ptobit组合模型小额贷款公司的个人贷款信用风险评估多数团队的第一版模型都是Logistic评分卡因为它可解释、好审计、上线快。但小贷客群和银行客群差别很大征信记录薄、多头借贷普遍、短期逾期和长期坏账之间的关系不稳定单靠Logistic一套连接函数处理全部样本总有一批客户的排序是乱的。把Logistic和Ptobit即计量里常见的Probit模型不少课题文献里也拼成Ptobit组合起来用目标不是让AUC涨出一大截而是让两个模型各管一段尾部行为再融合结论。这篇文章适合正在搭小额贷款评分模型的风控数据分析师和建模工程师也适合想复现这类组合模型课题的研究生。我会把从坏客户定义、WOE分箱、单模型拟合、概率融合到上线验证的完整路径写清楚把会坑人的位置都标出来。2. 数据与坏客户定义WOE分箱和滚动率法把样本先立住小额贷款和银行零售信贷最大的不同不是额度小而是客户的违约行为更“急”。一笔5万的消费贷客户逾期可能只是因为月底工资没到账也可能是因为他在别的平台已经借了十几笔资金链断了。这两种人在征信报告上长得完全不一样而Logistic和Ptobit这类参数模型对标签噪声特别敏感。标签定错了后面两个模型怎么组合都是在拟合噪声。2.1 滚动率法定义坏客户为什么“逾期30天”在小贷里不够用很多团队一开始直接用“当前逾期超过30天”当坏客户这个定义在银行零售信贷里能用在小贷公司里会翻车。小贷客户的还款周期随机性很强有些人习惯性晚两三天有些人逾期30天后能自己缓过来真正会变成坏账的是从M1滚到M2再到M3的那部分。常见做法是滚动率法取一个观察期看某个逾期档位的客户在下一个月表现期里滚动到更高档位的比例如果逾期30天到60天的客户里超过一半在一个月后滚到60天以上那30天就是一个合理的坏客户分界线。执行上我一般取6个月观察期、3个月表现期表现期内发生M2即算坏。坏客户占比最好落在5%到15%之间太低模型学不到信号太高说明标签定义过宽会把一批“临时困难户”永久打成坏客户。另一个小贷特有的问题是拒绝推断被审批拒绝的客户没有表现标签这是现状短期内很难补。至少要做的是在进件数据里保留渠道和审批结论变量后面做模型监控时能看出样本选择偏差有多大。提示坏客户占比不是越高越好。如果定义后的坏占比超过30%先回头检查是不是混入了“已核销但没走完流程”的订单如果低于3%则要考虑拉长表现期重新观察。2.2 WOE分箱与IV筛选把连续变量变成模型能吃的形状Logistic和Ptobit都是广义线性模型输入变量最好用离散化后的WOE值而不是原始连续值。原因有两个一是小贷场景里变量和违约率普遍是非线性关系年龄和违约率是U型曲线直接放线性项只会得到“年龄越大风险越低”的错误结论二是WOE分箱天然能处理缺失值和异常值线上变量取值飘了模型输出不会剧烈抖动。WOE的英文全称是Weight of Evidence计算方式是某个分箱里好客户占比和坏客户占比的比值取对数。我常用等频分箱代码和公式如下import pandas as pd import numpy as np def woe_iv(df, feature, target, bins5): # 等频分箱每个箱里的样本量基本一致 df[bin] pd.qcut(df[feature], qbins, duplicatesdrop) grp df.groupby(bin, observedTrue)[target].agg([sum, count]) bad grp[sum] good grp[count] - bad # 好/坏占比用各自总数做分母保证IV计算正确 good_rate good / good.sum() bad_rate bad / bad.sum() # WOE为正说明该箱好客户占比高于坏客户为负则相反 woe np.log(good_rate / bad_rate.replace(0, 1e-6)) iv ((good_rate - bad_rate) * woe).sum() return pd.DataFrame({good: good, bad: bad, woe: woe}), iv代码里有两个必须注意的细节duplicatesdrop避免连续变量在某个切点大量重复时qcut直接报错bad_rate.replace(0, 1e-6)防止某个箱里没有坏客户时对数无穷大。实际项目中还会要求每个箱至少有30个好客户和30个坏客户空箱或样本量过小的箱要手动合并。IV值的经验判断是小于0.02基本不用0.02到0.1是弱变量0.1到0.3是有效变量超过0.3要警惕。在小贷样本量只有几千的数据集里IV超过0.5的变量十有八九带了未来信息后面会专门说这个坑。2.3 时间切片设计训练集、验证集和测试集的切法组合模型比单模型更容易在训练集上自欺欺人因为多了一个“调权重”的环节。如果只在同一个数据集上把Logistic和Ptobit的概率做加权融合权重一定是过拟合的。正确做法是按申请时间把样本切成三段最早一段做训练集中间一段做验证集最近一段做测试集。训练集用来拟合两个单模型的参数验证集用来搜索组合权重测试集最后只跑一次推理。有个容易踩的坑是“政策后置泄漏”公司今年3月上线了新的风控规则把某些渠道的通过率砍掉了一半如果你用今年2月之后的申请样本做训练模型学到的是新政策下的客群分布而线上实际跑的仍是老客群样本内外不一致会让组合权重完全失效。我常规的做法是凡是遇到公司有重大进件政策调整的时间点就把它作为训练集和验证集的天然分界宁可减少训练样本量也不要让政策变更污染样本。3. 单模型实操用statsmodels同时跑Logistic和Ptobit的区别两个模型在理论上的核心差异只有一处连接函数。Logistic用logistic累积分布函数PtobitProbit用标准正态累积分布函数。但在小贷数据上这个差异会体现在系数大小、概率尾部行为和边界样本排序上直接影响后面组合的效果。3.1 Logistic回归与sigmoid曲线S型映射下的违约概率Logistic曲线就是S型曲线机器学习里通常叫sigmoid函数数学形式是p 1 / (1 exp(-z))z是线性得分。这个函数把z从负无穷到正无穷映射到0到1之间中间段斜率大两端趋于平缓。在信用评分里z可以理解成“好坏客户的对数几率”某个变量的系数每增加一个单位违约几率乘上exp(beta)。网上搜“logistic回归和sigmoid函数”能看到大量推导落到代码上其实就是statsmodels的一次fit。用小贷数据拟合Logistic要和上一章的WOE变量衔接好用分箱后的WOE值替换原始连续变量再进模型import statsmodels.api as sm # 假设df已经做过WOE分箱woe_cols是分箱后的WOE列 woe_cols [age_woe, income_woe, inq_6m_woe, overdue_days_woe] X sm.add_constant(df[woe_cols]) y df[bad] logit_res sm.Logit(y, X).fit(methodnewton) print(logit_res.summary())fit(methodnewton)是我在小样本上的习惯statsmodels默认的bfgs在几千笔贷款样本上偶尔会报收敛警告newton更稳。sm.add_constant给设计矩阵加截距项这一步容易漏漏了截距就等于强制把好坏客户的对数几率起点定在0通常会导致系数偏差。summary里重点看三样系数p值、Pseudo R-squared、LLR p值。小贷变量多的时候p值可以放宽到0.1Pseudo R-squared在0.1以上就算可用不要追求高LLR p值对应整体显著性。3.2 Ptobit模型连接函数正态累积分布与概率边界处理Ptobit这个拼写在课题文献里不少见其实就是Probit的变体写法Stata和SAS里的标准模型名是Probit。Probit和Logistic同样处理二元选择问题差别只在连接函数Probit用标准正态分布的累积分布函数Phi(z)Logistic用logistic分布的累积分布函数。在statsmodels里拟合Probit代码和Logistic几乎一样probit_res sm.Probit(y, X).fit() print(probit_res.summary())因为连接函数不同Probit的系数绝对值通常比Logistic小不能直接对比大小但符号应当一致。更关键的是概率尾部的行为差异Logistic尾部厚z极度负向时违约概率下降得慢Probit尾部薄概率更快接近0。在小额贷款场景里大部分好客户的违约概率处于低尾区两个模型对同一个客户的排序在这里会产生分歧这正是组合模型能带来增量信息的根本原因。3.3 单模型参数对比系数、标准误和预测概率有哪些差异两个模型都跑完后我习惯用一张表记录它们的差异对比项LogisticPtobitProbit连接函数logistic CDFS型曲线标准正态CDF系数含义对数几率增量潜变量Z分数增量概率尾部厚尾低违约概率区下降慢薄尾低违约概率区下降快计算速度略快几乎无差别常见落地评分卡主流计量研究、稳健性对照两者预测概率的相关系数在小贷样本上通常在0.98以上看起来高度相关但真正要关注的是相关系数低的那批样本。把两个模型预测概率绝对差超过0.2的样本单独拉出来这批人往往是中间分数段、资料里有特殊模式的人。我见过一个案例多头借贷客户在Logistic里被判为低风险因为他的收入项拉高了分数但Probit因为负债率变量的非线性反应更强把他判为高风险。这类分歧样本才是组合模型的着力点而不是去追求全样本AUC的大幅提升。4. 组合模型三种搭法权重寻优、残差修正、分客群融合先泼盆冷水两个概率高度相关的模型做加权融合全样本AUC提升通常只有0.003到0.01不要指望涨幅吓人。组合模型的真正价值在于排序稳定性、边界样本修正以及分客群下的局部优化。下面是三种常见的组合方式按落地复杂度从低到高排列。4.1 概率层加权融合网格搜索找权重别拍脑袋概率层加权是最直接的组合方式把两个模型预测概率按权重相加。权重不要拍脑袋定用网格搜索from sklearn.metrics import roc_auc_score p_logit logit_res.predict(X) p_probit probit_res.predict(X) best_auc, best_w 0, 0.5 for w in np.arange(0, 1.01, 0.05): p_combo w * p_logit (1 - w) * p_probit auc roc_auc_score(y, p_combo) if auc best_auc: best_auc, best_w auc, w print(f最佳权重: logit{best_w:.2f}, probit{1-best_w:.2f}, AUC{best_auc:.4f})权重遍历步长取0.05足够再细没有意义因为AUC的变化通常不到0.001。需要强调权重搜索必须在验证集上做不是在训练集上做。如果在训练集上寻优得到的权重会对样本噪声过拟合到时间外样本上反而变差。训练集负责拟合两个单模型验证集负责定权重测试集只做最终确认这个纪律要守住。4.2 残差修正融合让Ptobit的残差给Logistic“捡漏”残差修正的思路是先用Ptobit预测算出残差再把残差作为Logistic的一个新变量重新拟合。残差里带着Ptobit没解释掉的违约信息Logistic能从中学到互补的模式。代码如下# 先拟合Ptobit得到预测概率 probit_res sm.Probit(y, X).fit() p_probit probit_res.predict(X) # 构造残差变量实际标签减去模型预测概率 X[ptobit_resid] y - p_probit # 把残差变量一起喂给Logistic logit_cal sm.Logit(y, X).fit() print(logit_cal.summary())实际操作中残差融合最常见的坑是把残差当成普通变量做WOE分箱这会把残差里的连续信息离散化丢掉组合增益。我一般直接把残差作为连续变量进入Logistic不做分箱。另一个经验是看残差变量的p值如果p大于0.05说明Ptobit已经解释得足够充分这个融合项可以去掉。残差修正不是所有项目都适用先跑一次看显著性再决定留不留。4.3 分客群融合多头授信与白户客群分开跑小贷客群的特点决定了一个全局权重很难照顾所有人。多头授信客群近6个月征信查询次数超过8次和征信白户客群的风险驱动因素完全不同多头客群的风险主要来自负债累积白户客群的风险主要来自信息缺失。做法是先按关键变量把样本分成子客群在子客群内分别做概率层加权融合mask_multi df[inq_6m] 8 # 多头客群 mask_thin ~mask_multi # 白户/轻负债客群 for name, mask in [(multi, mask_multi), (thin, mask_thin)]: sub_y y[mask] sub_p1 p_logit[mask] sub_p2 p_probit[mask] # 在子客群内网格搜索权重 for w in np.arange(0, 1.01, 0.05): auc roc_auc_score(sub_y, w * sub_p1 (1 - w) * sub_p2) ...分客群的权重不需要跨客群统一线上部署时按同一个条件分支输出对应概率即可。这个做法的收益有两个子客群内变量关系更一致单模型本身拟合得更好同时组合权重在子客群内有实际业务含义。要注意的是切分变量必须用进件时就稳定的变量比如查询次数、收入区间不能用“内部评级等级”这种本身就要靠模型预测的变量否则就是循环论证。5. 避坑与排查小额贷款组合模型最容易翻车的5个地方这一章是血泪经验汇总。组合模型比单模型多了一层出问题时也更容易让人摸不着头脑以下5个场景是我在小贷项目里真实遇到过的翻车现场每条按现象、原因、解决三步写。5.1 现象Ptobit概率堆在0.9以上好坏客户没拉开有个项目里Probit模型跑完后验证集上超过六成客户的违约概率都在0.9到1.0之间好客户和坏客户根本没拉开AUC看着还行但分布一塌糊涂。原因是样本里“近3个月查询次数为0”这个特征几乎只出现在极优质客户中正态累积函数在很短的取值区间内从0.1跳到0.99导致概率整体被推向高端。解决方法是把概率输出改成百分位排名用排名做融合权重同时检查是否某个变量的区分度全部来自“缺失值分支”。如果线上缺失默认填0会把“缺失”和“查询0次”混为一谈这也是概率堆顶的常见诱因。5.2 现象Logistic收入系数为负业务逻辑完全相反收入越高风险越低是常识但有一次Logistic结果里收入系数是显著为负的。原因不是变量本身有问题而是收入和高负债客户高度相关小贷客群里借贷需求最大的恰好是收入中高但现金流紧张的人同时收入变量和授信额度变量存在强共线模型把“收入”当成了“额度”的替身。解决方法是先看变量相关性矩阵把额度类、负债类变量拆出去或者把收入改成“收入/月供”这种比率变量再进模型。在WOE分箱阶段还要检查分箱后的WOE是否单调U型或倒U型的WOE直接放进线性模型里符号不稳是必然的。5.3 现象训练AUC漂亮时间外样本AUC掉10个点训练集AUC 0.78时间外验证只有0.67这是最典型的组合模型翻车现场。原因通常是特征里有“当期催收状态”这类后验变量建模时已经带了标签信息另一种原因是分箱时用了全样本的分布算切点时间外样本的变量落到分箱边界外被归到空箱WOE值全部失效。解决方法是严格按申请时间切样本分箱只用训练集内侧的cut点时间外样本套用同一组切点越界的值统一归入“其他”箱。这条规矩我后来写成了固定的建模流程任何项目都先按时间切好再动特征工程。5.4 现象上线后概率分布与离线对比突变两个模型在线下都好好的上线后第一周概率分布突然和离线对不上大量客户分数集中在0.99。原因是线上数据库里部分字段空值被回填成0而离线的WOE分箱对“0”有专门解释特征工程顺序也不对先算了衍生变量再回填缺失回填值污染了衍生变量。解决方法是上线前准备一份“上线比对样本”逐变量核对线上和离线的min、max、缺失率缺失回填策略写进模型说明文档WOE分箱里给缺失单独分一个箱。这个坑不是模型问题是数据管道问题但表现出来就是模型失效排查时会浪费大量时间。5.5 现象SAS proc logistic和Python建模结果对不上同一份数据SAS的proc logistic和Python的statsmodels跑出来系数不一致但AUC几乎一样。第一次遇到时我以为是代码写错了查了半天发现是分类变量的编码方式不一样SAS默认用参考水平编码生成哑变量Python的pandas get_dummies如果不设置drop_first会用独热编码生成所有水平的列两边截距和某个水平的系数差了一个常数。网上搜proc logistic输出结果解释时还经常看到unequalslopes选项那个是用于有序多分类logit的不等斜率假设二分类违约预测根本用不上别往评分卡里套。解决方法是比对前先统一哑变量编码最省事的做法是两边都用连续WOE变量不做哑变量系数可以直接对齐。6. 上线验证用KS、PSI和滚动回测守住模型的底线6.1 用KS和AUC验证区分度KS值是好坏客户累计概率分布的最大距离小贷模型里KS大于0.25算可用0.3到0.4是常见目标低于0.2基本不能上线。AUC是全局排序能力容易被中间分数段的大批量样本主导而KS更关注极端分位两者一起看才不会漏掉尾部风险。6.2 用PSI守住稳定性PSI群体稳定性指数用来监控线上分数分布和建模基准分布的偏移计算方式如下def psi(actual, expected, bins10): # actual为线上分数占比expected为建模基准占比 actual np.clip(actual, 1e-6, 1 - 1e-6) expected np.clip(expected, 1e-6, 1 - 1e-6) return np.sum((actual - expected) * np.log(actual / expected))PSI小于0.1表示分布稳定0.1到0.25之间需要关注超过0.25必须找原因。我上线后的习惯是每周跑一次PSI按进件渠道拆分看哪个渠道先飘说明那个渠道的客群先变了。6.3 滚动回测与止损习惯建模时不要只看一个时间段的验证集按季度切片做滚动回测用Q1样本建模Q2样本验证然后再用Q1加Q2建模Q3样本验证。这样能看出组合模型的收益随客群变化是稳定还是运气。关于组合权重我在一个项目里吃过亏只看了AUC没看分客群的KS结果模型上线后某个渠道的通过率异常后来养成了“任何模型上线前必须先跑12个月滚动回测上线后第一个月每周看PSI和通过率”的习惯。异常达到阈值就降级回旧模型先止损再排查希望这个习惯也能帮到你。本文还有配套的精品资源点击获取
返回列表