
1. 三张卡的业务坐标先搞清楚模型到底在替谁做决策风控建模这行干久了最容易犯的一个错就是把A卡、B卡、C卡当成同一套建模流程的三个版本换个样本、换个时间窗口就交差。真到上线跑起来才发现A卡那套精雕细琢的评分卡搬到B卡上KS掉得只剩一半C卡照抄B卡的特征体系模型连坏客户的排序都排不出来。问题不在算法在于这三张卡面对的决策场景、可用信息、优化目标压根儿就不是一回事。A卡Application Scorecard申请评分卡解决的是这个人我第一次见要不要给他额度、给多少B卡Behavior Scorecard行为评分卡解决的是这个客户已经在我这儿借了三个月接下来六个月他会不会出问题C卡Collection Scorecard账务管理评分卡解决的是这笔账已经逾期了我该用什么力度、什么节奏去处理才能把钱收回来。三个问题在业务链条上是先后关系但在建模方法上是三条完全不同的技术路线。我把这三张卡的核心差异先摊在一张表里后面所有章节的展开都是围绕这张表来的维度A卡申请B卡行为C卡账务管理决策时点授信申请提交时贷中存续期内滚动逾期发生后可用信息申请表单外部数据内部历史行为全量账务状态触达记录标签定义首笔放款后N期是否逾期M观察点后N期是否逾期M逾期后N期内回收比例/是否回收样本规模中等受通过率限制大但只有放款客群小且极端不平衡核心算法WOE逻辑回归评分卡树模型/集成模型为主分群回归/分类混合首要诉求可解释、可申诉排序准、更新快区分处理优先级、控制成本迭代频率半年到一年月度到季度季度或按资产包这张表看着简单每一行背后都是真金白银的教训。比如A卡样本受通过率限制这一条意味着你手上只有被批准客户的标签被拒的那批人后来表现如何你是不知道的这就是业内常说的拒绝推断问题而B卡虽然样本量大但样本全部来自已经通过审批并且活到现在的客户天然带幸存者偏差模型对高风险客群的识别能力会被系统性高估。C卡更麻烦逾期客户里真正走完整个回收周期的样本可能只有几百条正负样本比例动辄1:20普通的AUC评估在这种情况下基本失真。所以我的建议很直接先别急着调参先把三张卡各自的决策问题翻译成一句能被数学描述的话。A卡翻译成给定申请时点可见的信息集合预测未来一段时间内发生严重逾期的条件概率B卡翻译成给定截至观察点的全部行为轨迹预测未来滚动窗口内的违约概率C卡翻译成给定逾期状态和触达历史预测未来一段时间内的回收金额或回收概率。这三句话里的每一个限定词——申请时点可见、截至观察点、逾期状态——都是后面特征工程和样本设计的硬约束写不清楚就别往下走。1.1 从业务链条看A/B/C卡的分工我习惯把整个信贷生命周期画成一条流水线客户进来申请→ 客户在里面活动用信、还款、提额→ 客户出问题逾期→ 客户被处理账务管理→ 客户离开或恢复。A卡站在流水线的入口做第一道筛子B卡在每个月的检查站做动态体检C卡在出问题之后做分级处理。三者串联起来才构成完整的风险闭环任何一环缺失整条流水线的效率都会打折。入口这道筛子决定了后面所有的资产质量上限。A卡如果放得太松B卡再精准也只能在烂苹果里挑相对不那么烂的A卡如果收得太紧通过率低到业务活不下去风控部门就成了业务部门的对立面。这个平衡点不是模型能算出来的是业务策略和风险偏好共同定的模型只是把给定通过率下的坏账水平这条曲线画出来让决策者有得选。我在实际项目里见过不少团队把A卡的KS做到0.45以上结果上线后通过率一压再压最后业务端直接绕过风控走人工审批模型形同虚设。A卡的终极指标不是KS是在目标通过率下的预期坏账率这一点一定要在建模之初就和业务方对齐。B卡的价值在于它是唯一能捕捉客户状态变化的模型。A卡看到的是静态切片客户申请那天是什么样就永远是什么样B卡看到的是连续剧客户这个月额度用了多少、还款是不是踩点、有没有频繁改绑定卡、APP登录频次是不是在下降。这些动态信号对违约的预测能力远超静态资质。我做过一个对比同一个客群A卡的特征体系在贷中第六个月上的KS大概是0.28而加入行为序列特征后的B卡能到0.38以上提升非常明显。原因不复杂违约从来不是一个瞬间事件它是一个过程过程中一定留下痕迹。C卡最容易被忽视很多团队做到B卡就停了觉得贷后是运营部门的事。这是个巨大的浪费。C卡的精细化程度直接决定了回收成本。举个我自己经历过的场景一批逾期15-30天的客户账务管理资源有限是先处理金额大的还是先处理失联风险高的如果C卡能把未来30天回收概率排出来按概率从高到低分配人力同样的投入能多回收两到三成。这不是模型多先进的问题是有没有把模型用在正确的地方。1.2 三个场景的本质差异时间、信息、目标把三张卡放在一起看最本质的差异其实只有三个词时间、信息、目标。这三个词决定了后面所有的技术选择值得逐一说透。时间的差异体现在两个层面。第一个层面是预测窗口。A卡通常预测放款后6到12个月的违约概率因为早期逾期更多反映的是欺诈和申请欺诈中期才反映真实还款能力B卡通常预测未来3到6个月窗口太长会被客户的正常状态变化稀释太短则业务来不及反应C卡的窗口最短通常7天、15天、30天三档因为账务管理的动作本身就是高频的。第二个层面是信息的时间边界。A卡只能用申请提交那一秒之前的信息多用一个小时后的数据就是穿越B卡用观察点之前的全部信息观察点的选择必须和决策动作对齐比如每月1号出额度调整决策观察点就卡在月末最后一天C卡的边界是逾期状态确立的那一刻。信息的差异决定了特征工程的形态。A卡是横截面数据一行一个客户特征是从申请表、外部数据源、设备信息里拼出来的静态快照。B卡是面板数据一个客户多行每行是一个观察点特征需要做时间窗口聚合比如近30天用信次数、近90天最低还款次数、额度使用率的7日移动平均。C卡是事件序列数据特征是账务状态和触达记录的组合比如逾期天数、历史最大逾期天数、近7天触达次数、上次触达后的还款金额。三种数据形态对应的特征处理工具链完全不同A卡那套WOE分箱流水线直接搬到B卡上会出大问题因为B卡的特征是随时间滚动的分箱边界如果按全样本一次性切会造成严重的信息泄露。目标的差异最容易被低估。A卡优化的是区分好坏好坏定义相对清晰逾期M3逾期90天以上就是坏其余是好二分类问题。B卡优化的也是二分类但好的定义要复杂得多因为贷中客户的表现是渐变的一个客户可能一直正常还款但额度使用率飙升到95%这种亚健康状态在简单的二分类标签里是被归到好里面的模型学不到。所以B卡经常需要做多标签或者加入辅助任务比如同时预测未来是否逾期和未来额度使用率变化。C卡的目标则完全不是二分类实务中更多是回归问题——预测回收金额比例或者回收概率×回收金额的期望值。用分类模型做C卡等于把最有价值的金额信息直接扔掉了。提示三张卡的时间边界一旦搞混模型在离线评估时可能表现漂亮上线后直接崩盘。我见过最典型的案例是B卡特征里混进了观察点之后才更新的额度调整记录离线AUC 0.82上线第一个月KS只有0.15。这类问题靠看指标是发现不了的只能靠严格的特征时间戳审计。2. 样本与标签设计模型地基九成效果在这里决定算法选型这事我的观点可能有点反主流在三张卡的项目里算法带来的效果差异通常不超过两成剩下的八成全部由样本和标签设计决定。同一个XGBoost样本定义改一改KS能从0.30跳到0.42标签口径调一调模型的业务价值可能直接归零。所以这一章我放在算法之前讲因为顺序错了后面全是白干。样本设计的核心是三个问题谁进样本、什么时候进、进去之后算什么账。这三个问题在A/B/C三类卡上的答案完全不同而且每一类都有自己的陷阱。2.1 A卡申请时点可见信息的严格边界A卡的样本定义看起来最简单——所有提交申请的客户放款后观察一段时间看有没有逾期。但魔鬼在细节里。第一个细节是通过率偏差。你手上只有被批准客户的真实表现被拒绝的客户后来是好是坏你不知道。如果拒绝策略本身比较激进被拒客群里藏着大量其实会按时还款的好客户那么你训练出来的模型对这类客户的打分是偏低的会导致后续审批越来越保守形成自我强化的收缩螺旋。解决这个问题有三条路我在不同项目里都用过。最保守的是只用在审批通过样本上建模不做任何推断适用于通过率高于70%的场景偏差可以接受。第二种是重新加权对被拒样本按如果被批准成为好客户的概率赋予权重这个概率可以用一个辅助模型估计辅助模型的特征是被拒时可见的信息。第三种是两条评分卡并行一条用通过样本建模一条用通过样本被拒样本标签用推断值建模两条卡的分数做融合。我个人的经验是通过率在50%到70%之间用第二种性价比最高低于50%才值得上第三种因为推断本身也有误差过度依赖推断反而引入噪声。第二个细节是表现期的选择。A卡的标签通常定义为放款后12期内是否出现M3逾期。这个12期不是拍脑袋定的要看产品的账龄分布。我做过的短期现金贷产品60%的坏账在放款后3期内就暴露了表现期定12期纯属浪费等待时间而房贷类产品12期远远不够至少要24到36期。判断方法很简单画一条累计坏账暴露曲线横轴是账龄月份纵轴是累计坏账占总坏账的比例找到曲线走平的那个点就是表现期的下限。第三个细节是观察期与表现期的重叠问题。严格来说观察期就是申请时点不存在重叠但如果你的标签定义里包含了放款后立即逾期的情况那这批客户很可能是欺诈而非信用风险混在信用模型里会污染特征的重要性排序。我的做法是把首期即逾期的样本单独拎出来做欺诈模型A卡只负责信用风险两类风险分开建模各自的特征体系也更纯粹。# A卡样本切分的核心逻辑示意 # 核心原则观察点之前的信息才可用表现期内的标签才可信 import pandas as pd def build_application_sample(loan_df, cutoff_date, perf_months12, bad_days90): loan_df: 包含 apply_date, loan_date, 每期还款状态 的明细 cutoff_date: 样本截止日保证每个样本都有完整的表现期 df loan_df[loan_df[apply_date] cutoff_date].copy() # 表现期必须完整观察剔除表现期未走完的样本 df df[df[loan_date] pd.DateOffset(monthsperf_months) cutoff_date] # 标签表现期内是否出现连续逾期超过 bad_days df[label] (df[max_overdue_days] bad_days).astype(int) # 剔除首期即逾期的疑似欺诈样本 df df[df[first_period_overdue_days] 30] return df这段代码看着平淡但最后那行剔除逻辑救过我两次。第一次是一个项目上线后A卡对某类客群打分异常高排查发现是这批人首期就逾期但被算作了坏样本模型学到的其实是申请资料造假的特征模式而我们真正想控制的是还款能力风险。剔除之后模型稳了很多。2.2 B卡观察期与表现期的切分艺术B卡的样本构造是三张卡里最需要工程能力的。因为一个客户在贷中会经历多个时间点每个时间点都可以构造一个样本这就带来一个选择是按客户构造样本还是按客户-月份构造样本。按客户构造简单一个客户一个样本取某个固定时点比如放款后第6个月作为观察点看之后6个月是否违约。缺点是样本量小而且浪费了大量中间过程信息。按客户-月份构造是主流做法每个月月末给所有存续客户打一次快照每个快照是一个样本标签是未来N个月的违约情况。样本量能放大十倍以上但引入了一个严重问题同一个客户的多条样本高度相关如果随机划分训练集和测试集会严重高估模型效果。我的处理方式是按客户ID做分组切分同一个客户的所有快照必须落在同一个集合里。这个细节很多人忽略直到上线后才发现离线AUC 0.85、线上AUC 0.68差距全来自样本泄露。分组切分的代码很简单from sklearn.model_selection import GroupShuffleSplit gss GroupShuffleSplit(n_splits1, test_size0.3, random_state42) train_idx, test_idx next(gss.split(X, y, groupsdf[cust_id]))比切分更麻烦的是观察点与表现期的错位。假设你每个月末给客户打快照标签是未来6个月是否M3。那么2024年6月的快照标签要用到2024年12月的数据。如果你在2024年8月就急着建模6月和7月的快照标签是不完整的必须剔除。更隐蔽的坑是客户在表现期内提前结清这批人算好还是算坏我的处理是提前结清且无逾期的算好样本但要在特征里加上是否提前结清倾向这个变量否则模型会把提前结清能力强的客户和乖乖还满全周期的客户混为一谈。对额度调整模型来说这两类客户的策略应该是完全不同的。还有一个容易被忽略的点是样本的时间衰减。B卡的客户行为模式变化很快两年前的还款行为和现在完全不可比。所以B卡样本通常只取最近12到18个月的快照更早的样本要么丢弃要么大幅降权。我一般用指数衰减加权半衰期设在6个月左右这个参数没有理论最优值靠业务体感和验证集表现调。样本构造方式样本量相关性风险适用场景单时点快照小低冷启动、样本稀缺多月快照客户分组切分大中可控主流B卡建模多月快照时间切分OOT大低最终验证与上线评估2.3 C卡不平衡标签与回收金额的加权处理C卡的样本问题在三张卡里最尖锐。逾期客户的分布本身就是长尾的M1逾期1-30天的客户可能占逾期总量的70%M3只占10%不到而真正需要模型精细区分的是M1到M2这个区间因为这是账务管理动作最密集、回收率差异最大的区间。如果你不分群直接建一个全局C卡模型会把大量精力花在区分M1会自己还和M3基本没戏上这两类的区分根本不需要模型规则就够了。真正有价值的是在M1内部区分提醒一下就还和需要重点跟进。所以C卡的第一步不是建模是分层。我通常按逾期天数DPD分三层DPD 1-7、DPD 8-30、DPD 30每层单独建模。分层的依据不是经验是回收率曲线的拐点——画出每个DPD区间的历史回收率曲线出现明显台阶的地方就是分层边界。我做过的一个项目里DPD 1-3的回收率是92%DPD 4-7骤降到71%这个断崖就是天然的分层点。分层之后的第二个问题是标签设计。分类标签是否回收会丢掉金额信息而账务管理的核心KPI是回收金额。我的建议是主模型用回归预测回收金额比例辅助模型用分类预测是否全额回收两个模型的分数做融合。回归模型的目标变量是实际回收金额 / 应还总额取值在0到1之间用Tweedie分布或者Beta回归比较合适普通的最小二乘回归在这个有大量0值的场景下表现很差。第三个问题是样本不平衡的处理。C卡的正样本高回收远多于负样本低回收但这不代表负样本不重要恰恰相反识别出低回收概率的客户才是账务管理资源分配的关键。我的做法是不做简单的过采样或欠采样而是用代价敏感学习给负样本更高的误判代价。代价系数怎么定用业务数据反推一个低回收客户被误判为高回收导致资源错配损失的期望回收金额是多少一个高回收客户被误判为低回收导致过度投入浪费的人力成本是多少。两个数字的比值就是代价系数。注意C卡的标签窗口一定要和账务管理的动作周期对齐。如果你们的账务管理是按周排班的标签窗口就用7天如果是按双周就用14天。用30天窗口训练出来的模型去打周度决策排序信息和实际动作节奏是错位的效果会打折扣。3. 算法策略差异为什么A卡死磕逻辑回归B卡敢上树模型聊算法之前先说个现象。我在不同团队见过太多无脑上XGBoost的项目A卡也上、B卡也上、C卡也上理由统一是效果更好。短期看KS确实高几个点长期看模型维护成本、解释成本、合规沟通成本全上来了最后往往是被迫回退到评分卡。算法选型从来不是纯技术问题它是效果、可解释性、运维成本三者的平衡而这三张卡的平衡点完全不同。3.1 A卡可解释性优先的WOE评分卡A卡为什么主流还是逻辑回归加WOE分箱不是因为树模型不行而是因为A卡的决策需要说得清。客户被拒了要申诉你得告诉他因为你的多头借贷次数超过X次业务方要复盘你得告诉他这个月通过率下降是因为收入分段的人群整体评分下移风控委员会要审批模型你得把每个变量的方向、强度、稳定性讲明白。这些诉求逻辑回归天然满足树模型需要额外一套解释工具而且解释的稳定性不如评分卡。WOE分箱的价值不只是把非线性关系线性化更重要的是它把每个变量的业务含义固化下来了。一个连续变量被切成5到8箱每箱对应一个WOE值这个WOE值的正负和大小直接告诉你这个区间是风险高还是低、高多少。我在评审模型时第一眼看的就是每个变量的WOE单调性如果收入变量的WOE不单调——比如中间收入段风险最高、两头都低——那要么是分箱有问题要么是这个客群有特殊的业务逻辑必须搞清楚才能用。评分卡的刻度转换也是必须掌握的。业内通用的做法是设定基准分和倍率PDOPoints to Double the OddsScore A - B * ln(odds) B PDO / ln(2) A BaseScore B * ln(BaseOdds)假设基准分600对应 odds20好坏比20:1PDO50那么 B 50/ln(2) ≈ 72.13A 600 72.13 * ln(20) ≈ 600 216.1 816.1。也就是说分数 816.1 - 72.13 × ln(odds)。这个公式的意义在于odds每翻一倍分数降低50分业务方一看分数差50就知道风险翻倍沟通成本极低。我强烈建议所有A卡都做这个转换原始概率对业务方来说是没有直觉的。当然A卡也不是完全不能用树模型。有一种情况我会考虑用GBDT做特征交叉再把叶子节点编码成离散特征喂给逻辑回归。这样既保留了评分卡的可解释框架又能捕捉变量间的交互效应。实测下来KS能比纯评分卡高3到5个点代价是模型复杂度上升需要额外的特征归因工具。中小团队我不推荐维护成本划不来。3.2 B卡时序特征驱动下的树模型组合B卡的算法选择就宽松得多因为B卡的使用场景是内部决策不需要对客户解释为什么给你降额可解释性的要求大幅降低。同时B卡的特征维度高、交互复杂、非线性强树模型天然适配。我目前主流方案是LightGBM单模型 特征重要性筛选 单调性约束的组合。单调性约束这个点值得单独说。B卡的特征里有大量越多越危险或越少越危险的变量比如近30天最低还款次数理论上越多风险越高。但树模型在有限样本下可能学出局部反向的规律比如在某个区间里最低还款次数多的反而是好客户可能是因为这批人额度高、还款能力强。这种局部反向规律在样本内看着合理样本外极不稳定。加单调性约束能强制模型保持业务逻辑上的一致性代价是损失一点点拟合能力但换来的稳定性提升非常值得。import lightgbm as lgb # B卡模型的单调性约束配置 monotone_constraints [ 1, # 近30天最低还款次数越多越危险 1, # 额度使用率越高越危险 -1, # 近90天正常还款次数越多越安全 1, # 近30天APP登录次数下降幅度降得越多越危险 0, # 客户年龄双向不加约束 ] params { objective: binary, metric: auc, monotone_constraints: monotone_constraints, monotone_constraints_method: advanced, learning_rate: 0.03, num_leaves: 31, min_data_in_leaf: 500, feature_fraction: 0.7, bagging_fraction: 0.8, bagging_freq: 5, }min_data_in_leaf这个参数在B卡上要比A卡设得更大因为B卡样本量大但相关性高叶子节点太小容易学到噪声。我一般设在300到1000之间看样本总量和特征维度。另外B卡一定要做时间外验证OOT用最近一个月的数据做测试集因为B卡的分布漂移比A卡快得多随机切分的验证结果会系统性偏乐观。还有一类特殊场景值得提一下多任务学习。B卡经常需要同时输出违约概率和额度使用率变化这两个任务共享底层的行为特征用多任务模型比如共享底层双塔输出能提升样本效率尤其是违约样本稀缺的时候。我试过在违约率1.5%的客群上用多任务违约预测的KS比单任务高2个点左右。但这个方案对工程能力要求高团队没有相应基础设施的话老老实实建两个单模型更稳妥。3.3 C卡分层建模与回收率回归C卡的算法选择最需要因地制宜因为不同DPD层的数据形态差异太大。我的标准方案是三段式第一段DPD 1-7用规则轻量模型。这个阶段的客户大部分只是忘了还或者临时资金周转回收率极高模型的价值不大规则比如历史从未逾期且金额小于X直接发提醒就够了。模型用逻辑回归或者浅层树模型特征重点是历史还款习惯和本次逾期金额占比。第二段DPD 8-30用主力模型。这是兵家必争之地回收率从90%一路掉到50%以下个体差异极大。用LightGBM做回归预测未来7天和14天的回收金额比例同时用一个分类模型预测是否全额回收。特征是账务状态、历史行为、触达响应的组合。这一层的模型效果直接决定账务管理的人力分配效率。第三段DPD 30用分群生存分析。这个阶段的客户要么是能力问题要么是意愿问题回收周期长、不确定性大用普通的回归模型效果一般。我倾向于先分群按历史最大逾期天数、是否有过协商记录、当前失联状态聚类每个群单独建模模型形态用生存分析预测距离下次还款的时间而不是直接预测回收金额。生存分析的好处是能处理删失样本——那些到观察期末都没还款但也没被核销的客户普通回归没法处理生存分析可以。C卡的评估指标也和A/B卡完全不同。AUC在这里意义不大因为排序对了但金额预测错了资源分配还是错。我主要看两个指标回收金额的预测误差MAPE或RMSE和按模型分数分层的实际回收率单调性。后者是关键把客户按模型预测的回收概率分十组实际回收率必须单调递减如果有交叉说明模型的排序在某些区间是错的需要检查那一层的特征。算法方案优势劣势推荐场景逻辑回归WOE可解释、稳定、易维护交互能力弱A卡首选LightGBM单调约束效果好、训练快需解释工具B卡首选多任务学习样本效率高工程复杂B卡样本稀缺时回归分类融合兼顾金额与概率需调融合权重C卡中期层生存分析处理删失、预测时点实现复杂C卡长逾期层4. 特征体系差异三张卡喂的料完全不是一回事特征工程这块我见过最省事的做法是建一个万能特征库三张卡共用。结果就是A卡的特征在B卡上大量缺失因为B卡客户不一定有外部数据授权B卡的行为特征在C卡上区分度极低因为逾期客户的APP活跃度都已经降到冰点。特征体系必须按卡种分别设计共享的只有客户基础画像那一小部分。4.1 A卡静态资质与外部数据A卡的特征体系是申请表单为主干、外部数据为增强、设备信息为补充的三层结构。申请表单里的年龄、职业、收入、学历、婚姻状况这些是基础盘虽然单变量区分度不高KS普遍在0.05到0.12之间但组合起来很稳。外部数据是A卡效果的主要来源包括信用历史、多头申请记录、消费能力评估等这类特征的单变量KS能做到0.15以上。设备信息主要用于反欺诈信用模型里用得少但设备指纹的稳定性、是否root、是否模拟器这些在申请环节是强信号。A卡特征工程的核心难点是缺失值处理。外部数据不是每个客户都能拿到缺失率动辄30%到60%。最粗暴的做法是均值填充这会严重扭曲分布。我的标准做法是把缺失本身当成一个信息每个高缺失率的外部变量都配一个是否缺失的哑变量缺失率本身在业务上是有含义的——拿不到数据往往意味着这个客户在外部体系里的活跃度低风险特征和普通客户不同。实测下来这个哑变量在模型里的重要性往往能排进前20。另一个难点是变量的业务合理性校验。A卡的每个变量都必须在业务上讲得通否则模型评审过不了。我一般会在建模前做一张变量业务说明表每一行写清楚变量名、业务含义、预期方向、数据来源、缺失率、更新频率。这张表看着是文书工作实际是防坑利器。我曾经在一个项目里发现手机号在网时长这个变量的方向是反的——在网时间越长风险越高一查才知道是数据供应商的口径把携号转网的时长重置了导致老客户被算成新客户。没有这张表这个坑要等到上线后才发现。4.2 B卡动态行为序列B卡的特征体系完全是另一个物种。核心是时间窗口聚合同一个行为指标在不同窗口下的含义完全不同。以还款金额为例近1期还款金额反映当期能力近3期还款金额的波动率反映收入稳定性近12期累计还款金额反映整体贡献度首次还款到现在的间隔反映忠诚度。这四个特征在模型里的作用完全不一样不能相互替代。我做B卡特征体系时习惯分五个大类每一类都要有明确的业务假设用信行为类额度使用率、用信频次、单笔金额分布、提现与消费的比例。核心假设是资金饥渴度使用率长期贴着上限的客户风险显著更高。还款行为类还款及时性、最低还款次数、提前还款次数、还款金额波动。核心假设是还款意愿与能力的稳定性这个类别是B卡最重要的特征来源。额度调整类历史提额次数、降额次数、主动申请与被动调整的比例。核心假设是客户与机构的关系质量。渠道与设备类登录频次变化、常用设备切换、操作时段分布。核心假设是账户活跃度异常频繁换设备、深夜登录往往是风险前兆。外部变化类外部多头查询次数变化、关联机构数量变化。核心假设是外部资金压力传导这类特征需要定期更新延迟太高会失效。时间窗口的设定有讲究。我一般用1期、3期、6期、12期四个窗口再配一个全生命周期窗口。窗口不是越多越好每个窗口都会引入一组高度相关的特征反而稀释模型。实际做特征筛选时同质性太高的窗口特征会互相压制重要性最后保留下来的往往是那个区分度最稳定的窗口。我做过统计最终进入模型的B卡特征里3期和6期窗口的占比最高1期太噪声、12期太滞后。提示B卡的特征计算一定要用截至观察点的累计快照方式而不是事后全量重算。后者在离线训练时看不出问题但线上实时打分时算不出来会导致特征穿越。我一般要求特征平台同时提供离线T1快照和线上实时计算两套口径且必须做一致性校验每天比对差异超过阈值就告警。4.3 C卡账务状态与触达响应C卡的特征体系最特殊因为它面对的是一个已经出问题的客户很多常规特征失效了。比如额度使用率逾期客户的这个指标基本都是100%没有区分度比如APP登录频次逾期后客户往往直接卸载APP这个特征也废了。C卡的特征必须围绕回收可能性重新设计。我的C卡特征分四类。第一类是账务状态特征包括当前逾期天数、逾期金额、逾期本金与利息的比例、历史最大逾期天数、历史逾期次数、是否有过协商记录。这类特征是基础盘区分度稳定。第二类是还款行为特征包括历史还款方式的分布自动扣款、主动还款、他人代还、历史还款时点分布工资日后还款还是随机、部分还款的频率。这类特征反映的是还款意愿的稳定性非常重要。第三类是触达响应特征包括历史触达次数、触达渠道偏好、触达后的响应率、上次触达后的还款金额、失联天数。这类特征是C卡独有的直接决定账务管理的动作选择。第四类是外部压力特征包括外部多头查询变化、关联账户异常、司法涉诉信息如有合法数据源。这类特征要慎用数据合规性必须严格把关。这里要特别强调失联特征的处理。失联是C卡最强的负向信号之一但失联的定义在不同团队差异巨大。我的定义是连续N天所有触达渠道均无响应且无任何还款行为N的取值要和账务管理的触达节奏匹配通常设14天或21天。定义清楚之后失联天数的分箱要特别细因为从3天未响应到14天未响应的风险跃升非常陡峭粗分箱会把这个信号抹平。5. 效果评估与上线监控考核口径必须分开设计模型建完评估环节是最容易走过场的地方。我见过太多团队的评估报告就是一页AUC和KS外加一张ROC曲线。这种报告对A卡勉强够用对B卡和C卡基本没有指导意义。三张卡的评估必须分开设计指标组合而且要把离线评估和上线监控当成两件事来做。5.1 区分度与排序性的评估差异A卡的评估以KS为主、AUC为辅、Lift为业务视角的补充。KS的价值在于它反映的是最佳分割点上的区分能力这正好对应审批决策的场景——审批就是找一个阈值把人群切开。AUC反映的是全局排序能力对审批场景的直接指导弱一些但在做额度分层时更有用。我一般要求A卡的KS在0.35以上才算可上线低于0.30的模型基本没有业务价值除非是极低通过率场景通过率低于20%时KS 0.28也可能是有效的。B卡的评估要复杂得多。KS仍然是核心但必须配三个补充指标PSI群体稳定性、迁移率矩阵、分组坏账率的单调性。PSI在B卡上的阈值要比A卡严格因为B卡的人群每个月都在变化PSI超过0.1就要警惕超过0.25基本要触发模型重训。迁移率矩阵是把客户按上期分数和本期分数交叉分组看客户在分数区间之间的流动情况这个矩阵能提前发现整体分数下移这种系统性风险。分组坏账率的单调性是检验模型排序能力的最直接方式把客户按分数分十组实际坏账率必须严格单调任何一组出现交叉都是危险信号。C卡的评估指标最不一样。AUC和KS在这里只能作为参考核心指标是回收金额的提升度和分层回收率的单调性。提升度的算法是把客户按模型分数分组高分组交给重点资源处理低分组交给低成本处理对比全部统一处理的基线计算多回收的金额比例。这个指标直接对应业务价值比任何统计指标都有说服力。我做过的一个项目模型上线后同样的人力投入多回收了约23%的金额靠的就是把高回收概率的客户优先分配给经验丰富的处理人员。卡种核心指标辅助指标上线门槛经验值A卡KSAUC、Lift、变量PSIKS ≥ 0.35B卡KS、PSI迁移率、分组单调性KS ≥ 0.32PSI ≤ 0.1C卡回收提升度分层回收率、MAPE提升度 ≥ 15%5.2 稳定性监控与迭代节奏模型上线只是开始后面是漫长的监控期。三张卡的监控节奏完全不同这个节奏不是拍脑袋定的是由各自的风险暴露周期决定的。A卡的监控主要是前端指标监控。因为A卡的客户刚进来真实的坏账要等6到12个月才暴露你不能等到坏账出来才发现模型坏了。所以A卡的监控靠前端代理指标通过率、拒绝率、分数分布、各分数段的申请量占比、变量的实时PSI。这些指标任何一项出现异常波动都要立即排查。我经历过一次A卡前端PSI突然从0.05跳到0.18排查发现是某个外部数据源的口径调整把一类客户的信用评分整体拉低了问题在坏账暴露前四个月就被发现并修复了。B卡的监控是滚动监控。每个月计算一次模型分数和实际表现更新PSI、KS、迁移率。B卡的优势是反馈快3到6个月就能看到真实表现所以监控的闭环比较短。我的做法是设三级预警PSI超过0.1或KS下降超过15%触发黄色预警做人工复核PSI超过0.25或KS下降超过30%触发红色预警启动模型重训连续两个月黄色预警自动升级为红色。这套阈值不是绝对的要结合客群变化速度调整快消类信贷产品可能要更敏感。C卡的监控是资产包级别的监控。C卡面对的是存量逾期客户客户结构变化相对慢但账务管理策略一调整模型效果就会大幅波动。所以C卡的监控要和策略联动每次账务管理策略变更比如触达频次调整、处理人员分组调整都要重新评估模型的适配性。我曾经遇到过策略从电话为主改成短信为主之后C卡模型的触达响应类特征全部失效模型的排序能力掉了一大截原因很简单——特征是在电话触达的场景下训练的换了渠道特征的业务含义就变了。迭代节奏上A卡通常半年到一年重训一次除非客群结构发生剧变B卡月度或季度重训因为行为和客群变化快C卡按资产包周期重训通常季度级别但策略变更时要临时加做。这个节奏不是死的我在项目里会设一个触发式重训机制只要监控指标触发红线不管有没有到周期都立即重训。6. 实操踩坑实录那些文档里不会写的细节前面五章讲的是方法论这一章讲的是我在实际项目里踩过的、当时没人告诉我的坑。这些坑的共同点是文档里都不会写因为写文档的人要么没遇到过要么遇到了但觉得是常识。但对第一次做三卡项目的人来说每一个都足以让项目延期一个月。6.1 样本穿越与时间穿越最隐蔽的效果杀手时间穿越这事我在三个不同项目里见过三次每次的形式都不一样。第一次是特征里混入了放款后30天内的还款行为这个特征在离线训练时区分度极高因为早还款的客户确实风险低但线上打分时根本拿不到模型等于作弊。第二次是B卡特征计算用了客户当前最新状态而不是观察点当时的状态导致同一个客户在不同观察点的特征完全一样失去了时序意义。第三次最隐蔽是一个外部数据源的更新时间戳和我们的观察点错位了8个小时凌晨的批量任务实际拿到的是第二天更新的数据。排查这类问题的标准动作是特征时间戳审计。每一个特征都要记录它的数据产生时间和可获取时间可获取时间必须严格早于模型决策时间。我在项目里会强制要求特征平台提供这两个时间戳并且在训练前做一次全量校验随机抽1%的样本人工核对特征值在观察点当天是否真的可以拿到。这个校验很枯燥但能省掉后面几个月的返工。另一个相关的坑是标签泄露。最典型的场景是C卡用最终是否核销作为标签但核销决策本身就依赖于模型分数或者账务管理历史这就形成了循环。正确的做法是用未来N期的实际回收金额作为标签核销状态绝对不能出现在标签里。6.2 分箱不稳定与分数漂移A卡的WOE分箱最怕的就是不稳定。训练集上分出来的箱子到验证集上样本量急剧萎缩某些箱子只有几十个样本WOE值波动巨大。我的一般处理是设最小箱样本占比通常要求每箱至少占总样本的3%到5%低于这个比例就和相邻箱合并。合并之后再看单调性如果不单调就检查是不是有特殊的业务逻辑比如收入极高的人群风险反而上升可能是虚报收入或者资金用途异常。分箱不稳定的另一个常见原因是分箱边界选在了数据的高密度区。比如逾期天数这个变量大部分样本集中在0到30天如果边界切在15天稍微有点样本波动就会导致大量样本在相邻箱之间来回跳。我的做法是边界尽量选在数据的自然断点上用决策树或者分位数法先找出候选断点再人工确认业务合理性。分数漂移的排查要分两步。第一步看是输入漂移还是输出漂移把每个变量的PSI算出来如果只有输入指标的PSI高说明是客群结构变了如果输入PSI都正常但分数分布偏移了说明是变量间的关系变了这种更麻烦往往要重新审视模型结构。第二步看是整体漂移还是局部漂移整体漂移通常是业务策略调整导致的局部漂移往往意味着某类客群的行为模式发生了变化需要针对性处理。注意B卡的分数漂移有一个典型的假象——模型分数整体下降但实际坏账率没有上升。这种情况往往是因为客群质量本身在提升比如获客渠道优化了模型把更优质客户打出了更低的分数这不是漂移是正常的分布变化。判断方法是看分数和实际坏账率的对应关系是否还保持单调如果关系没变就不用重训。6.3 三卡联动时的口径打架这个坑只有做过完整闭环的人才会遇到。A卡、B卡、C卡各自建模时口径都对但放在一起用就出问题。最典型的是坏客户定义不一致A卡的坏客户是M3B卡的坏客户是M2C卡统计的是DPD30三个口径混在一起管理层看到的风险客户总数根本对不上。我在项目里会强制推动一件事建立统一的客户状态字典明确每个状态的定义、计算口径、更新频率三张卡都从这个字典取标签。第二个联动问题是分数不可比。A卡分数600分和B卡分数600分的含义完全不同如果业务方把两个分数放在同一个看板上比较就会产生误读。我的做法是给每张卡单独定义一个业务映射比如把A卡分数映射成预期首年坏账率把B卡分数映射成未来6个月违约概率把C卡分数映射成预期回收率。业务方看这三个业务指标比看三个分数直观得多也不会混淆。第三个联动问题是策略冲突。A卡拒绝的客户B卡可能给出高分B卡判为高风险的客户C卡可能认为回收概率很高。这些冲突不是模型错了是三个模型的目标不同。解决方式是建立策略优先级规则申请环节以A卡为准B卡和C卡只作为参考贷中环节以B卡为准但C卡的历史信息可以作为调整项贷后环节以C卡为准。规则要写进策略引擎不能靠人工判断。7. 一些不太成熟但挺有用的经验写了这么多最后分享几个我个人觉得有用、但可能不适合所有人的经验算是给正在做同类项目的朋友一点参考。第一个经验是先用规则跑通再用模型优化。很多团队一上来就要做三张卡做了一年还没上线。我的做法是先上规则引擎用简单的阈值规则把三个环节的决策跑起来同时收集数据。规则阶段的效果肯定不如模型但能让你提前暴露数据质量问题、策略冲突问题、系统集成问题。等数据积累够了再用模型替换规则。这样整个项目的风险是可控的不会出现模型做完了发现数据不能用的尴尬。第二个经验是给每张卡留一条人工兜底的通道。模型再准也有失效的时候尤其是新客群、新场景、新策略上线初期。我会在策略引擎里保留一个人工复核分支模型分数落在某个灰色区间或者触发了特定规则就转人工。这条通道的价值不在于处理了多少量而在于给了模型一个观察期让你能在真实业务中收集反馈而不是一上线就全量执行。第三个经验是模型文档要比你想象中写得更细。我见过太多模型上线一年后没人能说清楚当时的变量为什么这么选、样本为什么这么切。等到要重训或者要审计的时候全靠翻代码和问老人。我现在的习惯是每个模型配一份活文档包含变量业务说明、样本定义、分箱逻辑、评估结果、已知缺陷、变更记录。这份文档不是给评审看的是给未来的自己看的。第四个经验是别把三张卡的团队完全分开。A/B/C卡虽然有差异但底层的特征平台、样本管理、监控工具是可以共用的。如果三个团队各建一套重复建设不说口径还容易打架。我倾向于一个团队负责三张卡或者至少保持密切的横向沟通共享特征库和监控框架各自专注在自己的算法和策略上。最后一个经验是关于心态的。三卡项目最容易让人焦虑的地方是模型效果不够好。但风控这个行当模型效果的边际提升是有天花板的从KS 0.35提升到0.38可能要花三个月但这三个月里如果能把策略优化好、把监控做扎实业务价值可能比那0.03的KS大得多。我现在的判断标准是模型达到业务门槛后就该上线然后靠监控和迭代慢慢打磨而不是在实验室里追求那最后一点点指标。真实世界的风险是动态的一个稳定运行、持续迭代的普通模型胜过一个躺在文件夹里的完美模型。