ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

反欺诈系统的最优欺诈量为何不是零?成本函数与阈值决策解析

反欺诈系统的最优欺诈量为何不是零?成本函数与阈值决策解析 在很多团队的周会上一旦说到“欺诈率上升”风控同学的压力会立刻拉满。产品侧和业务侧的第一反应通常是风控的目标就是把欺诈全拦住最好压到零。但从系统工程的角度看这个目标本身很可能是有问题的。2022 年一篇广为流传的技术短文《The optimal amount of fraud is non-zero》把这个反直觉的结论讲得很清楚一套成熟反欺诈系统的最优欺诈量不应该设为零。这里不是在给欺诈行为开脱。它真正想表达的是反欺诈系统的目标函数不是“最小化欺诈”而是在欺诈损失、误杀成本、人工审核成本和用户体验之间找到平衡点。欺诈率本质上是一个被策略配置出来的结果而不是一个越低越安全的硬性指标。这篇文章会从成本函数和阈值决策两个角度把这个概念拆开来讲。你会看到一个完整的 Python 模拟流程如何构造模拟交易数据、如何定义成本函数、如何通过扫描阈值找到“最优欺诈量”对应的决策点。同时我也会讨论这个思路怎么落到线上风控系统、有哪些常见坑以及团队 KPI 该怎么设计。1. 这篇文章真正要解决的问题先说一个真实场景。某支付团队上线了一个新的风控模型模型分数已经比上一版 AUC 高了不少。运营同学很兴奋直接把拦截阈值调低把“疑似欺诈”的交易全部拦下来。结果一周后人工审核队列爆满正常用户的申诉量翻了 5 倍支付成功率下降了两个百分点用户投诉“我自己的卡为什么付不了款”甚至有一部分用户直接流失。这就是典型的“把欺诈率打到最低”带来的连锁反应。反欺诈系统处理的海量交易绝大多数是正常交易。欺诈交易通常只占极小比例可能是千分之一甚至更低。系统为了拦住这个千分之一的欺诈需要把所有交易都过一遍评分模型。评分模型的输出是一个概率而不是上帝视角。当阈值设置得足够严格时它的确能多拦住一些欺诈但代价是大量正常交易被送进人工审核甚至被直接拒绝。被误杀的用户体验是真实的成本。他们可能不会再回来。所以这篇文章要解决的核心问题不是“怎么把欺诈率降到零”而是“如何用工程方法找到一个欺诈率的最优点”。在这个点上系统的综合成本最低业务体验和资金安全之间的平衡最好。这个点对应的就是“最优欺诈量”。适合读这篇文章的人有两类。一类是做风控、反作弊、内容审核的工程师你们需要新的指标来校准模型和策略。另一类是数据分析和策略产品你们需要理解为什么“欺诈率”不是越低越好以及如何用成本模型去做业务沟通。2. 基础概念误杀与漏放是一对天然矛盾要理解“最优欺诈量”先要理解反欺诈系统里的两个基本错误。第一个叫误杀也就是假阳性。系统把一笔正常交易识别成了欺诈交易拦截下来或者送进人工审核。用户实际上什么都没做错却要经历“支付被拒绝→联系客服→提交证明→等待处理”的流程。第二个叫漏放也就是假阴性。系统放行了一笔真正的欺诈交易等到 24 小时或者更久之后银行拒付、用户投诉、资金损失都已经发生了。用一个混淆矩阵可以表示得更清楚实际情况模型预测为欺诈模型放行真实欺诈交易真正例 TP假负例 FN漏放正常交易假正例 FP误杀真负例 TN真正险的地方在于误杀和漏放是此消彼长的关系。阈值调低代表更多交易会被拦截。欺诈交易更容易被抓住漏放变少但正常交易被误杀的数量会同步上升。阈值调高代表更少交易会被拦截。正常用户体验更好但更多欺诈交易会漏过去。因为它们是一对矛盾所以不可能同时为零。很多人会认为这不是 A/B 两个开关可以通过更好的模型来同时降低。确实模型做得更好可以把整个混淆矩阵向好的方向推但无法消除重叠区域。欺诈交易和正常交易在很多维度上本来就高度相似一个用户换新手机支付大额订单可能是正常消费也可能是盗刷。一个注册 3 个月的账号突然大量下单可能是真实用户也可能是测试卡。数据能给出的区分是概率性的不是确定性的。这就决定了任何一次判断都存在错误成本。最优策略一定是接受一部分错误同时为另一部分错误买单而不是追求某一类错误绝对为零。3. 为什么“零欺诈”在真实业务中不可达从理论角度“零欺诈”可能只存在于模型完全可分、对手完全不变化的假设里。真实业务至少有三层障碍。第一层是信息不完整。欺诈检测依赖特征但特征永远是在交易发生那一刻能拿到的有限信息。我们不知道用户此刻是否在手机屏幕前不知道同一张卡在另外两个 APP 上是否已经被盗刷不知道这笔订单的收件地址是不是新改的。所有特征都只是代理变量不是真相本身。信息不完整意味着模型必然存在不确定性。第二层是对抗性。欺诈者不是静态执行的。他们会根据风控策略调整行为换设备指纹、切换支付通道、控制交易金额、避开深夜下单等风险特征明显的行为模式。当你的策略把某一类行为完全封死时欺诈者会演化出新的绕过方式。你追求“全拦截”实际上是在逼欺诈者寻找新的逃逸路径模型训练的滞后性让这个对抗永远存在。第三层是成本不对称。多拦一笔欺诈交易省下的是这笔交易的损失金额。但如果为了多拦这笔欺诈误杀了 20 笔正常交易就需要承担用户申诉的客服成本、审核人力成本以及一部分用户流失后的长期价值损失。这笔账在一些品类的业务里根本不划算尤其是客单价不高、用户转化非常脆弱的场景。用一个直观的例子来类比。机场安检如果做到“绝对严格”理论上最安全但如果每位旅客都要开箱检查 20 分钟整个机场会因为排队而瘫痪。安检策略必须在“安全”和“通行效率”之间找到平衡。反欺诈系统也是一样欺诈量是平衡出来的结果不是单纯压低出来的结果。4. 核心原理最优欺诈率是一个成本最优点既然零欺诈不可达也不划算那应该怎么决定欺诈率答案是把欺诈率当成一个可以调整的参数用成本函数来寻找最优解。反欺诈系统的总成本可以拆成三个部分总成本 欺诈损失 人工审核成本 误杀衍生成本这三部分分开来看欺诈损失 未拦截欺诈金额 × 损失赔付比例 人工审核成本 (真正例 假正例) × 单笔审核成本 误杀衍生成本 假正例 × 用户流失概率 × 单个用户生命周期价值欺诈损失会随着阈值调低而下降因为更多欺诈交易会被拦截。但人工审核成本和误杀衍生成本会随着阈值调低而上升。这两类成本叠加之后总成本曲线通常是一条 U 型曲线。曲线最低点对应的阈值就是在当前业务参数下的最优决策点。这个点对应的欺诈率就是“最优欺诈量”。在实际建模中成本函数还可以做得更细。比如欺诈损失不是简单的全额损失不同交易类型的欺诈赔付比例不一样人工审核成本不仅包括人力时薪还包括审核等待期间资金占用成本误杀衍生成本还要区分高价值用户和普通用户高价值用户被误杀一次流失概率要高得多。这些细节在离线模拟中可以逐步加进去。关键模型思想是一样的风控决策的本质是最小化期望成本而不是最大化拦截数。理解这一点之后我们就能用代码把整个决策过程自动化。5. Python 实战成本函数驱动的阈值选取下面用 Python 模拟一组伪交易数据展示如何通过“成本函数 阈值扫描”找到最优决策点。所有数据均为模拟构造重点是演示完整思路不是复现某个真实业务。5.1 构造模拟数据假设我们有一个评分模型对每笔交易输出一个 0 到 1 之间的欺诈概率分数。分数越高代表欺诈嫌疑越大。真实业务中模型分通常偏向某一段区间。这里用 Beta 分布模拟“正常交易集中在低分段、欺诈交易集中在高分段”的情况。import numpy as np # 固定随机种子保证结果可复现 np.random.seed(2022) # 业务假设正常交易 9000 笔欺诈交易 1000 笔欺诈率约 10% n_normal 9000 n_fraud 1000 # 正常交易的模型分集中在 0 ~ 0.4 区间 scores_normal np.random.beta(1.3, 8, n_normal) # 欺诈交易的模型分集中在 0.6 ~ 1.0 区间 scores_fraud np.random.beta(8, 1.3, n_fraud) # 合并真实标签和模型分数 y_true np.concatenate([np.zeros(n_normal, dtypeint), np.ones(n_fraud, dtypeint)]) scores np.concatenate([scores_normal, scores_fraud]) # 交易金额正常交易以中小额为主欺诈交易金额偏高 amounts np.concatenate([ np.random.uniform(50, 1500, n_normal), np.random.uniform(500, 5000, n_fraud) ])这里需要注意真实数据中欺诈率通常远低于 10%这里为了演示概率分布和阈值扫描故意把欺诈率调高了。在生产环境做模拟时欺诈率应该使用离线样本中的真实分布否则成本计算结果会产生系统性偏差。5.2 定义成本函数接下来定义三个成本参数# 漏掉一笔欺诈交易按欺诈金额全额计入损失 FN_LOSS_RATE 1.0 # 每笔命中策略的交易需要人工审核单笔成本为 5 元 REVIEW_COST 5 # 每笔被误杀的正常交易用户流失带来的预期损失为 500 元 CHURN_COST 500基于这些参数写一个总成本计算函数def calc_cost(threshold): # 根据阈值判断哪些交易被拦截 pred scores threshold # 漏放的欺诈交易真实标签为欺诈但没有被拦截 fn_mask (y_true 1) (~pred) fraud_loss amounts[fn_mask].sum() * FN_LOSS_RATE # 命中策略的交易无论真假都需要人工审核 hit_count pred.sum() review_cost hit_count * REVIEW_COST # 误杀的正常交易会产生用户流失成本 fp_count np.sum((y_true 0) pred) churn_loss fp_count * CHURN_COST return fraud_loss review_cost churn_loss这个函数是整个决策思路的核心。它把“策略命中”和“真实结果”放到同一个成本框架里计算既考虑了漏放导致的资金损失也把误杀带来的隐性成本量化成了数字。5.3 扫描阈值寻找成本最优点有了成本函数之后用简单的网格扫描方法找出最优阈值# 在 0.01 到 0.99 之间每隔 0.01 扫描一次阈值 thresholds np.arange(0.01, 0.99, 0.01) costs [calc_cost(t) for t in thresholds] # 找到总成本最低的阈值 best_idx int(np.argmin(costs)) best_threshold thresholds[best_idx] best_cost costs[best_idx] print(f最优阈值: {best_threshold:.2f}) print(f最低总成本: {best_cost:.0f})如果希望观察整体趋势可以绘制成本曲线import matplotlib.pyplot as plt plt.figure(figsize(10, 5)) plt.plot(thresholds, costs, lw2) plt.axvline(best_threshold, colorred, linestyle--, labelfbest threshold {best_threshold:.2f}) plt.xlabel(model score threshold) plt.ylabel(total cost) plt.title(Cost curve under threshold scanning) plt.legend() plt.tight_layout() plt.savefig(cost_curve.png, dpi120)5.4 结果分析运行这段代码后你会看到成本曲线呈现明显的 U 型阈值很低时大部分交易被拦截人工审核成本和误杀成本都很高阈值很高时大量欺诈交易被放行欺诈损失迅速上升。曲线最低点对应的阈值就是当前成本参数下的最优欺诈决策边界。真正值得关注的是两件事。第一最优阈值不是两个端点。它既不会无限趋近于 0也不会无限趋近于 1。原因是端点两侧都有不可接受的成本全拦截等于把所有用户都当成欺诈者全放行等于没有风控。第二成本参数的变化会改变最优点的位置。如果把 CHURN_COST 调高代表业务更重视用户体验最优阈值会往高处走也就是更宽松。如果把 FN_LOSS_RATE 调高代表欺诈损失更严重最优阈值会往低处走也就是更严格。这就是为什么“最优欺诈量”不是一个固定数字而是跟随业务环境变化的动态结果。每次模型迭代或者每次业务策略调整都应该重新做一次阈值扫描。6. 从离线最优阈值到线上风控策略离线算出一个最优阈值只是第一步。线上风控系统通常不会只用单一阈值做二分类判断而是会采用“多层策略”分数高于“拒绝阈值”直接拒绝交易。分数介于“拒绝阈值”和“审核阈值”之间进入人工审核队列。分数低于“审核阈值”正常放行。这样可以避免“一刀切”导致的两头损失。高分段交易直接拦截节省审核资源中分段交易用人工兜底避免模型过度自信造成误杀低分段交易保持顺畅体验。一个典型的策略配置可能如下{ strategyName: payment_fraud_v3, modelVersion: fraud_model_v2022, thresholds: { reject: 0.85, review: 0.62, pass: 0.0 }, actions: { reject: 拒绝支付并记录风险事件, review: 进入人工审核队列, pass: 放行 }, notify: [risk-oncall] }这里的 0.85 和 0.62 是示例值。实际取值应该由离线成本模拟和线上回测共同决定。高分段和审核分段的跨度越大人工审核队列的压力越大跨度越小模型直接拒绝的比例越高。线上策略上线前一定要做离线回测。回测的核心逻辑并不复杂就是把策略跑在历史数据上统计总成本def backtest_strategy(events, reject_th, review_th): total_cost 0 for e in events: if e[score] reject_th: # 直接拒绝不算人工审核成本但记录事件 total_cost e[review_cost] elif e[score] review_th: # 进入人工审核 total_cost e[review_cost] if e[true_label] 0: total_cost e[churn_cost] else: # 放行如果真实标签为欺诈则计入欺诈损失 if e[true_label] 1: total_cost e[amount] * e[loss_rate] return total_cost回测要注意两个问题。一是真实标签的延迟很多交易要等 24 小时甚至更久才能被确认为欺诈所以回测时不能只看实时结果必须等标签收敛后再做。二是采样偏差如果离线样本中欺诈比例被人为放大回测成本会失真阈值也会偏离真实最优解。线上灰度同样关键。新阈值可以先覆盖 10% 的流量观察命中率、审核时效、投诉量和交易成功率再逐步放大。发现异常时需要能在一分钟内回滚到旧策略。7. 常见问题与排查思路在实际项目中阈值和成本模型的落地经常会遇到以下几种问题。问题现象可能原因排查方式解决方案线上策略命中率突增但确认欺诈率没有同步上升阈值过严模型分整体漂移对比模型分分布和 7 日/30 日分位数用最近真实样本重新扫描阈值灰度放宽人工审核队列堆积时效超过 SLA中分段交易过多假正例占比高拆分每个规则的单独准确率和命中量增加规则优先级把高误杀规则后置或删除已放行交易中欺诈率上升但整体拦截率不低欺诈者改变手法绕过了现有规则对漏放样本聚类分析特征差异补充新特征和规则加快模型迭代模型分数普遍偏高大量交易进入审核训练样本选择偏差模型未校准绘制分数校准曲线查看预测概率和实际频率用 Platt Scaling 或 Isotonic Regression 校准业务方要求欺诈率降到 0但支付成功率下降目标函数没有对齐只考核单一指标把总成本拆给业务看量化误杀损失将核心指标改为“综合成本”或“每笔有效审核成本”第一个问题在模型迭代后最常见。模型分数分布变了但策略阈值还是老的于是命中量突增。这并不一定是模型变差了而是阈值没有跟着新模型的分布重新适配。每次迭代模型后都建议做一次阈值校准。第二个问题则通常出现在策略叠多了以后。团队为了补漏积累了大量规则每条规则单独看都有一定效果但叠加起来会产生大量不必要的审核。这时候需要做规则去重用统计方法评估每条规则的增量价值。最后一个问题最考验沟通能力。业务方要的是“零欺诈”但你可以用成本计算告诉他们把欺诈率从 1% 压到 0.1%需要多拦截多少正常交易要花多少审核成本会让多少高价值用户流失。数据摆出来之后讨论往往会从“绝对安全”转向“成本最优”。8. 最佳实践与工程建议把“最优欺诈量”的思路落地到工程中有几个值得长期坚持的实践。第一用成本函数统一团队语言。风控、产品、运营对“欺诈率”的理解往往不同。风控关注拦截率产品关注转化率运营关注投诉量。与其在会上争论指标不如把三者统一到一个成本模型里。先定义清楚三档成本参数再讨论阈值和策略。一旦总成本模型被团队接受后续所有策略变更都可以在同一套体系里比较。第二构建自动化的阈值回评流程。阈值不应该靠人工肉眼调整。建议把成本函数固化到离线回测流水线中每次新模型或新特征上线之前自动跑一遍阈值扫描输出推荐阈值和对应的成本预估。把阈值调整变成一个版本化的配置项配合 CI/CD 流程做灰度发布。第三重视人工审核结果的回流。模型训练和成本计算都依赖真实标签。很多团队把人工审核当成“拦截后续处理”却没有把审核结果结构化地存下来也没有回灌到训练样本里。这非常可惜。每次人工审核都是对模型的一次标注应该生成结构化数据用于下一轮训练和成本模型修正。第四建立分层监控指标。除了欺诈率还要同时监控以下指标# 伪代码每日风控核心指标快照 metric { 命中率: 策略命中笔数 / 全部交易笔数, 人工确认欺诈率: 人工审核确认欺诈笔数 / 命中策略笔数, 误杀率: 人工审核为正常交易的笔数 / 命中策略笔数, 漏放率: 事后确认为欺诈但未被命中的笔数 / 确认欺诈总笔数, 用户申诉率: 被拦截用户发起申诉的笔数 / 被拦截总笔数 }单独看任何一个指标都可能失真。例如“命中率很低”看似健康可能意味着大量欺诈交易根本没被系统注意“漏放率很低”也不一定是好事有可能是策略过于宽松把所有可疑交易都放进了“未命中”那部分。站在成本模型的角度看需要同时观察“省下了多少欺诈损失”和“消耗了多少业务成本”。第五生产环境变更必须有安全边界。阈值调整、模型替换、策略规则增删都属于生产变更。建议按照最小权限原则配置操作权限所有变更先在小流量灰度验证并保留一键回滚能力。成本模型里涉及的赔付数据、用户流失预估数据在使用前要确认来源合法、脱敏合规避免把隐私数据直接用于策略计算。第六团队 KPI 不要只考核“拦截量”。如果团队考核指标只有“拦截了多少欺诈交易”那策略一定会往“宁可错杀”的方向倾斜。更合理的 KPI 是“综合损失率”或者“每笔有效拦截成本”同时关注支付成功率和用户申诉率。把多项指标放进同一个框架才能真正约束单指标带来的偏激行为。9. 总结风控的本质不是消灭欺诈而是管理欺诈回到最开始的问题最优欺诈量为什么是非零的因为欺诈是业务环境的一部分而反欺诈系统是一套资源有限的成本系统。没有任何模型可以做到百分之百判断正确任何拦截动作都需要代价。只有当欺诈损失、人工审核成本、误杀衍生成本三者达到最低总成本时系统的整体效果才是最优的。这个结论在实践中意味着三件事。第一欺诈率是一个可配置的工程参数不是一个越低越好的荣誉指标。每次策略迭代都应该重新计算成本最优点。第二团队讨论风控效果时不应该只问“拦住了多少欺诈”还应该问“为了拦住这些欺诈我们付出了什么代价”。第三反欺诈系统的核心能力不只是“识别”还包括“定价”。识别出一笔交易有欺诈概率只是第一步如何为这笔概率定价、如何决定拦截还是放行才是系统设计的关键。如果你正在做风控系统建议把这套成本函数和阈值扫描的思路带到下一次迭代会上去。哪怕只是先从离线数据算出当前的成本曲线也会比单纯讨论“欺诈率又升了”更有价值。建议收藏备用后续做反欺诈或者反作弊模块时直接按这个框架来推导决策边界会省掉很多无效争论。
返回列表