1. 引言
在当今的大数据和人工智能时代,人工智能机器学习的信用评级受到了学术界、金融财务实业界和政府部门的广泛关注。传统的信用评级,如统计和反向传播(BP)神经网络法存在难以解决小样本、局部极小点、高维数、函数逼近与分类能力差、学习速度低、需指导学习等方面的问题,这严重影响信用评级的质量。因此需要探索新的信用评级法——基于最小二乘支持向量机(LSSVM)的上市公司信用评级,来解决上述诸多方面的问题,以提高信用分类的质量。因此,本文研究不但可以丰富传统的信用评级法,而且对规范金融市场的健康发展有重要的意义。
国外对于信用评级的研究,大致经历了以下几类:(1) 定性分析评级法;(2) 统计分析评级法;(3) 神经网络评级算法;(4) 市场价值的KMV评级法。(1) 定性分析评级法,主要是5C要素分析法和LAPP原则,5C要素分析法主要从Character品格、Capacity能力、Capital资本、Collateral担保、Condition环境等5个方面来分析信用状况;LAPP原则主要从Liquidity流动、Activity活动、Profitability盈利、Potentialities潜力等4个方面分析信用状况。除此之外还有杜邦财务分析体系和沃尔比重分析法等,这些方法的缺点是:主观性较强,受人的主观影响大,为了克服定性分析能力差,缺乏整体概括、定量分析不足等问题,国外从20世纪60年代开始,普遍采用了统计评级法。(2) 统计分析评级法,Beaver (1966)以企业的29个财务指标建立指标体系,通过该指标体系分析企业违约状况,发现财务指标是影响企业违约的重要因素[1]。但是,统计法对数据要求严格,如:数据要服从多元正态分布、变量间不存在多重共线性、配对样本协方差矩阵应相同等等,而现实中的数据难以满足这样的要求。因此,后续学者采用Logistic等方法建立模型,Ohlson (1980)利用Logit回归模型预测企业违约概率,发现在样本数量比较多 时,财务指标对预测具有一定的可信度[2],Colin R. A.和Green R. D. (1982)则证明Logistic模型效果比多变量判别分析模型的效果好[3]。(3) 神经网络算法,20世纪80年代末和90年代初,随着信息技术的发展,神经网络方法引入了信用评级,并且它能解决非正态分布、非线性的信用分类问题,但它难以解决小样本数据、局部极小点、高维数、函数逼近与分类能力弱、学习速度慢等问题。(4) 市场价值的KMV评级法,20世纪90年代后期出现了许多新的信用分类模型,最具代表性的有:KMV公司开发的KMV模型与JPMorgen银行1997年在VaR模型的基础上建立的CreditMetrics模型。但CreditMetrics模型有很多参数需要确定,如等级迁移矩阵、资产之间的相关系数、远期收益率等,这些参数来自长时期统计数据积累,目前中国大陆还少有类似的统计资料。在国内的信用评级模型运用方面,朱顺泉(2009)运用市场价值的KMV评级法对上市公司信用评级进行了研究[4]。孙林(2022)基于一般均衡分析模型,论述发债企业经济类型、行业属性、业务开展情况等对债券违约的影响。然后基于2014~2020年我国上市公司财务数据构建三组面板数据模型,发现企业杠杆水平、多元化经营和行业差异等指标对企业债券违约率存在显著影响,高杠杆和多元化经营策略等因素会不同程度削弱发债企业主营业务竞争力对债券违约的抑制效果[5]。在使用Logistic模型方面,程昊(2020)基于企业内外部风险影响因素,构建风险识别指标体系,使用Logistic模型识别债券违约现象,效果较好[6]。在Z-score模型运用方面,何鑫超(2022)通过紫光集团财务状况和Z值检测证明了紫光集团在发生违约前就具有很高的债券违约风险[7]。
王春峰等(1999)、陈静(1999)、陈晓(2000)、吴世农等(2001)、张鸣等(2005)、石晓军(2005)、朱毅峰(2008)、吴冲等(2009)、余乐安等(2009)等学者相继发表了一些研究成果[8]-[16]。吴冲等(2009)建立了一种基于五级分类的支持向量机集成方法,利用Libsvm对某商业银行信贷的176组样本数据进行实证分析表明:论文提出的方法比其他分类方法的分类精度高,证实了该方法的可行性和有效性。余乐安等(2009)的结果表明:基于核主元分析的带可变惩罚因子最小二乘模糊支持向量机模型取得了较好的分类结果。
2. 支持向量机方法与原理
支持向量机(Support Vector Machine,简称SVM)就是通过支持向量运算的分类器。这里的“机”是机器的意思,可以理解为分类器或分类函数。
2.1. 线性分类方法
在训练数据集中,每个数据集都有n个的特征和一个类别标志,可以认为这些数据集在一个n维空间里。目标是找到一个n − 1维的超平面(hyperplane),使此超平面可以将数据集中的数据分成2类或多类,每部分数据都属于同一个类别。这样的超平面很多,这里要找一个最佳的超平面。因此,需要增加一个约束条件:此超平面到每边最近数据点的距离是最大的,即最大间隔的超平面。
对于需要训练的数据集T,它的数据可以分为C1和C2两类。对于线性分类函数:
。对C1类的数据集,有:
。数据中至少有一个点
这个点称为最近点。对于C2类的数据集,有:
。数据中至少有一个点
。这个点就是最近点。这两个约束条件可合并为:
。这里的
是点
对应的分类值(−1或者1)。目的是求出w和b,超平面函数是
。为了求最优的f(x),期望训练数据集中的每个点到超平面的距离最大。
2.2. 非线性分类方法
支持向量机SVM的优势之一就是可以做非线性分类。它结合使用拉格朗日乘子和KKT条件,以及核函数可以做非线性分类。
,
这里
为n个特征(属性)的训练数据i;
为训练数据i的标签值;
为训练数据i的拉格朗日乘子;
为核函数;
和b是训练数据后所形成的值。
可以调节
来匹配维度的大小,当
越高,维度就越低。
2.3. 非线性分类核函数
非线性问题可以通过函数映射到高维度后,把一个非线性问题转换成一个线性问题。比如:二维平面下的一个点
,可以映射到一个5维空间,此空间的5个维度分别是:
。从低维映射到高维后,有两个问题需要解决:一是如何映射?二是问题计算变得更复杂了。可以使用核函数来解决此问题。
核函数(kernel function)就是核技巧(kernel trick)。核函数提供了一个方法,就是通过原始特征空间的向量来计算高维空间的内积,而不用管映射方式。
可以用核函数代替
。核函数有很多,通常使用高斯核,其公式如下:
3. 变量选择与建模样本
我们选择我国上市商业银行信用评级来进行支持向量机的应用研究。根据联合、中诚信、大公国际等权威信用评级机构的评估报告,对上市商业银行进行信用评级一般选择如下指标:总资产,贷款总额,存款总额,所有者权益,营业收入,净利润,总资产收益率,净资产收益率,不良贷款率,拨备覆盖率,存货比,流动性比率,资本充足率,一级资本充足率,核心一级资本充足率。
考虑到数据的获取尽可能完善和准确,只采用了信用评级为AAA、AA+、AA这3个等级的国内商业银行。信用等级为AA−的银行数据较少或者残缺较多。本文选用2个变量作为特征值,流动性比率和利润率,有如下原因:一是不同银行间的资产规模大小不一,为消除数据绝对值差异对研究带来的影响,宜使用财务比率;二是为方便后面画图更直观,故只取了两个特征值向量进行训练;三是流动性比率反映了银行偿债能力,利润率反映银行盈利能力,是信用评级的重要指标。
3.1. 获取数据
由于使用tushare数据接口获取的银行财务数据残缺值太多,且银行个数太少。故改用优矿网站上的API功能获取。
2个特征变量利润比x1和流动比x2根据优矿平台https://uqer.datayes.com上20个变量计算得到的。
数据营业收入和净利润:NIncome和revenue。
利润比 × 1 (特征或属性1)的计算公式为:NIncome/revenue。
流动资产计算公式如下:
流动资产 = tradingFA + loanToOthBankFi + intReceiv + purResaleFa + CReserCB + derivAssets
+ deposInOthBfi + preciMetals + investAsReceiv;
流动负债计算公式如下:
流动负债 = CBBorr + depos + loanFrOthBankFi + tradingFL + soldForRepura + payrollPayable
+ taxesPayable + intPayable + bondPayable + deposFrOthBfi + derivLiab;
流动比 × 2 (特征或属性2) = 流动资产/流动负债。
这些变量的具体含义望参见优矿平台https://uqer.datayes.com上20个变量中的研究数据菜单。
除此之外,我们还通过查看了银行年报以及信用评估机构发布的评级报告来收集数据。
3.2. 读入数据
导入Python的numpy、pandas、sklearn、matplotlib模块以及train_test_split、pyplot、svm函数。
import pandas as pd
import numpy as np
import sklearn
from sklearn.model_selection import train_test_split
import matplotlib as mpl
import matplotlib.pyplot as plt
from sklearn import svm
#使用loadtxt读取数据可直接将文本数据转换成数组,便于操作
#为方便后面进行训练,将AAA设为3,AA+设为2.5,AA设为2
data=np.loadtxt('F:/2glkx/data/zonghe1.txt',delimiter=',')
#将浮点型数据转换成字符串,便于之后操作
data=data.astype(str)
4. 基于支持向量机的商业银行信用评级训练与测试结果
4.1. 将数据分为训练集和测试集
x, y = np.split(data, (2,), axis=1)
x_train, x_test, y_train, y_test = sklearn.model_selection.train_test_split(x, y, random_state=1, train_size=0.6)
上面函数split()参数分别为split(数据,分割位置,轴=1(水平分割) or 0(垂直分割);上面的sklearn.model_selection.train_test_split()的作用是随机划分训练集与测试集。在函数train_test_split(train_data, train_target, test_size=数字, random_state=0)中的参数解释如下:
train_data为要划分的样本特征集;train_target为要划分的样本结果;test_size为样本占比,如果是整数的话就是样本的数量。random_state为随机数的种子,这里的随机数种子就是该组随机数的编号,当需重复试验时,保证得到一组随机数是一样。例如每次填1,其他参数一样的情况下得到的随机数组是一样的。但当填0或不填,每次得到的都会不一样。随机数的产生取决于种子,随机数和种子之间的关系遵从以下两个规则:种子不同产生不同的随机数;种子相同即使实例不同也产生相同的随机数。
4.2. 训练分类器
# model = svm.SVC(C=0.1, kernel='linear', decision_function_shape='ovr')
model = svm.SVC(C=0.8, kernel='rbf', gamma=100, decision_function_shape='ovr')
model.fit(x_train, y_train.ravel())
其中的kernel='linear'时,为线性核,C支持向量机目标函数中惩罚项参数,C越大分类效果越好,但有可能会过拟合(defaul C=1)。
kernel='rbf'时(default)为高斯核,gamma支持向量机核函数中的
参数,gamma值越小,分类界面越连续;gamma值越大,分类界面越“散”,分类效果越好,但有可能会过拟合。
decision_function_shape='ovr'时,为one v rest,即一个类别与其他类别进行划分,decision_function_shape='ovo'时,为one v one,即将类别两两之间进行划分,用二分类的方法模拟多分类的结果。
得到如下结果:
SVC(C=0.8, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape='ovr', degree=3, gamma=100, kernel='rbf',
max_iter=-1, probability=False, random_state=None, shrinking=True,
tol=0.001, verbose=False)
经过对gamma取值的多次实验结果,发现取gamma=100支持向量机模型的效果最好。
print (model.score(x_train, y_train))
得到如下结果:
0.7962962962962963
从上可见,计算SVC分类器精度,训练集精度为0.80。
5. 商业银行信用评级的可视化图形
#确定坐标轴范围,x,y轴分别表示两个特征
x=x.astype(float)
y=y.astype(float) #将x,y数据类型转换回来为后面操作
x1_min, x1_max = x[:, 0].min(), x[:, 0].max()# 第0列的范围
x2_min, x2_max = x[:, 1].min(), x[:, 1].max()# 第1列的范围
x1, x2 = np.mgrid[x1_min:x1_max:200j, x2_min:x2_max:200j] # 生成网格采样点
grid_test = np.stack((x1.flat, x2.flat), axis=1) #测试点
grid_hat = model.predict(grid_test)
grid_hat = grid_hat.reshape(x1.shape)
#预测分类值grid_hat = grid_hat.reshape(x1.shape) # 使之与输入的形状相同
#绘制图形
cm_light = mpl.colors.ListedColormap(['#A0FFA0', '#FFA0A0', '#A0A0FF'])
cm_dark = mpl.colors.ListedColormap(['g', 'r', 'b'])
x1=x1.astype(float)
x2=x2.astype(float)
grid_hat=grid_hat.astype(float)
plt.pcolormesh(x1, x2, grid_hat, cmap=cm_light)
plt.scatter(x[:, 0], x[:, 1], c='b', edgecolors='k', s=25, cmap=cm_dark) # 样本
plt.xlabel(u'Current Ratio', fontsize=12)
plt.ylabel(u'Profit Ratio', fontsize=12)
plt.xlim(x1_min, x1_max)
plt.ylim(x2_min, x2_max)
plt.show()
执行上述Python代码,得到如图1所示的图形。
Figure 1. 3 classifications of the credit rating of commercial banks
图1. 商业银行信用评级的3分类
6. 商业银行信用评级的3分类结果分析与结论
从图1中可以看到,根据样本集训练的分类器将散落的样本点分为3类,即AAA、AA+、AA,分别分布在三个颜色区域。上方紫色区域为AAA级商业银行,可以看到,其利润率水平最高,通过散点分布可看到流动性比率集中在0.3~0.5之间,但也有个别流动性比率十分高,超过了0.5。红色区域为AA+商业银行,其利润率水平低于AAA级商业银行,高于AA级,流动性比率也大致介于0.3~0.5之间。绿色区域为AA级银行,AA级银行利润率水平低,但流动性比率较高,大部分在0.5~0.8之间。
由于数据样本数量受到实际情况(银行数量)的限制,以及数据不是全出自同一个来源(优矿、银行年报、评级评估报告),且最终使用进行训练的数据是通过再计算得出的(利润率 = 净利润/营业收入,流动性比率 = 流动资产/流动负债),具有较大误差,且只选择了两个特征变量(利润率、流动性比率)。因此,不能全面充分地反应出商业银行的信用评级。但从图1中我们可以看出,利润率是评估银行信用的一个重要指标,利润率反映了银行的盈利能力,信用级别越高的银行,其盈利能力越强。
基金项目
本研究为广东省重点建设学科科研能力提升项目(项目编号2024ZDJS113)、广州华商学院应用型示范专业-金融科技专业建设项目HS2024SFZY08、广州华商学院金融科技专业核心课程教研室建设项目HS2024ZLGC43等阶段性成果。