机器学习银行破产预测 声明: 这篇文章不是出自本作者手中,文章来源于一位学长的允许下发布的。
2022 第七届“数维杯”大学生数 学建模竞赛论文 题 目 银行效率分析及其破产成因研究
摘 要 在互联网金融的强大背景下,金融危机中的预测问题一直是当今社会的研究热点。 通过机器学习或人工智能技术实现对金融数据的分析和挖掘,在实际的应用中能够为银 行或企业予以提前预警,以减少经济上的损失。 针对任务 1 ,本文使用Z-score模型对 64 项指标进行了数据分析。首先,我们对附 件 1 中数据进行预处理,根据指标缺失率及指标含义剔除缺失值,通过 3 σ原则筛选异 常值。然后,根据Z-score模型和筛选出的指标计算各个银行的Z值;最后,通过引入阈 值实现对银行破产情况的预测。实验结果表明,2017-2021年的分界线分别为-1.0、-3.9、 -7.7、-2.1、-3.5,当阈值高于分界线时,银行正常运营,反之即为破产。 针对任务 2 ,本文使用随机森林算法选出 5 项贡献度最高的指标数据及其对权重进行 分析。实验结果表明,通过对 2017 年的特征值贡献度进行排序,最终选取X 29 , X 46 , X 61 , X 45 , X 44 指标,其他年份的所选指标见附件。 针对任务 3 ,本文将Z-score模型与随机森林模型的召回率、准确率、精确率和F测 度进行对比分析。实验结果表明,随机森林具有很高的平均召回率,其值高达99.89%, 因此本问基于随机森林算法作为倒闭风险预测模型。 针对任务 4 ,本文基于K-means聚类方法和蒙特卡洛方法对该问进行深度剖析。实 验结果表明,在聚类方法和蒙特卡洛方法下的代表性银行数据通过倒闭风险预测模型的 预测精度分别为54.76%、95.35%。由此可见,采用蒙特卡洛方法下选取的结果更加准 确,数据更具有代表性。 针对任务 5 ,本问首先从每年数据中选取 1000 个样本点,通过对每个指标的聚类中 心点进行线性拟合,以获取银行的整体偏移趋势;其次根据拟合方程计算出次年各个指 标的聚类中心作为次年预测结果,根据与次年真实情况的相似度最大值,确定为次年最 接近的银行编号,即为同一家银行。根据将每一家银行各指标线性拟合得到银行个体的 偏移趋势,建立有关整体偏移趋势和个体偏移趋势的函数,由 2021 年的各项指标来预 测 2022 年的各项指标数据,最后代入随机森林模型中求得最后的预测结果。
关键词:风险预测;Z-score模型;随机森林;K-means聚类;蒙特卡洛方法
目 录
一、问题重述
1.1 引言
1.2 要解决的具体问题
1.3 文献综述
1.4 我们的工作
二、问题分析
2.1 问题一的分析
2.2 问题二的分析
2.3 问题三的分析
2.4 问题四的分析
2.5 问题五的分析
三、模型假设
四、名词解释与符号说明
五、模型的建立与求解
5.1 数据的预处理
5.2 基于Z-score模型的银行风险预测
5.2.1 Z-score模型的建立
5.2.2 模型求解
5.3 基于随机森林模型的指标权重分析
5.3.1 随机森林算法简介
5.3.2 随机森林模型的构建
5.3.3 指标筛选结果及分析
5.4 Z-score模型与随机森林模型的对比
5.4.1 两种模型结果的对比分析
5.4.2 倒闭风险预测模型构建
5.5 随机森林模型的验证及预测
5.5.1 聚类方法
5.5.2 蒙特卡洛方法
5.5.3 结果对比分析
5.6 基于余弦相似度的银行同属模型构建及其预测
5.6.1 余弦相似度模型的构建
5.6.2 同属银行倒闭风险趋势模型的构建
六、模型的评价
参考文献
一、问题重述 1.1 引言 如今,金融行业在国民经济发展的过程中占据主导地位。金融的风险 防控问题一直以来是社会的研究热点。据中国银保监会统计,截至 2022 年 2 月,我国的大型商业银行的总资产为 1370052 亿元,总负债为 1250629 亿 元,均占银行业金融机构的39.7%。虽然我国银行业的大型商业银行占据主 导地位,但中小银行的总负债仍然占比较高。随着中小商业银行市场占额 的扩增和互联网金融等多因素的影响,各大金融机构竞争不断,部分银行 也因此出现了资金周转困难甚至破产的局面。国际、国内的中小商业银行 具有高负债、高风险和高回报的特征,难以躲避潜在的经营风险。因此,本 文旨在深度分析银行倒闭的原因,并提出能够精准预测银行破产风险的预 警体系。 1.2 要解决的具体问题 1. 从附件中的 64 项数据中整理出适合的投入产出数据,并对各银行的效 率展开对应评价,同时提供银行倒闭效率的分界线; 2. 利用附件中的 64 项指标对银行倒闭的原因进行挖掘,并提供最为重要 的 5 项指标数据及其对应的权重 3. 对任务( 1 )和任务( 2 )中的银行倒闭分析结果展开比对分析,同时提 出一个精确的倒闭风险预测模型; 4. 从 2021 年银行数据中筛选出最具代表意义的 20 家现存银行和 20 家倒 闭银行,并利用这些银行数据对其它银行倒闭风险进行预测。 5. 通过相关理论分析出 2017 年至 2021 年的银行数据中哪些数据可能来 自同一家银行,并结合同一家银行的时间序列数据预测哪些银行呈现 出了倒闭的趋势。 1.3 文献综述 早期用来判定企业是否破产的模型是由Altman教授在 1968 年提出来 的[1],其主要用来观察美国的破产和非破产的生产企业指标。该模型基于 梳理统计思想,从 22 个财务比率中筛选并建立了“五指标”Z-score模型。
Sharda等人[2]通过采用人工神经网络分析了信托机构的信用风险,从而有 效地帮助企业进行财务预警。随着机器学习的快速发展,基于机器学习的风 险预测模型相继被提出。例如霍远等人[3]通过聚类分析法对上市公司的财 务状况进行了分析。Chih-Fong Tsai[4]等人比较了主成分分析、因子分析等 常见的五种破产预测方法,并采用多层感知机作为预测模型。陈荣达等人 [5]将启发式算法与支持向量机相结合,既保留了原始数据的特征信息,又
提高了模型的泛化能力和训练效率。Santoni等人[6]对比分析了Z-score、分 类评定模型和随机森林等三种破产预测方法。实验结果表明,基于随机森 林具有较高的分类预测结果,其值高达99.85%。因此,本文使用随机森林 的方法构建银行破产预测模型,旨在帮助企业有效进行破产预警,以减少 企业的损失。
1.4 我们的工作 1. 筛选整理对于银行倒闭结果最为显著的指标,建立模型将银行财务风 险情况量化表示,通过合适的阈值来分类。 2. 通过两种模型来筛选指标并且预测结果,比较两种模型的预测准确性。 3. 从银行样本中选择最显著的样本,建立模型预测剩余银行的倒闭情况。 4. 分析五年内哪些样本的数据来自同一家银行,并建立模型预测银行的 财务情况发展趋势
二、问题分析 2.1 问题一的分析 要求对 64 项指标数据整理出适合的投入产出数据,显然 64 项指标过 多并且其中很多指标相关性很强,那么解决任务 1 就是找出对于银行的财 务情况的评价最有力的指标,并且通过这些指标,可以将对银行财务情况 的评价量化为一个评价分数。在诸多研究中表明Z-score模型对于预测银行 倒闭效果良好,并且可以根据银行的财务情况得分判断分类银行的财务情 况。因此我们建立一个Z-score模型来评价银行是否倒闭。根据附件给出的 数据可以发现存在一定数量的缺失值和异常值,所以首先对数据进行预处 理,下一步建立Z-SCORE模型分别对2017-2021年给出的银行样本进行预 测,得到关于银行财务情况的评价得分,最后与银行倒闭的真实情况对比, 给出可以最准确反映倒闭情况的临界阈值。
2.2 问题二的分析 任务 2 要求我们利用附件中的 64 项指标对银行倒闭的原因进行挖掘, 并提供最为重要的 5 项指标数据及其对应的权重。本问将预处理之后的 62 个指标(剔除X21和X37)作为研究对象,并构建随机森林模型。模型的 的输入为 62 个特征指标数据,输出则为银行是否倒闭的判定结果。首先划 分训练集和测试集;然后在训练集中随机有放回地抽取样本数据(重复 200 次),并通过特征选取构造决策树;其次调节模型参数生成随机森林;最终 对特征值的贡献度进行排序并选择最为重要的 5 项指标。 2.3 问题三的分析 任务 3 要求我们对任务( 1 )和任务( 2 )中的银行倒闭分析结果展开 比对分析,并提出一个精确的倒闭风险预测模型。本问将Z-score模型与随 机森林模型的结果展开对比。分析指标包括混淆矩阵中的比率,即召回率、 准确率、精确率和F测度,同时采用混淆阵列示每种方法的输出结果,以此 判断模型的性能。由于随机森林具有较强的泛化能力,因此本问基于随机 森林算法构建倒闭风险预测模型。
2.4 问题四的分析 任务 4 要求从 2021 年银行中选取出最具有代表性的 20 家破产和 20 个 未破产的样本,本文基于K-means聚类方法和蒙特卡洛方法对该问进行深 度剖析。由任务三可知,随机森林模型对于预测风险的效果更佳,因此将采 用聚类方法和蒙特卡洛方法生成的代表性银行数据分别输入到随机森林模 型中,并根据已训练模型对其余数据进行精准预测。本问对两种方法进行 了对比分析,最终给出最佳方案。
2.5 问题五的分析 任务 5 要求我们通过相关理论分析出 2017 年至 2021 年的银行数据中 哪些数据可能来自同一家银行,并结合同一家银行的时间序列数据预测哪 些银行呈现出了倒闭的趋势。以每一年的前 1000 个银行样本为例,根据任 务四得到的各个银行每个指标的聚类中心,在2017-2021年线性拟合各项指 标的聚类中心,以获取每项指标的整体偏移趋势;其次根据拟合方程计算出 我们选取银行样本次年各个指标的预测数据,并与次年真实值进行余弦相 似度的计算,余弦相似度最高的次年样本认为与我们所选样本属于同一家 银行。以此方法可以得到每一年所选样本在次年中发展趋势最相似的样本。 整理出来自同一家银行的指标数据,根据五年的指标数据可以线性拟合得 到同一家公司指标数据的个体偏移趋势,将整体偏移趋势和个体偏移趋势 的斜率的均值作为 2021 年至次年的偏移趋势,根据这一偏移趋势,通过拟 合方程得到次年的指标预测数据,将各项指标数据代入随机森林模型中求 得最后的倒闭与否结果。 三、模型假设 1. 假设题目所给的数据真实可靠且合理; 2. 不考虑不可抗力因素(如自然灾害、新冠肺炎等)的影响; 3. 假设银行破产因素只受附件中所给指标的影响; 4. 假设程序中浮点数运算的位数不会对结果产生较大影响。 5. 用以计算整体偏移趋势的样本中不包含倒闭样本,认为倒闭的银行次 年不再运营 四、名词解释与符号说明 1 2 3 4 5 6 7 8 9 序号 符号 符号说明 1 Ai Z-SCORE模型中第i项影响指标) 2 Xi 附件 1 中 64 项指标中的第i项指标 3 Ki 第i年份的Z-SCORE阈值 4 Hij 第i年份第j项指标的聚类中心点 5 Ti 第i个指标2017-2021年的整体偏移 趋势 6 Si 第i个银行自身的个体偏移趋势 7 Ui 第i个银行的真实偏移趋势
五、模型的建立与求解 5.1 数据的预处理 5.1.1 缺失值处理 首先,我们对附件 1 中的缺失数据进行统计,并对缺失率进行排列,其 中选取缺失率最高的前五项进行绘图,结果如图5-2:
由上图可以看出,附件 1 中每个年份中的X21和X37数据缺失最为严 重,其中X21指标表示销售(n)/销售(n-1),意义表明为销售数量的对比,其 值越接近 1 ,则销售数量越多。X37指标表示(流动资产-存货)/长期负债,意 义表明为银行负债承受能力。两者指标对银行倒闭风险相关程度不大,为保 证模型训练效果的一致性,因此我们剔除附件 1 中所有年份的X21和X 指标。其他指标的缺失率不足5%,因此也可直接剔除缺失数据,不影响数 据整体信息量。
5.1.2 异常值处理 根据3sigma准则,对银行样本的指标数据进行异常值的剔除,一旦产生 异常值我们认为该样本的数据将会对模型的准确性和整体性产生影响,所 以直接剔除产生异常值的样本。最后 2017 年的样本中剔除了 13 项, 2018 年的样本剔除了 5 项, 2019 年的样本剔除了 7 项, 2020 年的数据无剔除, 2021 年的数据剔除了 3 项。
5.2 基于Z-score模型的银行风险预测 5.2.1 Z-score模型的建立 Z-score模型是以多变量的统计方法为基础,以破产企业为样本,通过 大量试验后对企业运营情况、破产与否进行分析的模型。在大量的分析基 础上,从上市公司的财务报告中计算出一组反映反映公司财务情况的指标, 然后根据这些指标对于财务危机的作用大小给出权重,最后加权得到一个 公司的财务风险评价指数Z。 Z-score模型主要用来解决多变量预警问题,已被广泛应用于财务预警 领域中。关预警的计算公式如式( 1 )所示:
1 Z= 1. 2 A 1 + 1. 4 A 2 + 3. 3 A 3 + 0. 6 A 4 + 0. 999 A 5 (1)
其中,A 1 能够反映出银行资金的流动能力及其规模的大小,同时也能 较好地体现出银行在短时期内的偿付能力。若企业拥有较多的运营资金,则 说明其具有较强的偿付能力,破产几率就越小,反之,则将会面临破产的问 题。A 2 指标是衡量一段时间内的累积盈利能力,反映出银行在营期间的利 润情况。例如,一个相对年轻的公司可能会显示出较低的数值,因为它还
没有时间来建立其累积利润。因此,可以说年轻的公司在这个分析中受到 了某种程度的歧视,它被归类为破产的几率相对高于另一个较年长的公司, 当然也包括其他情况。但是,这正是现实世界中的情况。在公司的早期,破 产的发生率要高得多。A 3 主要体现出银行是否考虑税收与融资方面的影响, 侧面体现出银行提升资产价值的能力,该比值越大,则银行的利用效率越 高,因而具有较强的业务水平。A 4 主要体现银行在破产前的市值可下降程 度,该比值越大,则当银行出现较低的经营问题时,收益也越低。A 5 主要 体现出银行的收入情况,该比值越大,则说明资产利用效率越高,反之,则 说明资产利用效率越低。 根据附件 1 中的 64 项指标之中找出与A 1 , A 2 , A 3 , A 4 , A 5 相对应的指标。 其中A 1 , A 2 , A 3 , A 5 分别与X 3 , X 6 , X 7 , X 9 之相对应,X 4 由X 17 ·X 25 得到。 因此银行的风险评价指数的计算公式如式( 2 )所示: Z= 1. 2 X 3 + 1. 4 X 6 + 3. 3 X 7 + 0. 6 X 17 ·X 25 + 0. 999 X 9 (2) 5.2.2 模型求解 从附件 1 中2017 2021五个年份中各大银行的X 3 , X 6 , X 7 , X 9 , X 17 , XX 21 六个指标数据代入( 2 )进行计算,以此可得各年份中各大银行的Z-score值。 为节约篇幅,仅展示 2017 年部分银行的结果数据表。其余见附件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 表 5-1: 2017 年部分银行的Z-SCORE得分 银行序号 Z-SCORE得分 是否倒闭 4 1.78687973696 否 6260 -5.3947893104 是 1324 0.107538178 否 700 3.12884351904 否 98 1.639916158 否 150 -2.166910048832 是 259 2.846472957 否 1141 -2.2365304792 是 4722 1.463034408 否 6319 0.1308990584 否 888 3.2468726324 否 2527 -1.91140947424 是 3422 -0.42500176848 否 6291 0.181738457488 否 2914 -3.333019503872 是 3887 1.783426924 否 226 1.398590248 否 13 -2.235894737664 是 4505 0.572546358 否 781 -1.22306576608 是
为划分银行银行倒闭效率的分界,我们引入阈值K这一概念,当K < Z−score时,表示该银行经营效率妥善,财务情况良好;当K > Z−score 时,表示该银行处于破产区域。因此我们对附件 1 中各年的所有银行Z-score 值与K值进行比对,当准确率最高时且处于即将开始快速下降为最佳K值 点。以 2017 年数据为例,如图5-3和图5-4所示
由上图可知,当K值取-1.0时,能够较好的划分银行倒闭的概率区域。 因此,从 2017 年至 2021 年各年份的分界线如下表所示。
1 2 3 4 表 5-2:2017-2021年银行K值分界线及准确率 年份 2017 2018 2019 2020 2021 K值分界线 -1.0 -3.9 -7.7 -21 -3. 准确率 0.90915 0.92862 0.92486 0.92233 0.
5.3 基于随机森林模型的指标权重分析 5.3.1 随机森林算法简介 随机森林通过改进决策树算法,能够分析较为复杂且样本之间具有相 关性的数据特征。由于其能够捕获高维数据特征且具有较强的鲁棒性,被 广泛应用于数据分类、特征选择等领域。该算法的思想如下: 1. 假设原始数据集A中共有N个数据样本,从中随机地重复选取N个数 据(有放回)组成新数据集B。
假设B中共有X个特征,从中随机抽取x个特征,且x≪X,生成一 个可以不剪枝的分类回归树。
重复执行( 1 )和( 2 )m次,最终生成的m棵决策树即为随机森林。 在构造随机森林时,对每棵决策树对应的b个OOB(out of bag, OOB) 数据进行投票,以得到b个样本投票分数s 1 , s 2 ,… , sb。通过随机改变OOB 数据的特征变量xi来获取新的OOB数据样本,并利用随机森林对其进行 投票,得到矩阵S:
S= 0 BB BB BB @ 1 2 3 4 s 11 s 12 ... s 1 b s 21 s 22 ... s 2 b ... ... ... sk 1 sk 2 ... skb
1 CC CC CC A (3) 并通过式X计算各个特征向量对分类阶段的贡献大小ci,以衡量各个特征 的重要性:
(sj−sij) b (4) 其中,sj和sij为变量修改前后的第i棵树的OOB误差率。随机森林 算法的流程图如图5-5所示。
5.3.2 随机森林模型的构建 经数据预处理后,得到 62 个特征指标。我们选取 2017 年作为模型演 示。本文中随机森林模型的伪代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 算法 1: 随机森林模型构建伪代码 输入 : 上述中的 62 个特征指标数据 输出 : 银行是否倒闭 1 repeat 2 训练集与测试集的划分; 3 for n= 1 to 200 do 4 从训练集数据样本中随机有放回地抽取生成一个样本子集; 5 选取 p [62] = 8个特征作为特征子集; 6 生成决策树; 7 end 8 调节模型参数; 9 形成随机森林; 10 特征值贡献度排序; 11 特征选择结果; 12 until 模型准确率达到最大; 本文使用sklearn中的RandomForestClassifier函数。按照上述代码进行
随机森林模型编写,其调节参数如下表所示: 1 2 3 4 5 6 7 8 表 5-3:超参数列表 超参数名称 超参数值 n_estimators 8 max_features 8 random_state 90 criterion gini min_samples_leaf 4 min_samples_split 21
5.3.3 指标筛选结果及分析 将 2017 年数据代入上述模型运行,得到特征贡献度排序如下(得分越 高相关性越强): [(’X29’, 0.05607), (’X46’, 0.04940), (’X61’, 0.04850), (’X45’, 0.04751), (’X44’, 0.03391), (’X35’, 0.03291), (’X63’, 0.03092), (’X11’, 0.02669)]。如下 图所示:
1 2 特征指标选择结果:选取排名前 5 的特征:X 29 , X 46 , X 61 , X 45 , X 44 其中,X29为总资产的对数,其表示上市公司的总资产规模。X46为速
冻比率,其用来衡量某公司或企业的流动资产中能够快速变现并偿还流动 负债的能力。若该值大于 1 ,则说明公司投资的机会成本越多。X61为应收 帐款与销售额的比率,其用来衡量企业中有多少销售是赊销的业务。该值 越大,则说明该企业可能会遇到短期的资金流动性问题。X45为净利润占 存货的比值,其用来表明利润的临界值,当存货减少时,对当期净利润影响 较大,利润容易产生亏损。X44为应收账款的周转天数。该值越大,则说明 应收账款周转率越小,收账较慢,账龄较长,资产流动性和短期偿债能力较 弱。 5.4 Z-score模型与随机森林模型的对比 5.4.1 两种模型结果的对比分析 对于分类器的性能评价也出现了两大指标体系,分别是混淆矩阵中的 比率指标和ROC曲线以及曲线下面积AUC。基于混淆矩阵的思想下,又将 不同的比率进行分类,即召回率、准确率、精确率和F测度。本文采用混淆 矩阵列示每种方法的输出结果,以此判断模型的性能。 混淆矩阵表示如下:
1 2 3 真实情况 正例 预测结果反例 正例 TP(真正例) FN(假反例) 反例 FP(假正例) TN(真反例)
随机森林的混淆矩阵结果:
1. 召回率对比 召回率公式为: 召回率=T PT P+F N (5) 1 2 3 4 表 5-7:两种模型召回率的对比结果 2017 2018 2019 2020 2021 平均召回率 Z-score 96.93% 99.57% 98.45% 99.42% 99.94% 98.86% 随机森林 100.00% 100.00% 100.00% 100.00% 99.45% 99.89%
准确率对比 准确率公式为: 准确率=T P+F NT P++T NF P+F N (6)
1 2 3 4 表 5-8:两种模型准确率的对比结果 2017 2018 2019 2020 2021 平均准确率 Z-score 83.89% 97.45% 95.38% 95.73% 95.05% 93.50% 随机森林 98.52% 97.59% 96.61% 95.44% 95.99% 96.83%
精确率对比 精确率公式为: 精确率=T PT P+F P (7)
1 2 3 4 表 5-9:两种模型精确率的对比结果 2017 2018 2019 2020 2021 平均精确率 Z-score 86.16% 97.68% 96.82% 96.26% 95.10% 94.41% 随机森林 98.52% 97.59% 96.61% 95.44% 96.45% 96.92%
F测度对比 F测度公式为: F测度=^2 ×召回率召回率+×准确率准确率 (8)
1 2 3 4 表 5-10:两种模型F测度的对比结果 2017 2018 2019 2020 2021 平均精确率 Z-score 86.16% 97.68% 96.82% 96.26% 95.10% 94.41% 随机森林 98.52% 97.59% 96.61% 95.44% 96.45% 96.92%
5.4.2 倒闭风险预测模型构建 由于本文的中心在于预警银行倒闭风险,因此将未倒闭银行识别成未 倒闭银行的召回率更为重要,由以上结果可以看出随机森林模型具备更好 的性能,即随机森林模型在准确率、精准率和F测度都比Z-score模型精度 高,总体性能较好的分类器。
1 2 3 4 5 6 表 5-11:两种模型的性能对比汇总 Z-score模型 随机森林模型 平均召回率 98.86% 99.89% 平均准确率 93.50% 96.83% 平均精确率 94.41% 96.92% 平均F测度 96.06% 98.33%
5.5 随机森林模型的验证及预测 任务四中要求我们选取具有代表性的 20 家未破产银行和 20 家已破产 银行。为选取具有代表性的数据,我们分别采用聚类方法和蒙特卡洛方法 进行比对分析。 5.5.1 聚类方法 (1)聚类流程 第一步,将 2021 年中未破产和已破产银行分为两类; 第二步,通过聚类算法分别获取未破产银行和已破产银行的聚类中心 点; 第三步,通过欧式距离计算未破产银行和已破产银行数据点与聚类中 心点的距离,欧式距离公式如下; D=
该式表示两个n维向量间的欧氏距离。 第四步,分别筛选未破产银行和已破产银行距离总和最小的 20 家银行; 第五步,代入到训练好的预测风险模型中来判别剩余银行的倒闭概率。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 算法 2: Kmeans聚类算法伪代码 输入 : 输入数据C,聚类数k。 输出 : 输出结果C 1 , C 2 ,... , CK 1 repeat 2 聚类中心初始化; 3 for n=i to M G do 4 计算每一个数据点与之最近的聚类中心,并将其添加到此 集群中; 5 重新计算聚类中心ck=N^1 Pxt∈Ckxt,Nk为目前第个聚类集 群中所包含的样本数; 6 计算总类间离散度JM SE; 7 if JM SE收敛 then 8 break; 9 end 10 end 11 until 迭代次数达到最大值 MG ; (2)聚类结果 通过python聚类后,结果如表5-12所示: 表 5-12:聚类方法下部分代表性银行编号表 银行编号 已破产银行 3 12 21 60 65 79 84 89 100 112 未破产银行 283 448 1186 1335 1364 1558 1626 1769 1897 1959
(3)银行预测 将聚类方法下的代表性银行数据代入到已训练好的随机森林模型中进 行训练,并对剩余银行数据进行预测。其预测准确度为54.76%。
1 2 3 4 5 6 7 8 9 表 5-13: 2021 年随机森林模型超参数表格 超参数名称 超参数值 n_estimators 28 max_features 8 random_state 90 criterion entropy min_samples_leaf 1 min_samples_split 16 max_depth 18
5.5.2 蒙特卡洛方法 (1)蒙特卡洛流程 第一步,由计算机随机获取 2021 年已破产和未破产各 20 家银行数据, 并将其作为训练样本,其余数据则作为测试样本; 第二步,训练蒙特卡洛模型,并得出该训练集和测试集下的最终预测 精度; 第三步,针对步骤 1 和步骤 2 重复模拟次随机试验; 第四步,从个输出结果中选取预测精度最高的一组作为最具代表意义 的 20 家现存银行和 20 家倒闭银行。 (2)蒙特卡洛结果 通过蒙特卡洛方法后,结果如表5-14所示: 1 2 3 4 表 5-14:蒙特卡洛方法下部分代表性银行编号表 银行编号 已破产银行 133 236 101 134 131 125 118 203 217 186 未破产银行 3685 2260 4006 1894 4459 3919 2687 2119 28 4093
(3)银行预测 将蒙特卡洛方法下的代表性银行数据代入到已训练好的随机森林模型 中进行训练,并对剩余银行数据进行预测。其预测准确度为95.35%。
5.5.3 结果对比分析 从上述分析中,可以看出蒙特卡洛方法下选取的结果更加准确,为判 断是否具有代表性,我们通过碎石图分析得出K-Mean聚类下选取的银行是 不能够准确识别大多数银行的性质性,而蒙特卡洛方法下选取的银行是能 够有效的准确识别大多数银行的性质。因此,蒙特卡洛方法下选择的 40 家 银行数据是更具有代表性。
5.6 基于余弦相似度的银行同属模型构建及其预测 5.6.1 余弦相似度模型的构建 从 2017 年开始,从未倒闭的银行中的银行中选择 1000 个样本。因为已 经倒闭的银行不会再运营,因此不可能在次年及以后出现该银行的指标数 据,对于研究指标的整体偏移趋势没有意义。 在任务四中我们已经通过聚类算法得到2017-2021年各项指标的聚类 中心点Hij,这样我们可以线性拟合每一项指标五年的聚类中心点数值,可 以得到拟合出的直线方程,斜率即为指标的整体偏移趋势Tj,通过每个指 标拟合出的直线方程,从 2017 年开始逐年计算每一个银行样本次年的各项 指标的预测数据,接下来我们将每一个银行预测的数据与次年的真实指标 数据采用式( 10 )进行余弦相似度计算。
假定A= (A 1 , A 2 ,… , An)和B= (B 1 , B 2 ,… , Bn)是两个n维向量,则 A与B的夹角θ的余弦值为:
1 2 3 Pn pPn i=1(AI×Bi) i=1(AI)^2 ×
(10) =|AA|×|·BB| (11) 余弦相似度可以表示两个样本的相似度大小,余弦相似度越大则两个 银行的相似度越高,可以认为是来自同一家银行。当余弦相似度最大时,认 为次年该编号的银行样本与当前年份的银行样本数据相似度最高,最接近 整体发展趋势,认为次年该编号银行与当年银行是同一家。 根据余弦相似度,我们可以得到每一年选取的 1000 个银行按照整体偏 移趋势对应的次年的银行编号,如下表所示,可整理出来自同一家银行的 五年的指标数据。 1 2 3 4 5 6 7 8 9 10 11 表 5-15:不同年份同属银行表 2017 年公司编号 2018 年公司编号 2019 年公司编号 2020 年公司编号 2021 年公司编号 518 842 732 48 407 181 638 197 447 995 405 194 171 471 746 331 639 650 765 763 920 473 510 445 322 894 645 292 175 38 869 636 127 250 544 361 341 750 655 345 0 8 293 57 736
5.6.2 同属银行倒闭风险趋势模型的构建 为预测同一家银行在未来是否呈现倒闭趋势,我们引入真实偏移趋势 Uj。 Uj=f(Tj, Sj) (12)
其中Tj表示整体偏移趋势,Sj表示个体偏移趋势,个体偏移趋势是由同一 家银行在五年内本身数据变化引起的,通过最小二乘法拟合同一家银行各
指标随年份变化的直线方程。 式( 12 )表示各银行是由个体偏移趋势和整体偏移趋势共同导致而成, 为简便运算,我们令 Uj=Tj+ 2 Sj (13) 即整体偏移趋势和个体偏移趋势的比重一致。将表5-15整理后的银行 数据代入倒闭风险预测模型中进行预测分析。其结果如表5-16所示(仅展示 部分数据,其余数据见附件)。
1 2 表 5-16:倒闭银行风险趋向 2017 年 2018 年 2019 年 2020 年 2021 年 是否有倒闭倾向
1 2 3 4 5 6 7 8 9 10 518 842 732 48 407 0 181 638 197 447 995 0 405 194 171 471 746 0 331 639 650 765 763 0 920 473 510 445 322 0 894 645 292 175 38 0 869 636 127 250 544 0 361 341 750 655 345 0 0 8 293 57 736 0 425 385 521 203 883 1
六、模型的评价 6.1 模型的优点
在Z-score模型种引入了能够反映银行破产的临界阈值,以实现对各银 行的倒闭情况进行精准预测;
较好地解决了题目中的问题。随机森林的平均召回率在99%以上,其 准确率也达到96.83%。特征的提取也做到了少而精,结果更容易理解;
采用蒙特卡洛方法中筛选出最具代表意义的 20 家现存银行和 20 家倒 闭银行,在对其余的银行数据进行预测时,具有较高的准确度,其值 高达95.35%;
通过拟合方程找出次年各个指标的聚类中心,并与次年的每个真实指
标值计算余弦相似度。相比距离度量,余弦相似度更加注重向量在两 个方向上的差异,同时修正了数据间可能存在的度量标准不统一的问 题,具有更强的判决准确性。 6.2 模型的缺点 1. 由于缺失数据较多且不规律,导致模型误差较大; 2. 在计算余弦相似度时,时间复杂度和空间复杂度较高; 3. 由于时间有限,在对准确率进行对比分析时,未使用更为精确的深度 学习模型。 参考文献 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [1] Altman E I. Financial ratios, discriminant analysis and the prediction of cor- porate bankruptcy[J]. The journal of finance, 1968, 23(4): 589-609. [2] Odom M D, Sharda R. A neural network model for bankruptcy predic- tion[C]//1990 IJCNN International Joint Conference on neural networks. IEEE, 1990: 163-168. [3] 霍远, 王惠.关于上市公司财务状况的聚类分析[J].统计与决策, 2007 (17): 156-157. [4] TsaiCF,WuJW.Usingneuralnetworkensemblesforbankruptcyprediction and credit scoring[J]. Expert systems with applications, 2008, 34(4): 2639- 2649. [5] 陈荣达,虞欢欢.基于启发式算法的支持向量机选股模型[J].系统工程, 2014, 32(2): 40-48. [6] antoni V. La Previsione dell’insolvenza aziendale: confronto della perfor- mancedeimodelliZscore,LogiteRandomForestsuuncampionediaziende manifatturiere italiane[J]. 2014.
附 录
程序一:随机森林分类 : 1 2 3 4 5 6 7 8 9 10 import pandas as pd import numpy as np import pylab as pl from sklearn.preprocessing import OneHotEncoder from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import cross_val_score from sklearn.model_selection import GridSearchCV from sklearn import metrics # 分类结果评价函数 pl.rcParams['font.sans-serif'] = ['SimHei'] # 用来画图显示中文字体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 data = pd.read_excel(r'2021.xlsx') data_data = data.iloc [: ,0:62] target = data.iloc[:, 62] rfc = RandomForestClassifier(n_estimators =100, random_state =90) score_pre = cross_val_score(rfc , data_data , target , cv=10) score_pre.mean() scorel = [] for i in range (0, 200, 10): rfc = RandomForestClassifier(n_estimators=i, n_jobs=-1, random_state =90) score = cross_val_score(rfc , data_data , target , cv =10). mean() scorel.append(score) pl.plot( range (1, 201, 10), scorel) pl.show() scorel.remove(scorel [0]) print ( max (scorel), (scorel.index( max (scorel ))*10)+1) scorel = [] for i in range (15, 35, 1): rfc = RandomForestClassifier(n_estimators=i, n_jobs=-1,
1 2 3 random_state =90) score = cross_val_score(rfc , data_data , target , cv =10). mean() scorel.append(score)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 print** ( **max** (scorel), (scorel.index( **max** (scorel )))+15) pl.plot( **range** (15, 35, 1), scorel) pl.show() param_grid = {'max_depth': np.arange(1, 20, 1)} rfc = RandomForestClassifier(n_estimators =28, random_state =90) GS = GridSearchCV(rfc , param_grid , cv=10) GS.fit(data_data , target) param_grid = {'min_samples_leaf': np.arange(1, 11, 1)} rfc = RandomForestClassifier(n_estimators =28, random_state =90) GS = GridSearchCV(rfc , param_grid , cv=10) GS.fit(data_data , target) param_grid = {'min_samples_split': np.arange(2, 22, 1)} rfc = RandomForestClassifier(n_estimators =28, random_state =90) GS = GridSearchCV(rfc , param_grid , cv=10) GS.fit(data_data , target) param_grid = {'criterion': ['gini', 'entropy']} rfc = RandomForestClassifier(n_estimators =28, random_state =90) GS = GridSearchCV(rfc , param_grid , cv=10) GS.fit(data_data , target) rfc = RandomForestClassifier(n_estimators =28, random_state =90, max_depth =18, criterion='entropy', min_samples_leaf =1, min_samples_split =16) xtrain , xtest , ytrain , ytest = train_test_split(data_data , target , test_size =0.3) rfc = rfc.fit(xtrain , ytrain) importances = rfc.feature_importances_
1 2 3 4 5 6 7 sum (importances) predicted = rfc.predict(xtest) print (metrics.classification_report(ytest , predicted )) print (metrics.confusion_matrix(ytest , predicted )) auc = metrics.roc_auc_score(ytest , predicted) accuracy = metrics.accuracy_score(ytest , predicted) # 求精度 print ("Accuracy: %.2f%%" % (accuracy * 100.0))
程序二:银行相似性 : 1 2 3 4 5 6 7 8 9 10 11 12 from sklearn.cluster import KMeans import pandas as pd import numpy as np from scipy import optimize import pylab as pl import random from sklearn.preprocessing import OneHotEncoder from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import cross_val_score from sklearn.model_selection import GridSearchCV from sklearn import metrics # 分类结果评价函数
1 2 3 4 5 data_2017 = pd.read_excel('2017.xlsx') data_2018 = pd.read_excel('2018.xlsx') data_2019 = pd.read_excel('2019.xlsx') data_2020 = pd.read_excel('2020.xlsx') data_2021 = pd.read_excel('2021.xlsx')
1 2 3 4 5 6 num = 1000 data_2017 = data_2017.iloc [0:num ,0:62] data_2018 = data_2018.iloc [0:num ,0:62] data_2019 = data_2019.iloc [0:num ,0:62] data_2020 = data_2020.iloc [0:num ,0:62] data_2021 = data_2021.iloc [0:num ,0:62]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 X = [data_2017 ,data_2018 ,data_2019 ,data_2020 ,data_2021] **def** cosine_similarity(x,y): num = x.dot(y.T) denom = np.linalg.norm(x) * np.linalg.norm(y) **return** 1 - num / denom **def** func(x,k,b): **return** k*x+b centroid_list = [] **for** x **in** X: n_clusters = 1 cluster = KMeans(n_clusters=n_clusters , random_state =0) cluster.fit(x) centroid = cluster.cluster_centers_ centroid_list.append(centroid) T_list = [] **for** i **in range** (1, 5): k = centroid_list[i]-centroid_list[i-1] a = X[i-1]*k b = X[i] df = cosine_similarity(a,b) K_list = [] **for** j **in range** ( **len** (df)): min_index = df.stack (). idxmin () df = df.drop(min_index [0], axis =0) df = df.drop(min_index [1], axis =1) K_list.append ([ min_index [0], min_index [1]]) T_list.append(K_list) end_list = [] **for** i **in range** (num): sort_list = [] sort_list.append(T_list [0][i][0]) sort_list.append(T_list [0][i][1]) **for** j **in range** (num): **if** T_list [1][j][0] == T_list [0][i][1]: sort_list.append(T_list [1][j][1]) **for** s **in range** (num): **if** T_list [2][s][0] == T_list [1][j][1]:
1 2 3 4 5 6 sort_list.append(T_list [2][s][1]) for m in range (num): if T_list [3][m][0] == T_list [2][s][1]: sort_list.append(T_list [3][m][1]) end_list.append(sort_list) df1 = pd.DataFrame(end_list)
1 df1.columns = [' 2017 年公司编号', ' 2018 年公司编号', ' 2019 年公司编号', ' 2020 年公司编号', ' 2021 年公司编号', ]
1 df1.to_excel('同家银行编号.xlsx', index=False)
整体偏移 1 2 3 data = pd.read_excel('中心点偏移拟合直线 .xlsx') l_all = 2022 * data['k'] + data['b'] l_all = l_all.tolist ()
个体偏移 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 table = [] for i in range (1000): dat_2017 = data_2017.iloc[df1.iloc[i, 0], :]. tolist () dat_2018 = data_2018.iloc[df1.iloc[i, 1], :]. tolist () dat_2019 = data_2019.iloc[df1.iloc[i, 2], :]. tolist () dat_2020 = data_2020.iloc[df1.iloc[i, 3], :]. tolist () dat_2021 = data_2021.iloc[df1.iloc[i, 4], :]. tolist () dict = { 'A': dat_2017 , 'B': dat_2018 , 'C': dat_2019 , 'D': dat_2020 , 'E': dat_2021 } data = pd.DataFrame( dict ) l_unit = [] for j in range (62): popt , pcov = optimize.curve_fit(func , [2017 , 2018, 2019, 2020, 2021] , data.iloc[j, :]. tolist ()) k = 2022 * popt [0] + popt [1] l_unit.append(k)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 df = pd.DataFrame(table) rfc = RandomForestClassifier(n_estimators =28, random_state =90, max_depth =18, criterion='entropy', min_samples_leaf =1, min_samples_split =16) data = pd.read_excel(r'2021.xlsx') data_data = data.iloc [: ,0:62] target = data.iloc[:, 62] rfc.fit(data_data , target) pre_ = rfc.predict(df) df1['预测值'] = pd.DataFrame(pre_) df1.to_excel('预测值.xlsx',index=False) rfc.predict_proba(df)