尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

QUBO模型在金融风控阈值优化中的应用与量子计算求解实践

QUBO模型在金融风控阈值优化中的应用与量子计算求解实践 1. 赛题核心量子计算时代的金融风控新范式最近和几个做金融科技和算法优化的朋友聊天话题总绕不开一个词QUBO。这个词在组合优化圈子里火了好几年但真正让它“破圈”的是2023年MathorCup数学建模挑战赛的A题。这道题直接把“量子计算机”和“信用评分卡”这两个看似八竿子打不着的领域拧在了一起让很多参赛队伍直呼“脑洞大开”。我仔细研究了这道赛题发现它远不止是一道竞赛题更像是一份来自未来的“技术预言”精准地指向了金融风控领域一个即将到来的变革利用量子计算或量子启发式算法解决传统方法难以处理的复杂组合优化问题。简单来说这道题的核心是如何用QUBO模型来优化信用评分卡的阈值组合从而最大化风控收益信用评分卡大家都不陌生银行、消费金融公司用它来评估客户违约风险决定是否放贷、给多少额度。传统的阈值设定比如“分数低于600分拒绝”往往是基于业务经验或简单的单变量分析很难全局最优。而QUBO二次无约束二进制优化模型则是量子计算和某些专用硬件如退火机最“爱吃”的数学形式。把评分卡阈值优化问题“翻译”成QUBO模型就意味着我们有可能借助更强大的计算范式在海量的阈值组合中找到那个真正的最优解。这背后的驱动力正是像Intel、IBM等巨头在量子计算硬件上的持续进展以及像“小米笔记本电池充电阈值设置”这类大众产品功能所普及的“阈值管理”概念。前者提供了新的算力可能后者则让“动态阈值优化”的理念更加深入人心。所以这道赛题不仅考察数学建模能力更是在引导我们思考当量子计算从实验室走向应用哪些行业的哪些痛点会最先被解决金融风控无疑是一个绝佳的试验场。2. 问题拆解从业务场景到QUBO公式的“翻译”过程要理解这道题我们不能只盯着最后的数学公式必须从真实的金融风控业务逻辑出发一步步推导。这个过程就是建模的核心魅力。2.1 信用评分卡与阈值优化的业务逻辑假设我们有一张信用评分卡它会为每个申请客户打出一个分数比如300-850分。风控策略需要设定一个或多个阈值将客户分到不同的处理通道。一个最简单的策略是设定一个拒绝阈值T分数低于T的客户直接拒绝高于T的客户通过。但现实要复杂得多。更精细的策略会采用多阈值策略。例如分数 T1: 拒绝高风险T1 ≤ 分数 T2: 人工审核中风险分数 ≥ T2: 自动通过低风险这里T1和T2就是我们需要优化的决策变量。不同的阈值组合会产生完全不同的业务结果拒绝太多好客户误拒会损失利润放过太多坏客户误通过会增加坏账损失。我们的目标就是找到一组(T1, T2)使得总利润或综合收益最大化。赛题通常会提供一份历史数据样本包含每个客户的“分数”和“真实标签”好客户/坏客户。有了数据我们就可以量化评估任何一个阈值策略的效果。2.2 构建目标函数利润如何计算这是建模的关键一步。我们需要定义一个数学上的“目标函数”它能够精确计算任一阈值策略下的总利润。通常利润来源于好客户产生的收益如利息收入成本则包括坏客户造成的损失本金损失以及运营成本如人工审核成本。我们可以这样定义通过一个好客户获得收益R_good。误通过一个坏客户产生损失L_bad。人工审核一个客户产生成本C_review。拒绝一个客户无直接收益和成本但可能有机会损失。对于一个给定的阈值策略(T1, T2)我们可以根据历史数据统计出N_good_auto: 自动通过的好客户数N_bad_auto: 自动通过的坏客户数N_good_review: 进入人工审核的好客户数N_bad_review: 进入人工审核的坏客户数N_good_reject: 被拒绝的好客户数误拒N_bad_reject: 被拒绝的坏客户数正确拒绝假设人工审核可以完美识别客户好坏这是一个简化假设赛题中可能需要考虑审核准确率那么审核后的好客户会被通过坏客户会被拒绝。那么总利润P可以表示为P R_good * (N_good_auto N_good_review) - L_bad * N_bad_auto - C_review * (N_good_review N_bad_review)我们的目标就是找到使P最大的T1和T2。注意这里的收益R_good、损失L_bad、成本C_review是核心业务参数。它们的取值往往比模型本身更重要需要与业务部门反复确认。一个常见的坑是直接使用历史平均收益而忽略了不同客户群、不同产品的收益差异。2.3 引入QUBO为什么以及如何做到目前为止这还是一个传统的优化问题。为什么非要引入QUBO呢原因在于问题的组合爆炸本质。如果分数是离散的例如0-1000分那么T1和T2的候选值各有1001种可能假设分数为整数。简单的网格搜索需要计算1001 * 1001 ≈ 100万次目标函数。这看起来还能接受。但如果我们的策略更复杂包含5个、10个阈值呢或者分数精度更高呢组合数量将呈指数级增长传统算法如穷举、动态规划会很快遇到计算瓶颈。QUBO模型的优势在于它提供了一种将这类离散组合优化问题“标准化”的框架。许多专用硬件如量子退火机D-Wave、相干伊辛机CIM以及一些基于CMOS的数字化退火芯片都是为高效求解QUBO问题而设计的。Intel在量子计算方面的进展也包括了对量子比特和量子处理单元的研究旨在未来更高效地处理这类问题。如何将阈值优化转化为QUBO核心思路是使用二进制变量来表示决策。假设分数范围为[0, M]我们可以为每一个可能的分数值s引入一个二进制变量x_s。x_s 1表示分数为s的客户被“自动通过”。x_s 0表示分数为s的客户“未被自动通过”即进入审核或被拒绝。但这还不够因为我们需要区分“审核”和“拒绝”。一种经典方法是引入两组变量或通过约束来定义阈值。更巧妙且符合QUBO“无约束”特点的方法是用二进制变量的顺序性来隐含定义阈值。我们可以定义对于所有分数sx_s表示该分数段客户是否应被“接受”包括自动通过和审核后通过。那么一个合理的策略必然具有单调性如果分数s的客户被接受那么分数高于s的客户更应该被接受。即x_s应该是一个关于s的非递减序列从0变为1后就不再变回0。这个从0到1的跳变点就是我们的拒绝阈值T1。为了引入第二个阈值区分自动通过和人工审核我们可以定义第二组二进制变量y_s表示分数为s的客户是否“无需审核直接通过”。同样y_s也应该是非递减的并且显然有y_s ≤ x_s只有被接受的客户才可能被自动通过。这样y_s从0到1的跳变点就是T2。接下来我们需要将利润目标函数P用这些二进制变量x_s,y_s重新表达。这需要根据历史数据统计每个分数s下的好/坏客户数量g_s,b_s。然后利润函数可以写为P Σ_s [ R_good * g_s * x_s - L_bad * b_s * y_s - C_review * g_s * (x_s - y_s) ... ]这里(x_s - y_s)就代表了进入审核的好客户。对于坏客户部分公式会稍复杂需要仔细考虑审核环节对坏客户的拦截效果。最后也是最关键的一步将最大化利润P转化为最小化一个二次型H。因为QUBO的标准形式是min x^T Q x。这通常通过令H -P来实现。同时我们必须将之前提到的单调性约束x_s ≤ x_{s1},y_s ≤ y_{s1}和包含关系约束y_s ≤ x_s也以惩罚项的形式加入到H中。例如约束x_s ≤ x_{s1}可以转化为惩罚项λ * (x_s - x_{s1})^2当x_s1且x_{s1}0时该惩罚项为正从而鼓励解满足约束。惩罚系数λ需要足够大以确保约束在最优解中被严格遵守。至此我们成功地将一个业务问题“翻译”成了一个标准的QUBO模型准备好交给适合的求解器了。3. 求解策略从经典算法到量子启发模型建好了怎么求解这是赛题的第二大难点也是区分队伍水平的关键。我们面临的是一个NP-Hard的组合优化问题没有绝对意义上的“最快”解法只有针对不同场景的“更合适”的解法。3.1 经典精确算法穷举、动态规划与整数规划对于小规模问题例如分数分段不多阈值数量少我们完全可以使用经典精确算法来获取全局最优解以此作为基准答案。网格搜索/穷举法最简单粗暴。遍历所有可能的阈值组合计算目标函数值。当阈值数量为2分数有N种可能时复杂度为O(N²)。一旦阈值增多立即不可行。实操心得在正式尝试复杂算法前先用穷举法计算小规模样例可以验证你目标函数和QUBO转化代码的正确性这个基准非常重要。动态规划对于具有最优子结构的问题DP是利器。在本问题中我们可以定义状态dp[i][k]表示在前i个分数段中设置了k个阈值或处于第k个决策区间时的最大利润。通过状态转移可以在O(K*N²)复杂度内求解其中K是阈值区间数。这比穷举快很多且能得到精确解。整数规划使用Gurobi、CPLEX等商业求解器直接将问题建模为混合整数线性规划。这些求解器内置了强大的分支定界和割平面算法对于中等规模的问题非常有效。注意事项直接求解QUBO模型对应的整数二次规划可能效率不高最好利用问题的特殊结构如单调性建立更高效的MIP模型。3.2 元启发式算法模拟退火、遗传算法当问题规模变大精确算法失效时元启发式算法是首选。它们不保证找到全局最优但通常能在合理时间内找到高质量近似解。模拟退火这几乎是求解QUBO的“标配”经典算法。它的灵感来源于固体退火过程通过引入“温度”参数来控制接受劣解的概率从而有机会跳出局部最优。对于我们的问题邻域操作可以设计为随机选择一个阈值将其微调增加或减少1分。参数调优心得初始温度、降温速率、马尔可夫链长度是三大关键参数。一个实用的技巧是先进行多次快速试跑观察目标函数下降曲线据此调整参数。初始温度应设置得足够高使得初期有大约50%的概率接受劣解。遗传算法将阈值组合编码为一条“染色体”如一个整数数组。通过选择、交叉、变异操作来演化种群。实操技巧编码方式很重要。直接编码阈值分数值可能不是最好的因为交叉操作容易产生无效解如阈值顺序错乱。可以考虑编码阈值之间的间隔或者采用“随机密钥”编码。适应度函数就是我们的利润函数P。3.3 量子启发与专用硬件求解这才是赛题最前沿的部分也是呼应“量子计算机”这个热词的关键。量子退火如果你能访问D-Wave的量子退火机或其Leap云服务那么你可以直接将构建好的QUBO矩阵Q提交上去求解。量子退火利用量子隧穿效应来寻找能量最低态即我们的H最小态。重要提示由于当前量子比特数量有限且存在噪声通常需要将一个大问题“嵌入”到硬件连接图中这可能涉及链式耦合等复杂操作。对于这道赛题规模的问题很可能用经典模拟退火器就能很好解决但使用量子退火的过程本身极具学习价值。数字退火/相干伊辛机如富士通的数字退火机、东京大学的CIM。它们用经典或光量子模拟伊辛模型的行为来求解QUBO。与量子退火相比它们可能在某些问题上更稳定或更快。量子启发经典算法例如模拟退火本身就是受物理过程启发。还有禁忌搜索、粒子群优化等。这里特别提一下模拟分岔算法它是一种受量子力学启发的经典算法在求解大规模QUBO问题上显示出不错的速度。踩坑实录初次接触量子计算求解时很容易陷入“为了用量子而用量子”的误区。必须明白对于小规模问题经典算法通常更快、更准。量子计算的优势在于解决特定类型的、规模极大的组合优化问题。在比赛中更务实的做法是用经典算法如模拟退火作为主力求解器然后探讨如果问题规模扩大如评分维度增多从单卡到多卡组合量子计算将如何提供潜在的算力突破。这样既体现了对前沿技术的理解又保证了解决方案的落地性。4. 模型实现与结果分析全流程理论说得再多不如一行代码。这里我以一个简化的示例勾勒出从数据处理到结果输出的完整流程。假设我们有一份包含score分数和label1为好客户0为坏客户的历史数据CSV文件。4.1 数据预处理与统计第一步不是建模而是看数据。import pandas as pd import numpy as np # 读取数据 data pd.read_csv(credit_data.csv) # 假设分数范围为0-1000我们将其离散化为整数 data[score_bin] data[score].round().astype(int) # 确保分数在范围内 data[score_bin] data[score_bin].clip(0, 1000) # 按分数分组统计好坏客户数 stats data.groupby(score_bin)[label].agg([count, sum]).reset_index() stats.columns [score, total, good] stats[bad] stats[total] - stats[good] # 定义业务参数 R_good 1.0 # 通过一个好客户的收益 L_bad 5.0 # 误通过一个坏客户的损失 C_review 0.2 # 审核一个客户的成本 # 假设人工审核能100%识别坏客户审核通过的好客户比例设为100% review_good_pass_rate 1.0 review_bad_reject_rate 1.0这一步至关重要。你需要检查分数分布是否均匀好坏客户的分布情况。通常好客户的分布会偏向高分区域。画出分布图能给你直观感受。4.2 构建并求解QUBO模型我们采用模拟退火作为求解器使用dimod库来构建QUBO。import dimod from neal import SimulatedAnnealingSampler def build_qubo(stats, R, L, C, M1000): 构建QUBO模型。 stats: 按分数统计的数据框 R, L, C: 收益、损失、成本参数 M: 惩罚项系数需要足够大 # 初始化QUBO字典键为 (变量名1, 变量名2)值为系数 Q {} N len(stats) # 分数段数量 # 定义变量名x0, x1, ..., x_{N-1} 和 y0, y1, ..., y_{N-1} x_vars [fx{i} for i in range(N)] y_vars [fy{i} for i in range(N)] # 1. 构建目标函数部分 (-利润) for i, row in stats.iterrows(): s i # 分数索引 g, b row[good], row[bad] # 对于x_s变量好客户收益为正贡献坏客户在审核环节被拦截无直接损失但有人工成本 # 利润中x_s对应的好客户收益为 R*g审核成本为 -C*g (如果x_s1且y_s0) # 在QUBO中我们需要最小化 -利润所以符号反转。 # 线性项x_s 的系数 Q[(x_vars[s], x_vars[s])] Q.get((x_vars[s], x_vars[s]), 0) - R * g C * g # 注意审核成本项-C*g*x_s 已经包含在上面的线性项中当x_s1时产生成本。 # 但审核成本只发生在 x_s1 且 y_s0 时所以我们需要一个交叉项来抵消当y_s1时的成本。 # 交叉项C*g*x_s*y_s Q[(x_vars[s], y_vars[s])] Q.get((x_vars[s], y_vars[s]), 0) C * g # 对于y_s变量自动通过坏客户带来损失 Q[(y_vars[s], y_vars[s])] Q.get((y_vars[s], y_vars[s]), 0) L * b # 2. 添加约束惩罚项 # 约束1: 单调性 x_i x_{i1} 惩罚 (x_i - x_{i1})^2 当 x_i1, x_{i1}0 for i in range(N-1): # (x_i - x_{i1})^2 x_i^2 x_{i1}^2 - 2*x_i*x_{i1} Q[(x_vars[i], x_vars[i])] Q.get((x_vars[i], x_vars[i]), 0) M * 1 Q[(x_vars[i1], x_vars[i1])] Q.get((x_vars[i1], x_vars[i1]), 0) M * 1 Q[(x_vars[i], x_vars[i1])] Q.get((x_vars[i], x_vars[i1]), 0) - 2 * M # 约束2: 单调性 y_i y_{i1} for i in range(N-1): Q[(y_vars[i], y_vars[i])] Q.get((y_vars[i], y_vars[i]), 0) M * 1 Q[(y_vars[i1], y_vars[i1])] Q.get((y_vars[i1], y_vars[i1]), 0) M * 1 Q[(y_vars[i], y_vars[i1])] Q.get((y_vars[i], y_vars[i1]), 0) - 2 * M # 约束3: 包含关系 y_i x_i 惩罚 (y_i - x_i)^2 当 y_i1, x_i0 for i in range(N): # (y_i - x_i)^2 y_i^2 x_i^2 - 2*y_i*x_i Q[(y_vars[i], y_vars[i])] Q.get((y_vars[i], y_vars[i]), 0) M * 1 Q[(x_vars[i], x_vars[i])] Q.get((x_vars[i], x_vars[i]), 0) M * 1 Q[(y_vars[i], x_vars[i])] Q.get((y_vars[i], x_vars[i]), 0) - 2 * M return Q, x_vars, y_vars # 构建QUBO Q_matrix, x_list, y_list build_qubo(stats, R_good, L_bad, C_review, M1000) # 转换为dimod的BinaryQuadraticModel bqm dimod.BinaryQuadraticModel.from_qubo(Q_matrix) # 使用模拟退火求解 sampler SimulatedAnnealingSampler() sampleset sampler.sample(bqm, num_reads1000, num_sweeps1000) # 获取能量最低的解即最优解 best_sample sampleset.first.sample这段代码构建了完整的QUBO模型并求解。关键点在于惩罚系数M的选取。如果M太小约束可能被违反如果M太大可能会掩盖目标函数导致找到的解虽然满足约束但利润很低。一个经验法则是M应显著大于目标函数中系数的绝对值范围。可以通过尝试不同的M值检查约束是否满足来调整。4.3 解的解释与后处理求解器返回的是0/1变量序列我们需要将其还原为业务策略。def interpret_solution(best_sample, x_vars, y_vars, stats): 将求解器的二进制解解释为阈值和策略。 x_values [best_sample[var] for var in x_vars] y_values [best_sample[var] for var in y_vars] # 寻找跳变点 T1 None # 拒绝阈值 (x从0变1) T2 None # 自动通过阈值 (y从0变1) for i in range(1, len(x_values)): if x_values[i-1] 0 and x_values[i] 1: T1 stats.iloc[i][score] # 使用对应的分数值 break for i in range(1, len(y_values)): if y_values[i-1] 0 and y_values[i] 1: T2 stats.iloc[i][score] break # 计算该策略下的利润 profit calculate_profit(T1, T2, stats, R_good, L_bad, C_review) return T1, T2, profit, x_values, y_values def calculate_profit(T1, T2, stats, R, L, C): 根据阈值T1, T2计算利润 profit 0 for _, row in stats.iterrows(): s row[score] g, b row[good], row[bad] if s T1: # 拒绝区无收益无成本忽略机会成本 pass elif T1 s T2: # 审核区好客户通过产生收益但产生审核成本坏客户被拦截。 profit R * g - C * (g b) else: # s T2 # 自动通过区好客户收益坏客户损失。 profit R * g - L * b return profit T1_opt, T2_opt, profit_opt, x_opt, y_opt interpret_solution(best_sample, x_list, y_list, stats) print(f最优拒绝阈值 T1: {T1_opt}) print(f最优自动通过阈值 T2: {T2_opt}) print(f预估总利润: {profit_opt:.2f})结果分析要点阈值合理性检查得到的T1和T2是否在业务可接受的范围内。例如T2是否远高于T1如果两者非常接近可能意味着人工审核环节的价值不大需要反思成本C_review的设置是否合理。利润对比与单一阈值策略、或基于业务经验的策略进行利润对比量化优化带来的提升。稳定性测试使用交叉验证将数据分为训练集和测试集在训练集上优化阈值在测试集上验证利润。防止过拟合。敏感性分析改变业务参数R_good,L_bad,C_review观察最优阈值的变化。这能告诉业务方利润对哪些参数最敏感为调整业务策略提供依据。5. 延伸思考与避坑指南这道赛题像一个引子打开了一扇门。在实际应用和比赛深化中有几个方向值得深入。5.1 模型复杂化更贴近现实多张评分卡融合现实风控往往使用多个模型A卡、B卡、C卡或融合多个特征。此时决策不再是单维度的分数而是一个多维空间。QUBO模型可以扩展为每个维度或每个卡设置阈值变量数量会急剧增加这正是量子计算可能发挥优势的地方。审核准确率非100%更现实的假设是人工审核或次级模型有一定误判率。这需要在目标函数中引入条件概率使模型更复杂但更精确。引入不确定性客户的收益和损失可能不是固定值而是服从某种分布。可以引入随机规划或鲁棒优化的思想。5.2 常见问题与排查技巧问题QUBO求解结果不满足约束如x序列不单调。排查首先检查惩罚系数M是否足够大。可以逐步增大M直到所有解都满足约束。技巧在计算目标函数利润前先写一个校验函数检查解的有效性。无效解直接赋予一个极差的利润值或极高的能量值。根源有时是目标函数与约束惩罚的量级不匹配。可以尝试对目标函数进行缩放使其与惩罚项处于同一数量级。问题模拟退火结果不稳定每次运行找到的解差异很大。排查增加num_reads采样次数和num_sweeps退火步数。num_reads相当于从不同初始点开始多次退火取最好结果。技巧实施“退火计划”。不要用默认的线性降温尝试指数降温或自定义的温度序列。初始温度要足够高让系统能充分“探索”。进阶考虑使用并行退火或采用更高级的元启发式算法如禁忌搜索。问题模型求解速度慢尤其是分数分段很多时。优化目标函数计算是瓶颈。利用向量化操作避免在Python循环中进行逐分数计算。使用numpy进行矩阵运算。降维原始分数可能有1000个点可以先进行等频或等宽分箱将分数段聚合到50-100个区间大幅减少变量数。优化后再在更细的粒度上微调。硬件使用更快的求解器如富士通数字退火机的SDK或调用GPU加速的模拟退火库。问题业务方不理解或质疑QUBO/量子计算的结果。沟通避免一上来就大谈量子比特。用他们能懂的语言“我们使用了一种新的优化算法可以在海量策略组合中更快更准地找到利润最高的风控规则。”可视化绘制利润随阈值变化的等高线图或三维曲面图将QUBO找到的最优点标注在上面与传统网格搜索的结果对比直观展示其优越性。A/B测试提出小流量的线上A/B测试方案用数据证明新策略的有效性。这是最有力的说服方式。5.3 从赛题到现实应用的鸿沟比赛模型是高度简化的。真实应用必须跨越几道鸿沟数据质量与分布偏移历史数据的分布是否代表未来模型上线后客群变化、经济周期波动都会影响阈值效果。需要建立动态更新阈值的机制。多目标权衡我们只优化了利润。现实中还要考虑通过率、坏账率、监管合规、客户体验等多个目标。这需要引入多目标优化甚至将部分目标作为约束条件。系统集成优化出的阈值如何集成到实时风控决策引擎中需要一套可靠的配置管理和发布回滚机制。这道MathorCup赛题的价值就在于它用一个清晰的框架揭示了组合优化在金融风控中的巨大潜力并指明了QUBO模型这一通往未来算力量子计算的桥梁。它要求参赛者不仅要有扎实的数学建模和编程能力更要有将前沿计算范式与古老金融问题相结合的想象力。处理这类问题我个人的体会是永远要从业务本质出发让技术为业务目标服务而不是相反。先用手头的数据和经典方法构建一个可靠的基线再去探索量子启发等新方法带来的增量价值这样的路径才最踏实也最容易产出真正有影响力的成果。
返回列表