主要内容

采用套袋决策树进行信用评级

这个例子展示了如何构建一个自动信用评级工具。

信用风险管理的基本任务之一是为借款人设定信用等级。评级被用来根据客户感知到的信用度对其进行排名:评级越高,客户风险越低;相似的等级意味着相似的风险水平。信用等级分为两类:信用等级和信用分数。信用评级是为数不多的几个互不相关的等级,通常用字母标明,如“AAA”、“BB-”等。信用分数是数字等级,如“640”或“720”。信用等级是监管框架的关键要素之一,如巴塞尔协议II(见巴塞尔银行监管委员会[3])。

分配信用额度涉及分析借款人的信息。If the borrower is an individual, information of interest could be the individual's income, outstanding debt (mortgage, credit cards), household size, residential status, etc. For corporate borrowers, one may consider certain financial ratios (e.g., sales divided by total assets), industry, etc. Here, we refer to these pieces of information about a borrower as特征预测.不同的机构使用不同的预测因素,他们也可能具有不同的评级类别或分数范围来对他们的客户进行排名。对提供给市场潜力大的借款人(如信用卡)的相对较小的贷款,通常使用信用评分和分级借款人的过程通常是自动的。对于较大的贷款,接触到小到中型公司和大型企业,信用评级通常使用,分级过程中可能涉及的自动算法和专家分析相结合。

有评级机构跟踪公司的信誉。然而,大多数银行都制定了内部方法来为客户分配信用等级。如果客户未被评级机构评级,则必须对其进行内部评级,但即使存在第三方评级,内部评级也可以提供对客户风险状况的补充评估。

这个例子展示了MATLAB®如何帮助信用评级过程的自动化阶段。特别是,我们利用了统计学和机器学习工具箱™中现成的统计学习工具之一,一种称为a的分类算法袋装决策树

我们假设历史信息以数据集的形式提供,其中每个记录包含借款人的功能和分配给它的信用评级。这些可能是内部评级,由遵循已经到位的政策和程序的委员会分配。或者,评级可以来自评级机构,其评级用于“跳跃”新的内部信用评级系统。

现有的历史数据是起点,它被用来火车将自动进行信用评级的袋装决策树。在统计学习的词汇表中,这种训练过程属于监督式学习.然后使用分类器将额定值分配给新客户。在实践中,这些自动化或预测评级很可能被认为是暂时的,直到一个由专家组成的信用委员会审查它们。我们在这里使用的分类器类型也可以促进这些评级的修订,因为它为预测评级提供了确定性的衡量,a分类分

在实践中,首先需要训练分类器,然后使用它为新客户分配信用评级,最后还需要配置文件评估质量或分类器的准确性,这一过程也称为验证历史.我们还讨论了一些现成的后台测试工具。

加载现有的信用评级数据

我们从逗号分隔的文本文件加载历史数据CreditRating_Historical.dat.我们在这里选择使用文本文件,但是具有Database Toolbox™访问权的用户当然可以直接从数据库加载该信息。

该数据集包含企业客户列表的财务比率、行业部门和信用评级。这是模拟的,不是真实的数据。第一列是客户ID。然后是五列财务比率。这些比率与Altman的z-score相同(参见Altman [1];相关分析请参见Loeffler和Posch[4])。

  • 营运资金/总资产(WC_TA)

  • 留存收益/总资产(RE_TA)

  • 利息和税收/总资产之前的收益(EBIT_TA)

  • 权益市值/总债务账面价值(MVE_BVTD)

  • 销售额/总资产(S_TA)

接下来,我们有一个行业扇区标签,一个整数值从1到12。最后一列具有分配给客户的信用评级。我们将数据加载到一个表格数组中。

creditDS = readtable ('信用_historical.dat');

我们将特征复制到一个矩阵中X,以及相应的类,额定值,进入载体Y.这不是必填步骤,因为我们可以直接访问此信息数据集表格数组,但我们在这里这样做是为了简化下面的一些重复函数调用。

要存储在矩阵中的特征X是五个金融比率,行业标签。行业是一个分类变量,名义上的事实上,因为在工业部门没有秩序。反应变量,信用评级,也是绝对的,尽管这是一个序单变量,因为根据定义,评级意味着a排行的良好信誉。我们可以使用这个变量“as is”来训练我们的分类器。这里我们选择将它复制到有序数组因为这种方式的输出出来的自然顺序的评级和更容易阅读。评级的顺序是由我们在定义中作为第三个参数传递的单元格数组确定的Y.信用评级也可以映射为数值,这对于尝试替代方法来分析数据(例如,回归)是有用的。建议在实践中尝试不同的方法。

X = [creditDS。WC_TA creditDS。RE_TA creditDS。EBIT_TA creditDS。MVE_BVTD......信贷行业];Y=序号(信用评级);

我们使用预测器X和响应Y适合特定类型的分类集合,称为a袋装决策树.在此上下文中,“袋装”,代表“Bootstrap聚合”。该方法包括生成许多子样本,或者Bootstrap Replicas.,从数据集。这些子样本是随机生成的,从数据集中的客户列表中进行抽样并进行替换。对于每个副本,将生成一棵决策树。每棵决策树都是经过训练的分类器,可以单独用于对新客户进行分类。不过,对于从两个不同的自举复制体中生长出的两棵树的预测可能是不同的。的合奏聚合为所有引导副本生成的所有决策树的预测。如果大多数树预测一个新客户的特定类,那么认为该预测比单独预测任何一棵树更健壮是合理的。此外,如果一个不同的类是由一组更小的树预测的,这个信息也是有用的。事实上,树木的比例预测不同的类别是基础分类的分数在对新数据进行分类时由集成报告。

制作装树袋

构建分类集成的第一步将是为单个树找到一个好的叶子大小;这里我们尝试1、5和10的大小。(更多信息,请参阅统计学和机器学习工具箱文档TreeBagger)。我们从少量的树开始,只有25棵,因为我们主要想比较不同叶子大小的分类误差的初始趋势。为了再现性和公平比较,我们在每次构建分类器时重新初始化随机数生成器,该生成器用于从数据中进行替换取样。

Leaf = [1 5 10];nTrees = 25;rng (9876“旋风”);savedRng =提高;%保存当前RNG设置颜色='bgr'II = 1:长度(叶)%重新初始化随机数生成器,以便%随机样本是相同的每个叶子大小rng (savedRng)%为每个叶片大小创建一个袋装决策树,并在袋外绘制%的错误“oobError”b = TreeBagger (nTrees, X, Y,'Oobprediction'“上”......“CategoricalPredictors”,6,......'minleafsize',叶(ii));绘图(OobError(B),颜色(II))保持结束xlabel(“已长成的树的数量”) ylabel (“Out-of-bag分类错误”)传奇({' 1 '“5”“十”},“位置”“东北”)头衔(“不同叶片尺寸的分类误差”)举行

对于三个叶大小选项,错误是可以比较的。因此,我们将使用叶子大小为10的树,因为它会使树更瘦,计算效率更高。

请注意,我们不必将数据拆分为培训测试子集。这是在内部完成的,它隐含在采样过程中,该过程下潜的方法。在每个引导次迭代时,Bootstrap副本是培训集,遗漏的任何客户(“袋子外”)用作测试点以估计上面报告的袋袋分类错误。

接下来,我们想知道是否所有的特征对分类器的准确性都是重要的。我们通过打开功能的重要性量(Oobpredictorimportance.),并绘制结果以直观地找到最重要的特性。我们现在还尝试了更多的树,并存储分类错误,以便下面进行进一步的比较。

nTrees = 50;叶= 10;rng (savedRng);b = TreeBagger (nTrees, X, Y,“OOB预测重要性”“上”......“CategoricalPredictors”,6,......'minleafsize'、叶);酒吧(b.oobpermutedpredictordordeltaError)Xlabel(“功能部件编号”) ylabel (“Out-of-bag特性重要性”)头衔(“功能重要性的结果”) oobErrorFullX = oobError(b);

特点2,4和6脱颖而出。特点4,股权市场价值/账面价值总债务(MVE_BVTD)是该数据集最重要的预测因子。这一比率与结构模型中的信用可靠性预测指标密切相关,例如默顿模型[5],在该模型中,公司的权益价值与未偿债务进行比较,以确定违约概率。

行业信息,专题6(行业),也相对比其他变量更重要,以评估该数据集公司的信誉。

虽然不是那么重要MVE_BVTD,功能2,保留收益/总资产(雷乌塔),从其他人中脱颖而出。留存收益之间的相关性和公司的年龄(公司已经存在的时间越长,收益可以积累越多,一般而言),进而公司与信誉的年龄(旧公司往往更容易生存在困难时期)。

让我们用预测器拟合一个新的分类集成雷乌塔MVE_BVTD,行业.我们比较了它的分类误差与前一个分类器,它使用所有的特征。

X=[creditDS.RE_TA creditDS.MVE_BVTD creditDS.Industry];rng(savedRng)b=树形起重机(nTrees,X,Y,'Oobprediction'“上”......“CategoricalPredictors”3.......'minleafsize'、叶);oobErrorX246 = oobError (b);情节(oobErrorFullX'B')举行绘图(OobErrorx246,“r”)包含(“已长成的树的数量”) ylabel (“Out-of-bag分类错误”)传奇({的所有功能'特点2,4,6'},“位置”“东北”)头衔(“不同预测器组的分类错误”)举行

当我们删除重要性相对较低的特征(1、3和5)时,分类的准确性不会显著下降,因此我们将使用更精简的分类集成来进行预测。

在此示例中,我们仅启动了一组六个特征,并使用了分类器的特征重要性度量,以及禁止外包分类错误作为屏蔽三个变量的标准。当初始潜在预测器集包含数十个变量时,特征选择可能是耗时的过程。除了我们这里使用的工具(可变重要性和禁止异常错误的“视觉”比较),统计和机器学习工具箱中的其他变量选择工具可能对这些类型的分析有所帮助(请参阅文档)。然而,最终,成功的特征选择过程需要定量工具和分析师​​的判断。

例如,我们这里使用的可变重要性测量是通过测量该特征的值随机置换时,通过测量分类器的预测精度恶化的预测精度的相对影响来估计特征的相对影响。这个想法是,当相关的特征增加到分类器的预测力时,使用改变(在这种情况下置换)值不应影响分类结果。另一方面,相关信息不能随机交换而不会降低预测。现在,如果两个高度相关的功能很重要,则它们将在此分析中排名高。在这种情况下,保持其中一个特征应该足以满足准确的分类,但是一个人不知道从排名结果中单独。人们必须单独检查相关性,或使用专家的判断。也就是说,像变量重要性等工具顺序可以极大地帮助特征选择,但分析师的判断是这个过程中的关键部分。

此时,可以保存分类器(例如,保存分类器.Mat B.),要在未来的会话中加载(负荷分类器)来分类新客户。为了提高效率,建议在训练过程结束后保持精简版的分类器。

b =紧凑(b);

分类新数据

这里,我们使用前面构建的分类集成来为新客户分配信用评级。由于对现有客户的评级也需要定期进行审查,特别是当他们的财务信息发生重大变化时,数据集还可以包含审查中的现有客户的列表。我们从加载新数据开始。

newDS = readtable (‘信用评级(NewCompanies.dat)’);

为了预测这一新数据的信用评级,我们称之为预测方法。该方法返回两个参数,预测的类和分类分数。我们当然希望得到两个输出参数,因为分类分数包含了预测评级的确定性。我们可以复制变量雷乌塔MVE_BVTD行业成一个矩阵X,但由于我们将只打一次电话给预测,我们可以跳过这一步并使用newDS直接。

[predClass, classifScore] =预测(b, [newDS。RE_TA newDS。MVE_BVTDnewDS.行业]);

此时,我们可以创建一个报告。这里我们只在屏幕上显示前三个客户的一个小报告,用于说明目的,但是MATLAB部署工具可以极大地改进这里的工作流。例如,信用分析师可以使用网络浏览器远程运行这种分类,并获得报告,甚至在他们的桌面上没有MATLAB。

i = 1:3 fprintf('客户%d:\n'newDS.ID(我));流('RE/TA=%5.2f\n',newDS.RE_TA(i));fprintf('MVE/BVTD=%5.2f\n'newDS.MVE_BVTD(我));流('行业= %2d\n',newds.industry(i));流('预测评级:%s \ n'我,predClass {});流(“分类分数:\n”);j = 1:长度(b.ClassNames)如果(classifScore (i, j) > 0)流('%s:%5.4f \ n',b.classnames {j},classifscore(i,j));结束结束结束
客户60644:RE/TA=0.22 MVE/BVTD=2.40行业=6预测评级:AA分类分数:A:0.2874 AA:0.6919 AAA:0.0156 BBB:0.0051客户33083:RE/TA=0.24 MVE/BVTD=1.51行业=4预测评级:BBB分类分数:A:0.0751 BB:0.0017 BBB:0.9232客户63830:RE/TA=0.18 MVE/BVTD=1.69行业=7预测评级:A分类分数:A:0.6629 AA:0.0067 B:0.0008 BB:0.0005 BBB:0.3291

保持预测的评级和相应分数的记录对于分类器质量的定期评估有用。我们在此存储此信息表格大批泼妇

一会= b.ClassNames;predDS =[表(newDS.ID predClass) array2table (classifScore)];predDS.Properties.VariableNames = {“ID”“预评级”,类名{:};

例如,可以将此信息保存到逗号分隔的文本文件中PredictedRatings.dat使用命令

writetable (predDS PredictedRatings.dat);

或使用“数据库工具箱”直接写入数据库。

反向测试:分类过程分析

验证历史是分析或评估信用评级质量的过程。有许多不同的措施和测试与这项任务相关(例如,参见巴塞尔银行监管委员会[2])。在此,我们重点探讨以下两个问题:

  • 与实际评级相比,预测评级的准确性如何?这里“预测评级”是指那些从自动分类过程,获得和实际评级分配信贷委员会将在一起预测评级及其分类分数,和其他的信息,比如新闻和经济状况来决定最终的评级。

  • 根据客户的信誉度,实际评级对他们的评级有多高?这是在事后例如,在一年后,当知道哪些公司在一年内违约时进行分析。

文件Creditrating_expost.dat.包含上一节中考虑的相同公司的“后续”数据。它包含委员会分配给这些公司的实际评级,以及一个“违约标志”,表明相应公司是否在评级过程的一年内违约(如果1)或未违约(如果0)。

expostds = readtable(“CreditRating_ExPost.dat”);

比较预测的评级与实际评级。训练自动分类器的基本原理是加快信贷委员会的工作。预测的评级越准确,委员会花在审查预测评级上的时间就越少。因此,可以想象,委员会希望定期检查预测评级与他们分配的最终评级的匹配程度,如果不匹配似乎令人担忧,则建议重新培训自动分类器(可能包括新功能)。

我们可以用来比较预测和实际评级的第一个工具是混淆矩阵,现成的统计和机器学习工具箱:

C=混淆图(曝光率、预测率、预测率);分类(C{'aaa''aa''一种'“BBB”'bb''B'“CCC”})

行对应实际评级,列对应预测评级。头寸的数量(i,j)在混乱矩阵中,指示有多少客户获得实际评级并被预测为评级j.例如,位置(2)告诉我们有多少客户被信用委员会评为“a”,但被自动分类器预测为“AA”。你也可以用百分比来表示这个矩阵。通过具有相同真实评级的观察值的数量对每个值进行归一化。

C.Normalization =“行规范化”

预测和实际评级之间的良好一致性将导致主对角线上的值主导一行中的其他值,理想的值接近1。在这种情况下,我们实际上看到了一个关于“B”的重要分歧,因为大约一半被信用委员会评为“B”的客户被自动分类器预测为“BB”。另一方面,令人欣慰的是,除了“BBB”之外,大多数情况下评级相差最多一个等级。

混淆矩阵也可以用来比较机构分配的内部评级和第三方评级;在实践中经常这样做。

对于每个特定的评级,我们可以计算预测评级和实际评级之间的一致性的另一个度量。我们可以建立一个受试者工作特征(ROC)曲线使用性能曲线函数,并检查曲线下的区域(AUC).的性能曲线函数作为论证,实际评级是我们的基准,我们正在比较的标准以及通过自动化过程确定的“BBB”分类分数。让我们在我们的示例中建立一个ROC并计算评级'BBB'的AUC。

[xVal yVal, ~, auc] = perfcurve (exPostDS.Rating predDS.BBB,“BBB”);情节(xVal yVal)包含(的假阳性率) ylabel (“真阳性率”)文本(0.5,0.25,strcat (“AUC =”num2str (auc)),“EdgeColor”“k”)头衔(“ROC曲线BBB,预测与实际评级”

这里是如何建立中华民国的解释。回想一下,对于每个客户,自动分类器将返回每个信用评级的分类评分,特别是对于“BBB”,这可以解释为该客户应该被评级为“BBB”的可能性有多大。为了构建ROC曲线,我们需要改变分类阈值.也就是说,将客户分类为“BBB”的最低分数。换句话说,如果阈值是t,如果他们的“BBB”得分大于或等于,我们只将客户归类为“BBB”t.例如,假设这家公司XYZBBB评分为0.87。如果实际额定值XYZ(信息exPostDS。评级然后是'bbb',然后'XYZ将被正确地分类为“BBB”的任何阈值不超过0.87。这是一个真阳性,它会增加所谓的敏感分类器。对于大于0.87的任何门槛,该公司不会收到“BBB”评级,我们将有一个假阴性的情况。为了完成描述,现在假设XYZ的实际评级为“BB”。那么当临界值超过0.87时,它将被正确地拒绝为“BBB”,成为“a”真正的消极,从而增加所谓的特异性分类器。但是,对于高达0.87的阈值,它将成为一个假阳性(它会被归类为“BBB”,而实际上是“BB”)。ROC曲线是通过绘制真阳性(敏感性)与假阳性(1特异性)的比例来构建的,阈值从0到1不等。

AUC,顾名思义,就是ROC曲线下的面积。AUC是越接近1,更准确的分类器(1)的一个完美的分类器会有AUC。在这个例子中,AUC似乎足够高,但是它将由委员会决定的AUC级别评级应该触发一个建议来提高自动分类器。

比较下一年的实际评级和违约情况。用于评估信用评级中隐含的客户排名的常见工具是累积精度剖面(CAP),以及相关的准确比率衡量。这样做的目的是衡量评级与次年观察到的违约数量之间的关系。人们可能会认为,评级越高,违约越少。如果所有评级的违约率都是一样的,那么评级系统将与一个幼稚(且无用)的分类系统没有什么不同。在这个分类系统中,客户被随机分配了一个评级,而不考虑他们的信用度。

不难看出性能曲线函数也可用于构造CAP。与以前一样,我们比较的标准不是评级,而是从Creditrating_expost.dat.文件。我们使用的分数是一个“虚拟分数”,它表明了评级列表中隐含的信用等级。虚拟评分只需要满足以下条件:评分越高的客户得到的虚拟评分越低(他们“不太可能有默认值为1的标志”),以及任何两个评分相同的客户得到的虚拟评分相同。当然,违约概率可以作为分数传递,但我们这里没有违约概率我们不需要估算违约概率来构建CAP,因为我们没有验证违约概率。我们用这个工具评估的是评级的好坏排名客户根据信誉。

通常,考虑中的评级系统的上限与“完美评级系统”的上限一起绘制。后者是一个假设的信用评级系统,最低评级包括所有违约者,没有其他客户。此完美曲线下的面积是评级系统可达到的最大可能AUC。按照惯例,AUC根据上限进行调整,以减去天真的系统也就是随机给客户评级的系统的CAP。朴素系统的CAP只是从原点到(1,1)的一条直线,AUC为0.5。的准确比率然后定义为调整后的AUC(考虑系统的AUC减去原始系统的AUC)与最大精度(完美系统的AUC减去原始系统的AUC)的比率。

ratingsList = {'aaa''aa''一种'“BBB”'bb''B'“CCC”};nratings =长度(RATingsList);dummydelta = 1 /(nratings + 1);Dummyrank = Linspace(Dummydelta,1-Dummydelta,Nratings)';d = semostds.def_tplus1;Fractotdef = Sum(D)/长度(D);maxacc = 0.5  -  0.5 * fractotdef;r = double(序号(expostds.rating,[],Ratingslist));s = dummyrank(r);[xval,yval,〜,auc] = perfcurve(d,s,1); accRatio = (auc-0.5)/maxAcc; fprintf('实际评级的精度比:%5.3f\n', accRatio);xPerfect (1) = 0;xPerfect (2) = fracTotDef;xPerfect (3) = 1;yPerfect (1) = 0;yPerfect (2) = 1;yPerfect (3) = 1;xNaive (1) = 0;xNaive (2) = 1;yNaive (1) = 0; yNaive(2) = 1; plot(xPerfect,yPerfect,“——k”,xval,yval,'B'xNaive yNaive,“同意”)包含(“占所有公司的比例”) ylabel (“违约公司的比例”)头衔(“累积准确性概要”)传奇({“完美的”“实际的”“天真的”},“位置”“东南”)文本(xVal (2) + 0.01, yVal -0.01 (2),“CCC”)文本(xVal (3) + 0.01, yVal -0.02 (3),'B')文本(xVal (4) + 0.01, yVal -0.03 (4),'bb'
实际评级的精度比:0.850

读取帽子信息的关键是在“扭结”中,标记为评级'CCC,''B,'和'BB的曲线。例如,第二扭结与第二最低评级'B,'相关联,并且它位于(0.097,0.714)。这意味着9.7%的客户被排名为'b'或更低在观察到的违约中,他们占了71.4%。

一般来说,准确率应被视为一个相对的度量,而不是一个绝对的度量。例如,我们可以在同一个图中添加预测评级的上限,并计算其准确率,将其与实际评级的准确率进行比较。

rpred = double(序号(predds.predrating,[],Ratingslist));spred = dummyrank(rpred);[xvalpred,yvalpred,〜,aucpred] = perfcurve(d,spred,1);Accratiopred =(AUCPRED-0.5)/ MAXACC;流(“预测评级的准确率:%5.3f\n”, accRatioPred);情节(xPerfect yPerfect,“——k”,xval,yval,'B'xNaive yNaive,“同意”......xvalpred,yvalpred,“:r”)包含(“占所有公司的比例”) ylabel (“违约公司的比例”)头衔(“累积准确性概要”)传奇({“完美的”“实际的”“天真的”“预测”},“位置”“东南”
预测评级的准确率:0.830

预测评级的准确率较小,其上限大多低于实际评级的上限。这是合理的,因为实际评级是由考虑预测评级的信贷委员会指定的额外的信息,可以是重要的微调评级。

最后发言

MATLAB提供了广泛的机器学习工具,除了袋装决策树,可以在信用评级的背景下使用。在统计学和机器学习工具箱中,你可以找到分类工具,如判别分析和朴素贝叶斯分类器。MATLAB还提供了深度学习工具箱™。此外,数据库工具箱和MATLAB部署工具可以为您提供更灵活的工作流程,以适应您自己的偏好和需求。

这里没有计算违约概率。对于信用评级,违约概率通常是根据信用评级迁移历史计算的。看到transprob财务工具箱中的参考页™ 了解更多信息。

参考书目

[1] Altman,《财务比率、判别分析与企业破产预测》,金融杂志,第23卷第4期(1968年9月),第589-609页。

[2] 巴塞尔银行监管委员会,“内部评级系统验证研究”,国际清算银行(BIS),第14号工作文件,修订版,2005年5月。可在以下网址查阅:https://www.bis.org/publ/bcbs_wp14.htm.

[3]巴塞尔银行监管委员会,“资本计量和资本标准的国际趋同:修订框架”,国际清算银行(BIS),综合版,2006年6月。可以在:https://www.bis.org/publ/bcbsca.htm。

G.吕弗勒和P. N.波许,基于Excel和VBA的信用风险建模英格兰西苏塞克斯:威利金融,2007。

[5] Merton, R.,《企业债务定价:利率的风险结构》,金融杂志,卷。29,2,(5月,1974),第449-70页。