ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

数学建模竞赛:中小微企业信贷决策的建模思路与Python实现

2026/9/5 10:59:34 拓冰建站 浏览量
数学建模竞赛:中小微企业信贷决策的建模思路与Python实现 简介本资源是2020年全国大学生数学建模竞赛C题“中小微企业信贷决策”的完整参赛成果包面向数学建模参赛学生、金融数据分析初学者及毕业设计阶段的本科生聚焦小微企业风控建模这一典型商业实战问题。压缩包共160个文件含60个xlsx与csv格式的原始及处理后数据集如train.csv、test.csv、42个txt日志与参数说明、26个jpg/png图表含特征重要性图、预测对比图等、10个MATLAB核心算法脚本m文件、5个Word论文文档含主论文与神经网络专项说明整体大小248.35MB结构清晰、模块可溯。已有659人学习下载提供从数据清洗、特征工程、多模型构建线性回归、决策树、神经网络到交叉验证与结果可视化的全流程实现附带可编辑论文与可运行代码便于复现、调试与课程设计拓展应用。1. 项目概述与核心价值如果你正在准备数学建模竞赛尤其是涉及经济、金融或数据分析类的题目那么“中小微企业信贷决策”这个赛题绝对是一个绕不开的经典案例。它源自2020年全国大学生数学建模竞赛的C题之所以至今仍被反复研究和讨论是因为它完美地融合了数学建模的核心思想与金融风控的现实需求。简单来说题目给出一批虚构的中小微企业及其相关经营数据要求参赛者建立数学模型评估这些企业的信贷风险并制定合理的信贷策略比如决定给谁贷款、贷多少、利率怎么定。这听起来像是银行信贷部门的工作实际上这正是数学建模的魅力所在——用数学工具解决一个真实的、复杂的系统工程问题。我当年带队参赛时就对这道题印象极深。它不像一些纯理论优化题它的每一个决策都牵扯到收益与风险的平衡你需要同时扮演数据分析师、风险模型师和策略经理多个角色。最终提交的成果通常是一篇结构严谨的Word论文和一套能跑出结果的源代码多是MATLAB或Python。对于新手而言直接看优秀论文和源代码是最高效的学习路径你能瞬间明白一个完整的解决方案是如何从问题分析、模型构建、算法实现到结果可视化的。但更重要的是你要理解这套代码和论文背后的建模思想与业务逻辑这才是能举一反三、应用到其他赛题甚至未来工作中的关键。2. 赛题深度解析与建模思路拆解2.1 问题本质在不确定性中寻求最优决策我们先抛开“数学建模”这个术语用最直白的话理解这个题你是一家银行的负责人面前有123家中小企业题目中编号为1-123的贷款申请。你手里有它们连续4年2016-2019的一些关键财务数据比如营业收入、应收账款、存货、利润等等。你的任务是风险评估量化每家企业的违约可能性信用评分。信贷决策在银行总信贷额度固定比如1亿元的前提下决定给哪些企业放贷、各自的贷款额度是多少、年利率定为多少。策略优化使得银行的总收益利息收入尽可能高同时将坏账损失风险控制在可接受范围内。这本质上是一个带有约束条件的优化问题。约束包括总资金量、监管要求如对某些高风险企业的限制、以及你自身对风险承受的设定。目标函数就是银行的最终利润。难点在于企业的“风险”是一个无法直接观测的隐藏变量你需要从那些财务数据中把它“挖”出来。2.2 核心建模思路一个经典的“流水线”框架解决这类问题成熟的思路通常遵循一个分层递进的流程我把它称为“信贷决策建模流水线”第一层企业信用评价这是整个模型的基石。目标是将企业的多维财务数据如盈利能力、偿债能力、运营效率、发展能力综合成一个单一的信用分数或等级。常用方法有主观赋权法如层次分析法AHP。你需要构建一个评价指标体系例如一级指标盈利能力、偿债能力二级指标销售利润率、资产负债率等然后通过两两比较判断矩阵来确定各指标的权重。这种方法依赖于专家经验在赛题中常用于体现评价体系的构建过程但主观性较强。客观赋权法如熵权法Entropy Weight Method、TOPSIS法。熵权法根据各指标数据本身的离散程度信息熵来确定权重数据差异越大该指标权重越高。TOPSIS法则通过计算每个企业到理想解和负理想解的距离来排序。这类方法完全由数据驱动客观性强在数学建模中非常受欢迎。现代机器学习方法如逻辑回归Logistic Regression、随机森林Random Forest、XGBoost等。你可以将企业是否违约题目可能需要你根据历史数据或规则进行界定作为标签财务指标作为特征训练一个分类模型来预测违约概率。这种方法预测能力强但需要一定的数据预处理和模型调优知识。在实际的优秀论文中经常看到组合模型比如先用熵权法确定指标权重再用TOPSIS进行排序评分最后用聚类分析如K-means将企业划分为“A优质、B中等、C风险”等不同信用等级。这样既保证了客观性又使得结果易于理解和后续处理。第二层信贷额度与利率定价模型有了信用等级下一步就是“区别对待”。基本原则是信用好多贷款、低利率信用差少贷款、高利率风险补偿。额度模型通常基于企业的实际资金需求如营收规模、资产规模和信用等级来确定。一个简单的思路是设定一个基础额度公式如额度基数 f(企业规模指标)然后用信用等级系数进行调节最终额度 额度基数 × 信用等级系数。信用等级系数ABC。利率定价模型这涉及到风险收益匹配。常见方法有基准利率加成法贷款利率 无风险利率 信用风险溢价。其中信用风险溢价与企业的信用评分或等级挂钩信用越差溢价越高。你也可以构建一个更复杂的函数让利率随信用评分连续变化。第三层投资组合优化模型这是最体现数学建模功力的部分。即使你给每个企业都算出了额度和建议利率但银行的钱是有限的不可能满足所有申请。你需要从所有企业中选择出一个子集并分配具体的贷款额使得总收益最大、总风险最小。 这天然是一个多目标优化问题。两个核心目标最大化总收益总收益 Σ(贷款额_i × 利率_i)最小化总风险总风险 Σ(贷款额_i × 违约概率_i)此处为简化违约概率可由信用评分转换而来约束条件包括总贷款额上限、对单个企业或某一信用等级企业的贷款上限、监管要求等。 解决方法线性/非线性规划如果目标函数和约束能写成明确的数学形式可以直接使用优化求解器如MATLAB的linprog,fminconPython的SciPy.optimize或PuLP库求解。智能优化算法当问题规模较大或模型复杂时常用遗传算法GA、模拟退火算法SA等来寻找近似最优解。这些算法代码实现有一定套路是数学建模竞赛中的利器。注意很多新手会忽略“利率”也是决策变量。在优化时利率并非固定不变高利率能带来高收益但也会增加企业违约风险逆向选择。有些优秀模型会将利率对违约概率的影响称为“风险弹性”考虑进去构建更复杂的耦合关系。2.3 数据处理一切模型的基础题目提供的Excel数据通常不会完美。在建模前必须进行数据预处理缺失值处理对于连续变量可用均值、中位数或回归插值填补对于分类变量可用众数填补。如果某企业缺失数据过多可能需要考虑将其剔除。异常值处理通过箱线图或3σ原则识别异常值。需要判断是录入错误修正或剔除还是真实存在的极端情况保留但可能需要稳健模型。数据标准化/归一化由于各财务指标量纲不同如营收是百万级利润率是百分比在计算综合评分前必须进行标准化如Z-score标准化或归一化如Min-Max归一化使所有指标处于同一尺度。指标同向化财务指标有正向如利润率越高越好和负向如资产负债率越低越好。在综合评分前需将负向指标转化为正向常用方法是用倒数或取负数。3. 核心模块实现与源代码关键点解读一套完整的源代码通常会对应上述建模思路分成几个模块。这里我以Python为例讲解关键代码段背后的逻辑和实操要点。3.1 数据预处理模块import pandas as pd import numpy as np from sklearn.preprocessing import StandardScaler, MinMaxScaler # 读取数据 data pd.read_excel(附件1企业数据.xlsx) # 1. 缺失值处理 - 向前填充对于时间序列数据用前一年数据填充 data_filled data.fillna(methodffill, axis0) # 对于仍缺失的用列均值填充 data_filled data_filled.fillna(data_filled.mean()) # 2. 异常值处理 - 使用箱线图原则用上下限截断 def cap_outliers(series): Q1 series.quantile(0.25) Q3 series.quantile(0.75) IQR Q3 - Q1 lower_bound Q1 - 1.5 * IQR upper_bound Q3 1.5 * IQR return series.clip(lower_bound, upper_bound) for col in data_filled.select_dtypes(include[np.number]).columns: data_filled[col] cap_outliers(data_filled[col]) # 3. 数据标准化 (为后续熵权法、TOPSIS准备) scaler StandardScaler() data_scaled pd.DataFrame(scaler.fit_transform(data_filled.select_dtypes(include[np.number])), columnsdata_filled.select_dtypes(include[np.number]).columns) # 4. 指标同向化 - 假设资产负债率是负向指标 data_scaled[资产负债率_正向化] 1 / (data_scaled[资产负债率] 0.01) # 加0.01防止除零 # 或者使用 max - x 的方法 # data_scaled[资产负债率_正向化] data_scaled[资产负债率].max() - data_scaled[资产负债率]实操心得数据处理没有唯一标准。在比赛中你需要在论文中明确陈述你采用的方法及理由。例如选择“向前填充”是因为财务数据具有时间连续性使用箱线图法处理异常值是因为其统计意义明确。代码的鲁棒性很重要比如同向化时加一个小的epsilon防止除零错误。3.2 信用评价模块熵权法TOPSIS示例def entropy_weight(data): 熵权法计算指标权重 data: 标准化后的正向指标矩阵行为样本列为指标 # 计算第j个指标下第i个样本的比重 P data / data.sum(axis0) # 计算第j个指标的熵值 epsilon 1e-10 # 防止log(0) e -np.sum(P * np.log(P epsilon), axis0) / np.log(len(data)) # 计算差异系数 d 1 - e # 计算权重 w d / d.sum() return w def topsis(data, weight): TOPSIS法计算综合得分 data: 标准化后的正向指标矩阵 weight: 各指标权重向量 # 加权标准化矩阵 weighted_matrix data * weight # 理想解和负理想解 Z_pos weighted_matrix.max(axis0) Z_neg weighted_matrix.min(axis0) # 计算距离 D_pos np.sqrt(((weighted_matrix - Z_pos) ** 2).sum(axis1)) D_neg np.sqrt(((weighted_matrix - Z_neg) ** 2).sum(axis1)) # 计算相对贴近度即综合得分 score D_neg / (D_pos D_neg) return score # 假设我们已经有了正向化后的数据矩阵 data_positive (DataFrame) # 计算权重 weights entropy_weight(data_positive.values) print(各指标权重, weights) # 计算TOPSIS得分 credit_scores topsis(data_positive.values, weights) data[信用评分] credit_scores # 根据评分进行聚类分档例如K-means分3类 from sklearn.cluster import KMeans kmeans KMeans(n_clusters3, random_state42) data[信用等级] kmeans.fit_predict(data[[信用评分]]) # 将聚类标签映射为A,B,C假设0-C, 1-B, 2-A评分越高等级越高 label_map {0: C, 1: B, 2: A} data[信用等级] data[信用等级].map(label_map)关键点解读熵权法核心是“差异越大权重越大”。TOPSIS的核心思想是“离理想解越近离负理想解越远越好”。这段代码清晰地实现了这个流程。最后用K-means聚类而不是简单分位数划分等级是因为聚类能更好地发现数据内在结构使同一等级内企业性质更相似。random_state参数是为了保证结果可复现这在比赛中至关重要。3.3 信贷策略优化模块线性规划示例假设我们简化问题利率固定只优化贷款分配。我们使用线性规划。from scipy.optimize import linprog # 假设有n家企业 n len(data) # 决策变量每家企业的贷款额 x_i # 目标函数系数c -收益系数。因为linprog默认求最小化所以最大化收益需取负。 # 收益 贷款额 * 利率假设利率根据信用等级已确定存储在 data[利率] 中 c -data[利率].values # 求最小化 -收益等价于最大化收益 # 约束条件 # 1. 总贷款额约束sum(x_i) TOTAL_LOAN (e.g., 100,000,000) A_total np.ones((1, n)) b_total [TOTAL_LOAN] # 2. 单户贷款额约束0 x_i max_loan_i # max_loan_i 可以根据企业营收的一定比例和信用等级计算得出 bounds [(0, max_loan_i) for max_loan_i in data[最大额度].values] # 3. 风险约束sum(x_i * risk_i) MAX_RISK (可选) # risk_i 是违约概率可由信用评分转换例如 risk_i 1 - normalized_score A_risk data[违约概率].values.reshape(1, n) b_risk [MAX_RISK] # 合并约束 A_ub np.vstack([A_total, A_risk]) # 不等式约束 b_ub np.hstack([b_total, b_risk]) # 求解线性规划 res linprog(c, A_ubA_ub, b_ubb_ub, boundsbounds, methodhighs) if res.success: optimal_loan_amounts res.x print(最优贷款分配方案, optimal_loan_amounts) print(银行最大总收益, -res.fun) # 记得取反回来 else: print(优化失败, res.message)注意事项这是一个极度简化的模型。现实中利率和违约概率可能随贷款额变化问题会变成非线性。此时就需要用到前面提到的遗传算法。用遗传算法时编码方式很关键如用0/1表示是否贷款用实数表示贷款额适应度函数要精心设计平衡收益和风险并处理好约束条件如使用罚函数法。4. 论文写作要点与常见陷阱有了模型和代码如何组织一篇优秀的论文论文是向评委展示你思维的载体。4.1 论文核心结构摘要重中之重需用300-500字清晰概括针对什么问题、用了什么方法、建立了什么模型、设计了什么算法、得到了什么结果、有何特色。避免出现公式和图表引用用精炼的语言讲一个完整的故事。问题重述与分析不要照抄题目。用自己的话梳理问题的背景、目标和约束条件并画出逻辑框图阐明解决问题的总体思路。模型假设与符号说明假设要合理且必要如“假设宏观经济环境稳定”、“假设数据真实有效”。符号说明用三线表格呈现清晰美观。模型的建立与求解这是论文主体。对应前面讲的“三层模型”分节论述。每一部分都要有问题分析 - 模型建立公式推导- 求解方法/算法设计 - 结果分析。将核心代码以流程图或伪代码形式展示关键结果用图表呈现。模型的评价与推广分析模型的优点创新性、实用性、稳定性和缺点简化了哪些现实因素。提出模型的改进方向和在更广领域的应用可能。参考文献与附录参考文献格式要规范。附录可放核心代码不宜过长摘取关键部分、大量原始数据或中间结果。4.2 常见问题与避坑指南问题一模型堆砌逻辑断裂表现论文中罗列了AHP、熵权法、TOPSIS、灰色预测、神经网络等多个模型但读下来不知道这些模型之间是什么关系为什么用这个不用那个。对策建立一条清晰的主线逻辑。例如“首先为了量化企业信用我们采用客观的熵权法确定指标权重并结合TOPSIS进行综合评分理由避免主观性。然后基于评分采用K-means聚类划分信用等级。接着针对不同等级设计差异化的信贷额度与利率模型。最后在总额度约束下建立以收益最大、风险最小为目标的多目标优化模型并采用线性加权和法将其转化为单目标利用遗传算法求解。” 每个模型的引入都要有明确的“承上启下”的说明。问题二结果分析空洞表现只给出“最终银行收益为XXX元”这样一个数字没有分析这个结果是否合理没有做灵敏度分析。对策进行深入的数值实验与灵敏度分析。例如不同权重方法对比尝试AHP和熵权法比较得出的信用排名差异并讨论哪种更合理。参数敏感性分析改变优化模型中的风险厌恶系数观察收益和风险如何变化绘制趋势图。这能体现你对模型的理解深度。场景对比对比“完全按信用评分分配”和“经过优化模型分配”两种策略下的收益结果突出优化模型的价值。问题三代码与论文脱节表现论文里写的是算法A附录代码里是另一个东西或者代码根本无法运行。对策代码必须与论文描述严格对应。在论文关键步骤处可以给出算法的伪代码或流程图。提交前务必在另一台干净的电脑上运行一遍所有代码确保结果可复现。附录的代码要加上必要的注释。问题四忽视可视化表现通篇文字和表格让人看得昏昏欲睡。对策善用图表。企业信用得分的分布可以用直方图或箱线图不同信用等级企业的财务指标均值可以用雷达图对比优化算法的收敛过程可以用迭代曲线展示最终信贷分配结果可以用条形图或饼图呈现。一图胜千言。5. 从赛题到实战思维延伸这道赛题的价值远不止于获奖。它训练的核心能力——数据驱动下的决策优化——在金融科技、风险管理、供应链管理等领域是通用的。当你掌握了这套方法你可以尝试更换数据找真实的上市公司财务数据尝试构建股票投资组合选择模型。更换场景将“信贷”换成“广告投放预算分配”、“研发项目优先级排序”、“物流中心选址”底层建模逻辑评价-排序-优化是相通的。深化模型引入更复杂的机器学习模型进行信用预测如LightGBM使用随机优化或鲁棒优化来处理不确定性甚至尝试用强化学习来模拟动态的信贷决策过程。我个人的体会是数学建模竞赛最宝贵的不是那个奖状而是在高压下与队友一起将一个模糊的现实问题抽象、分解、建模、求解并清晰表达出来的完整经历。这个过程里踩过的每一个坑解决的每一个bug都会让你对“如何用数学和编程解决实际问题”有更深一层的肌肉记忆。所以不要只满足于看懂别人的论文和代码一定要亲手把整个流程实现一遍遇到问题自己去查、去调、去和队友争论这才是成长最快的方式。最后一个小建议组队时最好能有分别擅长建模、编程和写作的队友分工明确又紧密协作是成功的关键。本文还有配套的精品资源点击获取