
1. 项目概述一场关于信贷决策的“数据马拉松”2020年的全国大学生数学建模竞赛C题题目是“中小微企业的信贷决策”。这个题目一出来当时我们团队就意识到这绝对是一场硬仗。它不像一些纯算法优化的题目给你一堆数据让你去拟合、去预测就完事了。这道题的核心是把我们这些“象牙塔”里的学生直接推到了银行信贷经理的位置上要求我们基于真实、复杂且充满不确定性的企业数据去构建一套完整的信贷风险评估与决策模型。说白了就是让我们用数学模型去回答一个现实世界里银行每天都在面对的核心问题这笔钱该不该贷该贷多少该收多少利息这道题的价值远远超出了竞赛本身。它精准地切入了当时乃至现在金融科技领域最核心的议题之一——如何利用数据驱动的方法解决中小微企业“融资难、融资贵”的痛点。对于参赛者而言这不仅是一次数学和编程能力的考验更是一次对金融逻辑、商业理解、数据处理和系统化思维的综合锤炼。你需要懂一点财务分析知道哪些指标能反映企业的健康状况你需要懂一点统计和机器学习能从海量数据中挖掘出风险信号你还需要懂一点优化理论能把风险、收益、政策约束变成一个可求解的数学问题。整个解题过程就像完成一个微缩版的金融科技产品开发项目从业务理解、数据清洗、特征工程到模型构建、策略制定、方案评估最后形成一份逻辑严谨、可落地的分析报告。接下来我就结合我们当时的实战经验把这道题的解题思路、核心方法、踩过的坑以及一些独家的建模心得完整地拆解一遍。2. 赛题核心需求与业务逻辑拆解拿到题目后切忌一头扎进数据里。第一步也是最重要的一步是彻底读懂题目在问什么背后的业务逻辑是什么。2020年C题提供了123家有信贷记录的企业和302家无信贷记录企业的数据包括进销项发票信息、信誉评级、是否违约等。题目要求我们解决四个核心问题2.1 问题一信贷风险量化与评级题目要求根据123家企业的发票数据、信誉评级和是否违约记录建立信贷风险模型并对这123家企业进行风险评估。这里的关键在于“量化”。信誉评级A, B, C, D是一个离散的、主观的标签而“是否违约”是一个二分类结果。我们需要做的是构建一个模型能够输出一个连续的、更精细的风险分数或者对原有评级进行验证和细化。注意这里最容易犯的错误是直接拿“是否违约”作为标签去训练一个分类模型比如逻辑回归、随机森林然后直接用模型预测的概率作为风险分数。这忽略了题目中“信誉评级”这个重要先验信息。更合理的思路是将“信誉评级”作为模型的一个重要特征或者将其与违约记录结合构造一个更稳健的监督信号。2.2 问题二与问题三未知企业的信贷策略制定这是题目的核心和难点。对于302家无信贷记录的企业我们需要制定具体的信贷策略包括是否放贷一个二分类决策。信贷额度一个回归或优化问题贷多少钱。贷款利率一个定价问题风险和收益如何权衡。题目还给出了一个非常关键的约束银行的年度信贷总额固定比如1亿元。这意味着我们的决策不是孤立的而是一个资源分配优化问题。你不能给所有低风险企业都批很高的额度因为钱就那么多。必须在所有申请企业中找到一个最优的分配方案使得在总额度限制下银行的整体预期收益最大或风险损失最小。2.3 问题四突发情况疫情下的策略调整题目假设突发情况如新冠疫情对所有企业产生影响但影响程度不同。要求我们分析突发情况对模型和策略的影响并给出调整方案。这考察的是模型的稳健性和可解释性。你不能说“模型失效了重做吧”而必须能说清楚哪些特征可能变得不可靠风险传导的路径是什么如何基于有限的假设进行快速调整2.4 业务逻辑闭环综合来看整个解题过程需要构建一个逻辑闭环数据发票流 - 特征经营指标 - 模型风险分数 - 策略额度/利率 - 优化总额度约束 - 评估与调整突发情况。 每一步都需要有坚实的数学或统计方法作为支撑并且每一步的选择都要有明确的业务解释。3. 数据预处理与特征工程实战题目提供的核心数据是企业的进项和销项发票信息。这是典型的交易流水数据原始数据非常“碎”直接建模几乎不可能。特征工程是这里成败的关键工作量可能占整个项目的60%以上。3.1 发票数据的关键信息提取一张发票通常包含时间、金额、对方企业名称、商品名称等。我们需要从这些流水记录中提炼出能反映企业“经营健康度”和“稳定性”的指标。核心特征构建思路经营规模与活跃度特征交易总额/均值进项总额、销项总额。直接反映业务量。交易频次月度/季度发票张数。反映业务活跃度和稳定性。交易对手数量进项/销项中不同的合作企业数量。反映客户/供应商集中度集中度过高可能有风险。盈利能力与现金流特征这是重点毛利率估算这是一个关键衍生特征。虽然发票没有直接成本但我们可以用(销项总额 - 进项总额) / 销项总额来近似估算毛利率。当然这非常粗糙因为进项和销项在时间上不匹配且包含税费。但作为相对比较指标在大量企业中依然有效。进销项匹配度计算每个时间窗口如月度的“销项/进项”比率。长期远大于1可能虚开发票长期远小于1可能经营萎缩。现金流波动性计算月度净现金流销项-进项的标准差、变异系数。波动越大经营风险可能越高。稳定性与趋势特征季节性/趋势分解对企业的月度交易额进行时间序列分解查看其是否存在稳定的增长趋势、季节性波动或是无规律的随机波动。稳定的增长趋势是加分项。断流检测企业是否存在长时间如超过2个月无任何交易记录的情况这可能是经营中断的危险信号。行业与上下游特征如果数据允许通过对商品名称进行简单的文本分类或关键词匹配可以大致划分企业所属行业如“电子元件”、“纺织服装”。分析其上下游企业交易对手本身的风险特征如果对手也在样本池中。例如一家企业的核心供应商风险很高那么它的风险也会被传导。3.2 数据处理中的“坑”与技巧时间窗口对齐发票日期是精确到日的但我们需要聚合到月或季度。务必注意窗口的起止时间确保每个企业都有可比的时间段。对于新成立或数据缺失的企业要谨慎处理。异常值处理发票数据中可能存在错漏如金额极大或极小的发票。我们当时采用的方法是对于单张发票金额计算其与企业历史交易额均值的差距超过3倍标准差的需要人工复核在比赛中就是根据业务逻辑判断是否剔除。不要盲目删除一笔巨大的进项可能是购买了设备一笔巨大的销项可能是接到了大订单。缺失值处理对于302家无标签企业特征也可能缺失。我们采用了基于同类企业行业、规模相近的均值填充并在特征中增加了一个“是否填充”的布尔标记让模型知道这个信息是估算的。特征标准化由于后续模型涉及距离计算或梯度下降如神经网络必须对连续特征进行标准化Z-score或归一化Min-Max。树模型如随机森林、XGBoost对尺度不敏感但标准化有助于我们理解特征重要性。实操心得特征工程不是一蹴而就的。我们采用的是“构建-评估-筛选”的迭代方式。先基于业务理解构建一大批特征我们当时构建了超过50个然后使用问题一中有标签的数据通过计算特征与目标风险评级/违约的相关性以及用简单的模型如逻辑回归查看系数显著性进行初步筛选。最终保留15-20个解释性强、相关性高的特征进入主模型。4. 核心模型构建从风险预测到策略优化这是整个解题的“发动机”。我们将其拆解为两个核心模型风险预测模型和信贷策略优化模型。4.1 风险预测模型选型与实践目标输入企业的特征向量输出一个连续的风险评分Risk_Score例如0-100分分数越高风险越大。可选模型对比模型优点缺点适用场景逻辑回归可解释性极强系数代表特征影响稳定。线性假设难以捕捉复杂非线性关系。基线模型用于特征初筛和理解。随机森林能处理非线性抗过拟合能力强可输出特征重要性。黑盒模型可解释性差可能忽略特征间细微的线性关系。作为主力预测模型效果通常不错。XGBoost预测精度高能自动处理缺失值有正则化防过拟合。比随机森林更黑盒调参稍复杂。追求预测精度时的首选。神经网络理论上拟合能力最强能学习复杂模式。需要大量数据训练不稳定可解释性最差易过拟合。数据量极大时考虑本题不推荐。我们的方案融合模型我们最终没有只用一个模型。而是采用了一个两阶段融合的方案第一阶段 - 有监督预测使用XGBoost模型以123家企业的“是否违约”为主要标签同时将“信誉评级”作为有序变量A1 B2 C3 D4融入损失函数进行训练得到一个初始风险概率P_default。第二阶段 - 无监督校准考虑到违约样本较少直接用有监督模型预测302家无标签企业可能不稳定。我们引入了无监督的聚类分析如K-Means或高斯混合模型GMM基于特征空间将所有企业包括123家和302家进行聚类。然后观察每个簇中有标签企业的风险分布。如果一个簇里已知的高风险企业多那么这个簇的整体风险权重就调高。最终风险分由P_default和聚类调整因子加权得到。为什么这么做这相当于结合了“经验”有标签数据和“相似度”无监督聚类。即使一个新企业没有任何历史信贷记录只要它的经营模式特征和历史上那些“坏企业”很像它的风险分也会被拉高。这增强了模型的泛化能力和稳健性。4.2 信贷策略优化模型构建有了风险分数接下来就是制定策略。这本质上是一个带约束的优化问题。决策变量对于每个企业i我们需要决定x_i是否放贷0或1a_i信贷额度连续变量r_i贷款利率连续变量通常在一个基准利率上浮动目标函数银行希望最大化总预期收益。Maximize: Σ [ x_i * a_i * (r_i - Cost_of_Capital) * (1 - P_default_i) - x_i * a_i * P_default_i ]解释收益部分 额度 * 利差 * 不违约的概率损失部分 额度 * 违约的概率。P_default_i就是我们从风险模型得到的企业i的违约概率。约束条件总额度约束Σ (x_i * a_i) Total_Credit_Limit题目给出的总额度如1亿。额度上下限Min_Amount a_i Max_Amount 对于不同规模企业额度应有合理范围。利率风险定价r_i Base_Rate Risk_Premium_i。风险溢价Risk_Premium_i应与P_default_i正相关例如Risk_Premium_i k * P_default_i。这保证了高风险高收益。逻辑约束如果x_i 0不放贷则a_i 0。求解方法 这是一个混合整数非线性规划问题直接求解较难。我们做了合理简化将是否放贷x_i和额度a_i的决策分开。先根据风险分数和预期收益用一个排序规则初筛出“值得放贷”的企业池x_i1。在放贷池中将利率r_i表示为风险分数s_i的线性函数代入目标函数。此时问题简化为在总额度约束下对放贷池中的企业分配额度a_i以最大化一个关于a_i的线性或二次目标函数。这可以用经典的线性规划或二次规划求解器如Python的PuLP,CVXOPT高效求解。策略输出求解后我们得到一张清晰的信贷策略表企业ID是否放贷建议额度(万元)建议利率风险等级E001是1005.8%低E002否0-高...............5. 突发情况影响分析与模型调整题目第四问模拟新冠疫情这类系统性冲击。我们的分析框架如下5.1 影响识别系统性冲击不会同等地影响所有企业和所有特征。对特征的影响直接冲击特征如“最近一季度交易额”、“交易频次”可能断崖式下跌。这类特征的当期数据会瞬间“失真”。间接冲击特征如“毛利率”、“现金流波动性”其计算依赖于多期数据影响会滞后并持续一段时间。相对稳定特征如企业长期的“交易对手集中度”、“历史平均规模”可能变化不大。对模型的影响特征分布漂移冲击后数据的统计分布均值、方差与模型训练时所用数据的分布发生显著变化导致模型预测失效。风险关联性变化原本不重要的特征如“是否依赖线下”可能突然成为强风险因子。5.2 调整策略我们不能等有新违约数据了再重新训练模型必须基于假设快速调整。特征重加权这是最快速有效的方法。在原有模型中手动调高那些对冲击敏感的特征的权重。例如在风险评分公式中增加“近期交易活跃度下降比例”这个新特征的权重同时降低“历史年均交易额”的权重。Adjusted_Score α * Original_Score β * Impact_Indicator其中Impact_Indicator可以是行业受冲击系数假设旅游、餐饮行业系数高与近期经营下滑系数的乘积。引入先验规则在模型决策层之上加入规则引擎。例如“如果企业所属行业为受冲击严重行业且近期交易额下降超过50%则无论原模型评分如何将其风险等级临时上调一级并大幅降低授信额度。”压力测试模拟利用历史数据如果有类似冲击时期或蒙特卡洛模拟模拟冲击下企业现金流断裂的概率并将其作为额外的风险因子加入评估。策略的弹性调整信贷策略优化模型中的约束条件需要动态调整。例如总额度不变但可以临时增设“对特定行业的集中度限制”或提高所有企业的利率风险溢价基础值k以覆盖更高的系统性风险。注意事项在论文中阐述这部分时重点不在于你调整得多么精确因为无法验证而在于你的分析逻辑的完整性和合理性。你需要清晰地展示a) 识别了哪些可能受影响的环节b) 提出了哪些具体的、可操作的调整方法c) 解释了这些方法如何缓解冲击带来的问题。6. 建模全流程中的常见陷阱与应对技巧回顾整个解题过程有几个地方特别容易出错这里集中分享一下6.1 数据理解与清洗陷阱陷阱忽视发票数据中的“负数”金额。在实际中负数可能代表红字发票退货、折让。如果直接求和会低估交易额。我们一开始就漏掉了导致一些企业的特征计算错误。应对在数据清洗的第一步就单独统计正负金额分析负数发票的比例和原因。在计算交易总额时使用绝对值求和或净额计算需根据业务含义决定并在论文中说明。陷阱简单按企业ID分组计算特征忽略了集团企业的关联交易。如果两家企业是母子关系或关联公司它们之间的交易可能虚增经营规模。应对这是一个高级技巧。如果时间允许可以对交易对手名称进行模糊匹配或网络分析识别出频繁交易且名称相似的企业群将它们视为一个整体进行风险评估。6.2 特征工程与模型过拟合陷阱构建了大量复杂、高维的特征如各种交互项、多项式特征直接在123条小样本数据上训练复杂模型如深度网络导致严重的过拟合。模型在训练集上表现完美但泛化能力为零。应对特征筛选是必须的使用方差阈值、相关性分析、基于模型的特征重要性如XGBoost的feature_importances_进行筛选。坚决使用交叉验证在123条数据上采用留一法或5折交叉验证来评估模型性能而不是看训练集准确率。优先选择简单模型在数据量小时逻辑回归加精心构建的特征其效果和可解释性往往优于一个过拟合的黑盒模型。6.3 优化模型求解的可行性陷阱设计的优化模型过于复杂如非线性、非凸自己无法求解或者求解时间过长。应对一定要做简化像我们前面做的那样将是否放贷和额度分配分步进行。先用一个清晰的规则如风险分数低于阈值且预期收益为正筛选出候选集大大减少决策变量。验证解的质量对于求出的解要检查其是否满足所有约束条件。可以设计一个简单的贪婪算法作为基线例如按“单位风险收益比”从高到低分配额度对比优化解的效果证明优化是有效的。利用成熟求解器Python的PuLP对接多种开源/商业求解器或SciPy.optimize对于线性/二次规划问题非常可靠代码也简洁。6.4 论文写作与结果展示陷阱论文通篇是模型公式和代码没有业务解释或者结果只有一堆数字表格没有可视化。应对每一部分都要有“为什么”为什么选这个特征为什么用这个模型为什么这样设定约束这是评委最看重的逻辑链。可视化是关键企业风险得分的分布直方图、特征重要性条形图、额度分配前后的对比饼图、聚类结果散点图……一图胜千言。使用Matplotlib或Seaborn制作清晰、专业的图表。结果要可解释对于最终的信货策略表可以附上一些典型企业的案例分析。例如“企业E123因其毛利率持续下滑且交易波动大被模型评为高风险故不予授信。”这能让你的模型结果落地。最后想说的是数模竞赛和真实的数据科学项目一样没有唯一的标准答案。我们的这套方案——融合模型、两阶段优化、系统性风险分析——只是众多可行路径中的一种。它的优势在于逻辑层次清晰兼顾了监督与非监督学习并且将业务约束很好地融入了数学建模。在实际比赛中更重要的是你思考的深度、解决问题的完整度以及将复杂问题清晰呈现的能力。这道题就像一个微缩的金融科技沙盘走完一遍你对如何用数据驱动商业决策会有完全不一样的理解。