精华内容
下载资源
问答
  • 主要利用公司价值模型将信用风险引入到变化类型权证期权定价中,通过鞅和概率方法,推导出信用风险变化类型权证期权定价公式,给出了更切合实际期权定价 。
  • 信用风险评级模型开发过程

    千次阅读 2019-02-18 10:44:25
    一、信用风险评级模型的类型 信用风险计量体系包括主体评级模型和债项评级两部分。主体评级和债项评级均有一系列评级模型组成,其中主体评级模型可用“四张卡”来表示,分别是A卡、B卡、C卡和F卡;债项评级模型通常...

    参考《基于R语言的证券公司信用风险计量和管理》第三章

    一、信用风险评级模型的类型

    信用风险计量体系包括主体评级模型和债项评级两部分。主体评级和债项评级均有一系列评级模型组成,其中主体评级模型可用“四张卡”来表示,分别是A卡、B卡、C卡和F卡;债项评级模型通常按照主体的融资用途,分为企业融资模型、现金流融资模型和项目融资模型等。

    A卡,又称为申请者评级模型,主要应用于相关融资类业务中新用户的主体评级,适用于个人和机构融资主体。

    B卡,又称为行为评级模型,主要应用于相关融资类业务中存量客户在续存期内的管理,如对客户可能出现的逾期、延期等行为进行预测,仅适用于个人融资主体。

    C卡,又称为催收评级模型,主要应用于相关融资类业务中存量客户是否需要催收的预测管理,仅适用于个人融资主体。

    F卡,又称为欺诈评级模型,主要应用于相关融资类业务中新客户可能存在的欺诈行为的预测管理,适用于个人和机构融资主体。

    我们主要讨论主体评级模型的开发过程。

    二、信用风险评级模型开发流程概述

    图2.1 评级模型开发流程

    典型的评级模型开发流程如图2.1所示。该流程中各个步骤的顺序可根据具体情况的不同进行适当调整,也可以根据需要重复某些步骤。

    信用风险评级模型的主要开发流程如下:

    (1) 数据获取,包括获取存量客户及潜在客户的数据。存量客户是指已经在证券公司开展相关融资类业务的客户,包括个人客户和机构客户;潜在客户是指未来拟在证券公司开展相关融资类业务的客户,主要包括机构客户,这也是解决证券业样本较少的常用方法,这些潜在机构客户包括上市公司、公开发行债券的发债主体、新三板上市公司、区域股权交易中心挂牌公司、非标融资机构等。

    (2) EDA(探索性数据分析)与数据描述,该步骤主要是获取样本总体的大概情况,以便制定样本总体的数据预处理方法。描述样本总体情况的指标主要有缺失值情况、异常值情况、平均值、中位数、最大值、最小值、分布情况等。

    (3) 数据预处理,主要工作包括数据清洗、缺失值处理、异常值处理,主要是为了将获取的原始数据转化为可用作模型开发的格式化数据。

    (4) 变量选择,该步骤主要是通过统计学的方法,筛选出对违约状态影响最显著的指标。

    (5) 模型开发,该步骤主要包括变量分段、变量的WOE(证据权重)变换和逻辑回归估算三部分。

    (6) 主标尺与模型验证,该步骤主要是开发某类主体的主标尺并进行模型的验证与校准。

    (7) 模型评估,该步骤主要是根据模型验证和主标尺设计的结果,评估模型的区分能力、预测能力、稳定性,并形成模型评估报告,得出模型是否可以使用的结论。

    (8) 模型实施,即模型的部署和应用。

    (9) 监测与报告,该步骤主要工作是定期检测模型的使用情况,并关注和定期检验模型的区分能力与预测能力的变化及模型稳定性的变化,在出现模型可能不能满足业务需求的情况时,反馈至模型开发团队,及时进行模型更新或重新开发。

    三、基于Logistic回归的标准评分卡模型开发实现

    3.1 明确要解决的问题

    在开发信用风险评级模型(包括个人和机构)之前,首先要明确我们需要解决的问题。因为,个人信用风险评级模型包括申请者评级、行为评级、催收评级、欺诈评级等几类,开发每一类评级模型所需要的数据也是不同的,例如开发个人申请者评级模型需要的是个人客户申请融资类业务时提交的数据,开发个人行为评级模型需要的是存量个人客户的历史行为数据,这两部分数据及需要解决的问题,也存在较大的差异。因此,在开发信用风险评级模型之前,我们需要明确开发模型的类型。此处以开发个人客户的申请者评级模型为例,来详细讲述此类模型的开发过程。

    开发申请者评分模型所需要的数据是个人客户申请融资类业务时所需的数据,包括反映个人还款意愿的定性数据,应用申请者评分模型的目的是预测该申请客户在未来一段时间发生违约的概率。

    我们做预测模型的一个基本原理是用历史数据来预测未来,申请者评分模型需要解决的问题是未来一段时间(如12个月)融资人出现违约(如至少一次90天或90天以上逾期)的概率。在这个需求中,“未来一段时间”为表现时间窗口(performance window),“融资人出现至少一次90天或90天以上逾期”为观察时间窗口(sample window)。个人主体的违约跟个人行为习惯有很大的相关性,因此我们可以通过分析个人样本总体中客户的历史我违约频率来确定表现时间窗口观察时间窗口。这两个窗口的确定对于我们要解决的问题,有着非常重要的影响,我们将放在第二步中结合具体的数据来分析,并讲述具体的确定方法。

     

    3.2 数据描述和探索性数据分析

    数据准备和数据预处理是整个信用风险模型开发过程中最重要也是最耗时的工作了。通常情况下,数据准备和数据预处理阶段消耗的时间占整个模型开发时间的80%以上,该阶段主要的工作包括数据获取、探索性数据分析、缺失值处理、数据校准、数据抽样、数据转换,还包括离散变量的降维、连续变量的优先分段等工作。

    明确了要解决的问题后,接下来我们就要搜集相关的数据了。此处,我们以互联网上经常被用来研究信用风险评级模型的加州大学机器学习数据库中的german credit data为例,来详细讲述个人客户信用风险评级模型的开发方法。

    German credit data 的数据来自”klaR”包

     

    install.packages(“klaR”)

    library(“klaR”)

    data(GermanCredit)

    View(GermanCredit)      #查看该数据集

    该数据集包含了1000个样本,每个样本包括了21个变量(属性),其中包括1个违约状态变量“credit_risk”,剩余20个变量包括了所有的定量和定性指标,分别如表3.1所示。

    接下来,我们需要检查数据的质量,主要包括缺失值情况、异常值情况及其他处理方法。缺失值和异常值处理的基本原则是处理前后的分布总体保持一致。

     

    3.21 用户数据的缺失值处理:

    3.21 用户数据的缺失值处理:

    在我们搜集样本时,许多样本中一般都含有缺失值,这种情况在现实问题中非常普遍,这会导致一些不能处理缺失值的分析方法无法应用,因此,在信用风险评级模型开发的第一步我们就要进行缺失值处理。缺失值处理的方法,包括如下几种。

    (1) 直接删除含有缺失值的样本。

    (2) 根据样本之间的相似性填补缺失值。

    (3) 根据变量之间的相关关系填补缺失值。

    直接删除含有缺失值的样本时最简单的方法,尤其是这些样本所占的比例非常小时,用这种方法就比较合理,但当缺失值样本比例较大时,这种缺失值处理方法误差就比较大了。在采用删除法剔除缺失值样本时,我们通常首先检查样本总体中缺失值的个数,在R中使用complete.cases()函数来统计缺失值的个数。

     >GermanCredit[!complete.cases(GermanCredit),]

    >nrow(GermanGredit[!complete.cases(GermanCredit),]

    >GermanCredit<-na.omit(GermanCredit)    #删除包含缺失值的样本

    >View(GermanCredit)                     #查看结果

    根据样本之间的相似性填补缺失值是指用这些缺失值最可能的值来填补它们,通常使用能代表变量中心趋势的值进行填补,因为代表变量中心趋势的值反映了变量分布的最常见值。代表变量中心趋势的指标包括平均值、中位数、众数等,那么我们采用哪些指标来填补缺失值呢?最佳选择是由变量的分布来确定,例如,对于接近正态分布的变量来说,由于所有观测值都较好地聚集在平均值周围,因此平均值就就是填补该类变量缺失值的最佳选择。然而,对于偏态分布或者离群值来说,平均值就不是最佳选择。因为偏态分布的大部分值都聚集在变量分布的一侧,平均值不能作为最常见值的代表。对于偏态分布或者有离群值的分布而言,中位数是更好地代表数据中心趋势的指标。对于名义变量(表3.1中的定性指标),通常采用众数填补缺失值。

    我们将上述分析放在一个统一的函数centralImputation()中,对于数值型变量,我们用中位数填补,对于名义变量,我们用众数填补

    上述按照中心趋势进行缺失值填补的方法,考虑的是数据每列的数值或字符属性,在进行缺失值填补时,我们也可以考虑每行的属性,即为我们要讲述的第三种处理缺失值的方法,根据变量之间的相关关系填补缺失值。

    当我们采用数据集每行的属性进行缺失值填补时,通常有两种方法,第一种方法是计算k个(本文k=10)最相近样本的中位数并用这个中位数来填补缺失值,如果缺失值是名义变量,则使用这k个最近相似数据的加权平均值进行填补,权重大小随着距离待填补缺失值样本的距离增大而减小,本文我们采用高斯核函数从距离获得权重,即如果相邻样本距离待填补缺失值的样本的距离为d,则它的值在加权平均中的权重为:

     

    在寻找跟包含缺失值的样本最近的k个邻居样本时,最常用的经典算法是knn(k-nearest-neighbor) 算法,它通过计算样本间的欧氏距离,来寻找距离包含缺失值样本最近的k个邻居,样本x和y之间欧式距离的计算公式如下:

     

    式中:δ_i ( )是变量i的两个值之间的距离,即

     

    在计算欧式距离时,为了消除变量间不同尺度的影响,通常要先对数值变量进行标准化,即:

     

    我们将上述根据数据集每行的属性进行缺失值填补的方法,封装到knnImputation()函数中

    调用knnImputation()函数,用knn方法填补缺失值

     

    3.22 用户数据的异常值处理:

    离群点检测、

    缺失值处理完毕后,我们还需要进行异常值处理。异常值是指明显偏离大多数抽样数据的数值,比如个人客户的年龄大于100时,通常认为该值为异常值。找出样本总体中的异常值,通常采用离群值检测的方法。

    离群值检测的方法有单变量离群值检测、局部离群值因子检测、基于聚类方法的离群值检测等方法。由于本文采用的样本总体GermanCredit已经进行了数据预处理,即已经做了缺失值和异常值处理,因此,我们以随机产生的样本为例来说明离群值检测的方法。

    (1)第一种方法是单变量离群值检测,该方法的原理是通过求解单变量数值的第1个和第3个四分位数的值,将数值小于第1个四分位数和大于第3个四分位数的值定义为离群值。该方法可通过R包grDevices中的boxplot.stats()函数实现。

    我们用随机数来演示获取异常值的方法,

     

     

    需要特别说明的是,在实际的样本搜集和数据预处理中,我们应该首先对个人客户的违约做出定义,并根据对违约的定义对搜集的样本进行必要的校准。一般情况下,我们搜集的数据为非标准化的数据,如表3.2所示,该表中假设搜集的是前10个客户在两年内的历史违约情况。

     

     

    在表3.2所示的数据集中,如果我们假设连续出现三个月逾期可被定义为违约,则客户6至客户9可被确认为违约。然而,为了明确违约的概念,我们还需要确定基准时间和观察时间窗口。如果当前时间是2016年7月末,则只有6和7两个客户为违约,其他客户均属于正常客户,如果当前时间是2016年9月末,则只有6、7、8三个客户为违约,客户9已经自愈,则再次变成正常客户。

    结合上述分析,在明确评分卡要解决的实际问题时,还应该确定表现时间窗口和观察时间窗口,而这两个窗口的确定,需要根据我们搜集的数据来具体确定。他们的确定方法,分别如下:

    在确定变现时间窗口的长度时,我们通常需要客户从开始开立融资类业务时到最近时间点(或至少两年以上的历史逾期情况)的逾期表现,用图形表示,如图3.7所示。

     

    按照图3.7所示的表现时间窗口的定义方法,我们对样本总体进行统计分析,以逾期90天定义为违约,会得出表3.3所示的统计结果。

     

    表3.3中8月最后一列数据3.48%表示,2.1日开立的所有账户中,8个月后出现逾期90天以上的账户占样本的比重为3.48%。我们通过这样统计方法,并绘制样本总体的违约状态变化曲线,即可得到如图3.8所示的曲线。从图3.8所示的曲线中我们可以看出,在账户开立第11个月到第13个月时,客户的违约状态达到稳定状态,曲线变得非常平稳。此时,我们可以确定评分卡的表现时间窗口为11个月到13个月,即我们将违约状态变得稳定的时间段确定为表现时间窗口。这种方法可使我们开发的评分卡模型的区分能力和预测能力准确性均达到最优稳定状态。

     

     

    由图3.8的曲线可以看出,客户开立融资类业务的账户的起始阶段发生违约的频率是不断增多的,但随着时间的推移发生违约的客户的占比处于稳定状态。那么,我们在开发信用风险评分卡模型时,需要选择客户违约处于稳定状态的时间点来作为最优表现时间窗口,这样既可以最大限度地降低模型的不稳定性,也可以避免低估最终的违约样本的比率。例如,当我们选择表现时间窗口为6个月时,样本总体中的违约样本占比仅为3%左右,而实际违约样本占比约为4.5%。

    上例中,观察时间窗口我们确定为90天,当然也可以是60天或30天,但当观察时间窗口确定为30天时,客户的违约状态将会更快地达到稳定状态。如果我们按照某个监管协议(如巴塞尔协议)的要求开发信用风险评分卡模型,则观察时间窗口也要按照监管协议的要求确定。除此之外,观察时间窗口的确定要根据样本总体和证券公司的风险偏好综合考虑确定。但在个人信用风险评级模型开发领域,大多数将逾期90天及以上定义为个人客户的违约状态。

    以上讲的都是开发申请者评分卡模型时表现时间窗口的确定方法,在开发个人客户的行为评分卡和催收评分卡模型时,表现时间窗口的确定方法也算是类似的。但开发这两类模型时,表现时间窗口的长度却跟申请者评分模型有较大不同,如催收评分卡模型的表现时间窗口通常设定为2周,甚至更短的时间。因为实际业务开展过程中,通常客户逾期超过2周,就要启动催收程序了。

    个人客户的信用风险评级模型开发进行至此时,我们已经得到了没有缺失值和异常值的样本总体,违约的定义确定了,表现时间窗口和观察时间窗口也确定了。接下来,我们将进入评分卡模型开发的第三步数据集准备阶段了。

     

    3.3 数据集准备

    在缺失值和处理完成后,我们就得到了可用作信用风险评级模型开发的样本总体。通常为了验证评级模型的区分能力和预测准确性,我们需要将样本总体分为样本集和测试集,这种分类方法被称为样本抽样。常用的样本抽样方法包括简单随机抽样、分层抽样和整群抽样三种。

     

    数据集准备:

    在缺失值和处理完成后,我们就得到了可用作信用风险评级模型开发的样本总体。通常为了验证评级模型的区分能力和预测准确性,我们需要将样本总体分为样本集和测试集,这种分类方法被称为样本抽样。常用的样本抽样方法包括简单随机抽样、分层抽样和整群抽样三种。

    简单随机抽样:

     

    smp1<-sample(nrow(GermanCredit),10,replace=F)

    样本集可表示为:

     

    train_data=GermanCredit[-smp1,]

    test_data=GermanCredit[smp1,]

    分层抽样:在R中,使用strata()函数来实现上述的分成抽样方法:

    strata(data,stratanames=NULL,size,method=c(“srswor”,”srswr”,”poisson”,”systematic”), pik,description=F)

    其中,data即为待抽样数据集;stratanames为分层所依据的变量名称;size为每层中将要抽出的样本数,其顺序应当与数据集中该变量各水平出现的顺序一致,且在使用该函数前,应当首先对数据集按照该变量进行升序排序;method参数用于选择列示的4中2抽样方法,分别为无放回、有放回、泊松、系统抽样,默认去srswor(无放回);pik用于设置各层中各样本的抽样概率;description用于选择是否输出含有各层基本信息的结果。

    我们假设按照GermanCredit数据集中的housing属性进行分层抽样,每层抽取5个样本,代码如下:

    #分层抽样

    library(sampling)

    x<-GermanCredit[order(GermanCredit[,"housing"]),]

    sub_set<-strata(x,stratanames = "housing",size = c(5,5,5),method = "srswor")

    result<-getdata(GermanCredit,sub_set)

    查看抽样结果可见,抽样数据集的最后多了3列内容,分别是ID_unit表示抽样样本在原样本总体中的ID,Prob表示样本在各层内的抽样概率,Stratum表示抽样样本属于哪一层。

    第三种抽样方法整群抽样,是指以样本总体中的某个变量分群为依据,对样本进行随机抽样的方法。在考虑使用整群抽样时,一般要求各群对数据总体有较好的代表性,即群内各样本的差异较大,而群间的差异较小。因此,当群间差异较大时,整群抽样往往具有样本分布面不广、样本对样本总体的代表性相对较差等缺点,整群抽样方法通常情况下应用较少。

    在R中,我们使用cluster()函数实现整群抽样,其基本格式为:

     

    cluster(data,clustername,size,method=c(“srswor”,”srswr”,”poisson”,”systematic”), pik,description=F)

    该函数的参数中,除了clustername和size略有不同外,其他参数都与strata函数完全相同。clustername是指用来划分群的变量名称,size为一个整数,表示需要抽取的群数。代码如下:

     

    > sub_cluster<-cluster(GermanCredit,clustername = "housing",size = 1,method = "srswor",description = T)

    Number of selected clusters: 1

    Number of units in the population and number of selected units: 1000 713

    > cluster_data<-getdata(GermanCredit,sub_cluster)

    > View(cluster_data)

    根据本文采用的样本总体GermanCredit数据较少的特点,在进行个人主体信用风险评级模型开发时,我们采用基于无放回随机抽样的五折交叉验证的方法来进行模型开发和验证。所谓五折交叉验证是指我们将样本总体随机分为5份,每次都是取其中的4份做模型开发,另外一份做模型验证,连续这样做5次,并对这5次的模型验证的统计指标取平均值,即为模型的最终验证结果。交叉验证也是在样本总体较少时,经常采用的模型开发和验证方法,这种方法得到的评级模型可较好的提高模型的区分能力、预测准确性和稳定性。抽样代码如下:

     

    train_kfold<-sample(nrow(GermanCredit),800,replace=F)

    train_kfolddata<-GermanCredit[train_kfold,]

    test_kfolddata<-GermanCredit[-train_kfold,]

    在接下来的讲解中,我们均以train_kfolddata作为样本集来用作模型开发,以test_kfolddata作为测试集用作模型验证。五折交叉验证时,我们只需要重复上述步骤5次,并选出稳定性和区分能力最优的模型即为我们最终开发的信用风险评级模型。

    3.4 变量筛选

    模型开发的前三步主要讲的是数据处理的方法,从第四步开始我们将逐步讲述模型开发的方法。在进行模型开发时,并非我们收集的每个指标都会用作模型开发,而是需要从收集的所有指标中筛选出对违约状态影响最大的指标,作为入模指标来开发模型。接下来,我们将分别介绍定量指标和定性指标的筛选方法。

     

    3.41 定量指标的筛选方法

    模型开发的前三步主要讲的是数据处理的方法,从第四步开始我们将逐步讲述模型开发的方法。在进行模型开发时,并非我们收集的每个指标都会用作模型开发,而是需要从收集的所有指标中筛选出对违约状态影响最大的指标,作为入模指标来开发模型。接下来,我们将分别介绍定量指标和定性指标的筛选方法。

    (1)第一种定量指标的筛选方法:用随机森林法寻找自变量中对违约状态影响最显著的指标。

     

    #第一种方法:随机森林法

    #基于变量均值的精度下降,获取自变量的重要性

    #mtry代表在每一棵树的每个节点处随机抽取mtry 个特征,通过计算每个特征蕴含的信息量,特征中选择一个最具有分类能力的特征进行节点分裂。

    #varimp代表重要性函数。

    #经过变量间的相关系数调整后,获取自变量的重要性

    #经过变量间的不平衡性调整后,获取自变量的重要性

     

    (2)第二种定量指标的筛选方法:计算变量间的相对重要性,并通过相对重要性的排序,获取自变量中对违约状态影响最显著的指标,代码如下:

     

    #第二种方法:计算变量间的相对重要性,回归法

    library(relaimpo)

    lmMod<-lm(credit_risk~.,data = quant_GermanCredit)  #线性回归

    relImportance<-calc.relimp(lmMod,type = "lmg",rela = TRUE)

    #计算自变量间的相对重要性

    sort(relImportance$lmg,decreasing = TRUE)

    #排序并输出自变量间的相对重要性

    (3)第三种定量指标的筛选方法:通过自变量间的广义交叉验证法,获取自变量中对违约状态影响最显著的指标,代码如下:

     

    #第三种方法:自变量间的广义交叉验证法

    library(earth)

    marsModel<-earth(credit_risk~.,data = quant_GermanCredit)

    ev<-evimp(marsModel)

    #经过自变量间的广义交叉验证后,获取自变量的重要性

    (4)第四种定量指标的筛选方法:通过自变量的逐步回归法,获取自变量中对违约状态影响最显著的指标,代码如下:

    #第四种方法:自变量的逐步回归法

    base.mod<-lm(credit_risk~1,data = quant_GermanCredit)

            #获取线性回归模型的截距

    all.mod<-lm(credit_risk~.,data = quant_GermanCredit)

            #获取完整的线性回归模型

    stepMod<-step(base.mod,scope = list(lower=base.mod,upper=all.mod),

                  direction = "both",trace = 0,steps = 1000)

            #采用双向逐步回归法,筛选变量

    shortlistedVars<-names(unlist(stepMod[[1]]))

            #获取逐步回归得到的变量列表

    shortlistedVars<-shortlistedVars[!shortlistedVars %in%"(Intercept)"]

            #删除逐步回归的截距

    print(shortlistedVars)

    #输出逐步回归后得到的变量

     

    (5)第五种定量指标的筛选方法:采用“Boruta”法,获取自变量中对违约状态影响最显著的指标,代码如下:

     

    #第五种方法:"Boruta"法

    library(Boruta)

    boruta_output<-Boruta(credit_risk~.,data = na.omit(quant_GermanCredit),

                          doTrace=2)

    boruta_signif<-names(boruta_output$finalDecision[

      boruta_output$finalDecision %in%c("Confirmed","Tentative")])

    #获取自变量中确定的和实验性的指标

    print(boruta_signif)

    #Levels: Tentative Confirmed Rejected

    #Confirmed坚定的;Tentative踌躇的;Rejected拒绝的

     

    plot(boruta_output,cex.axis=.7,las=2,xlab="",main="Variable Importance")

    #绘制变量显著性表示的箱图

    图3.9 箱图表示变量重要性(Boruta法)

     

    综上,我们共计详细使用了五种定量指标入模的方法,在实际的模型开发过程中,我们可以只选择其中一种方法,也可以结合多种方法,来筛选出定量数据的入模指标。综合这五种方法,我们筛选出了对违约状态影响最显著的四个入模指标,如表3.11所示。

     

    3.42 定性指标的筛选方法

    定量指标是数值型的,我们还可以用回归的方法来筛选,那么定性的指标怎么办呢?

    R里面给我们提供了非常强大的IV值计算算法,通过引用R里面的informationvalue包,来计算各指标的IV值,即可得到各定性指标间的重要性度量,选取其中的high predictive指标即可。

    有很多小伙伴不知道informationvalue是什么:

    我大概说一下,IV值衡量两个名义变量(其中一个是二元变量)之间关联性的常用指标。

     

    library(InformationValue)

    library(klaR)

    credit_risk<-ifelse(train_kfolddata[,"credit_risk"]=="good",0,1)

    #将违约状态变量用0和1表示,1表示违约。

    tmp<-train_kfolddata[,-21]

    data<-cbind(tmp,credit_risk)

    data<-as.data.frame(data)

     

    factor_vars<-c("status","credit_history","purpose","savings","employment_duration",

                   "personal_status_sex","other_debtors","property",

                   "other_installment_plans","housing","job","telephone","foreign_worker")

    #获取所有名义变量

    all_iv<-data.frame(VARS=factor_vars,IV=numeric(length(factor_vars)),

                       STRENGTH=character(length(factor_vars)),stringsAsFactors = F)

    #初始化待输出的数据框

    for(factor_var in factor_vars)

    {

      all_iv[all_iv$VARS==factor_var,"IV"]<-InformationValue::IV(X=

                                                                   data[,factor_var],Y=data$credit_risk) 

      #计算每个指标的IV值

      all_iv[all_iv$VARS==factor_var,"STRENGTH"]<-attr(InformationValue::IV(X=

                                                                              data[,factor_var],Y=data$credit_risk),"howgood") 

      #提取每个IV指标的描述

    }

    all_iv<-all_iv[order(-all_iv$IV),]    #排序IV

    由结果可知,可选择的定性入模指标,如表3.12所示。

    https://img-blog.csdn.net/20170802235919157?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGxsMTUyODIzODczMw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/0/gravity/SouthEast

     

    综上所述,模型开发中定量和定性的入模指标如表3.13所示。

     

    对入模的定量和定性指标,分别进行连续变量分段(对定量指标进行分段),以便于计算定量指标的WOE和对离散变量进行必要的降维。对连续变量的分段方法通常分为等距分段和最优分段两种方法。等距分段是指将连续变量分为等距离的若干区间,然后在分别计算每个区间的WOE值。最优分段是指根据变量的分布属性,并结合该变量对违约状态变量预测能力的变化,按照一定的规则将属性接近的数值聚在一起,形成距离不相等的若干区间,最终得到对违约状态变量预测能力最强的最优分段

     

    3.5 WOE值计算

    对入模的定量和定性指标,分别进行连续变量分段(对定量指标进行分段),以便于计算定量指标的WOE和对离散变量进行必要的降维。对连续变量的分段方法通常分为等距分段和最优分段两种方法。等距分段是指将连续变量分为等距离的若干区间,然后在分别计算每个区间的WOE值。最优分段是指根据变量的分布属性,并结合该变量对违约状态变量预测能力的变化,按照一定的规则将属性接近的数值聚在一起,形成距离不相等的若干区间,最终得到对违约状态变量预测能力最强的最优分段。

    我们首先选择对连续变量进行最优分段,在连续变量的分布不满足最优分段的要求时,在考虑对连续变量进行等距分段。此处,我们讲述的连续变量最优分段算法是基于条件推理树(conditional inference trees, Ctree)的递归分割算法,其基本原理是根据自变量的连续分布与因变量的二元分布之间的关系,采用递归的回归分析方法,逐层递归满足给定的显著性水平,此时获取的分段结果(位于Ctree的叶节点上)即为连续变量的最优分段。其核心算法用函数ctree()表示。

     

    评分卡模型开发-WOE值计算:

    http://blog.csdn.net/lll1528238733/article/details/76600598

     

     

    展开全文
  • 第一章:评分卡开发过程 ...两种类型的开发过程方案基本相同,但有两个主要差别: 通常,行为评分卡比申请评分卡更精确。因为行为评分卡在对账户状态进行预测时基于更多数据要素(交易产生) 拒绝演绎...

     

    第一章:评分卡的开发过程

    标准评分卡

    信用评分卡类型:

    1. 申请评分卡。对新贷款申请,判断违约风险,并据此决定批准或拒绝。一次性
    2. 行为评分卡。已审批通过,后期的检测和管理业务账户的手段。反复进行

    两种类型的开发过程方案基本相同,但有两个主要差别:

    • 通常,行为评分卡比申请评分卡更精确。因为行为评分卡在对账户状态进行预测时基于更多的数据要素(交易产生的)
    • 拒绝演绎技术只在申请评分卡的开发过程中使用。

    评分卡的优势:表格样式,易于理解;总信用评分用加法计算,简单;依据可计算得到的比率,信用状况是正常或违约的概率与总的评分直接相关;对于每个预测变量,根据不同类别或范围分别赋予一定分值,使得最终消费者清楚如何提高其信用评分。

    开发流程

     

     问题准备

    首先要确定以下几个问题:

    1. 在特定业务重点、财务结果和具体信贷产品历史表现的基础上,确定违约和正常的定义。
    2. 确定计划的评分卡的范围、开发和实施窗口
    3. 识别数据的范围和来源,内部还是外部,并确保能够取得这些数据
    4. 设计主要项目管理计划,对时间、资源、人员等进行管理

     

    数据获取与整合

     

    转载于:https://www.cnblogs.com/Hyacinth-Yuan/p/7956538.html

    展开全文
  • 信用风险评级模型的类型信用风险计量体系包括主体评级模型和债项评级两部分。主体评级和债项评级均有一系列评级模型组成,其中主体评级模型可用“四张卡”来表示,分别是A卡、B卡、C卡和F卡;债项评级模型通常...

    信用风险评级模型的类型:

    信用风险计量体系包括主体评级模型和债项评级两部分。主体评级和债项评级均有一系列评级模型组成,其中主体评级模型可用“四张卡”来表示,分别是A卡、B卡、C卡和F卡;债项评级模型通常按照主体的融资用途,分为企业融资模型、现金流融资模型和项目融资模型等。 

    A卡,又称为申请者评级模型,主要应用于相关融资类业务中新用户的主体评级,适用于个人和机构融资主体。 

    B卡,又称为行为评级模型,主要应用于相关融资类业务中存量客户在续存期内的管理,如对客户可能出现的逾期、延期等行为进行预测,仅适用于个人融资主体。 

    C卡,又称为催收评级模型,主要应用于相关融资类业务中存量客户是否需要催收的预测管理,仅适用于个人融资主体。 

    F卡,又称为欺诈评级模型,主要应用于相关融资类业务中新客户可能存在的欺诈行为的预测管理,适用于个人和机构融资主体。 

    我们主要讨论主体评级模型的开发过程。

    信用风险评分卡为信用风险管理提供了一种有效的、经验性的解决方法,是消费信贷管理中广泛应用的技术手段。

    课程链接:信用风险评估评分卡建模方法及原理

    评分卡是信用风险评估领域常见的建模方法。评分卡并不加单对应于某一种机器学习算法,而是一种通用的建模框架,讲原始数据通过分箱后进行特征工程变换,继而应用于线性模型进行建模的一种方法。

    更多精品课程:

    阿里云云计算专业

    阿里云大数据专业

    阿里云云安全专业

    展开全文
  • 该资源属于代码类资源,用jupyter notebook编写,文档类型是ipynb,只能用jupyter note 打开,主要内容是机器学习算法中决策树算法,数据来源于p2p网贷数据,通过此模型算法可以很好对客户是否会违约进行预测...
  • 文章目录1、明确需求和目的1.1 比赛目的1.2 Home Credit介绍2、 数据收集3、数据预处理3.1 数据整合3.1.1 加载相关库和数据集3.1.2 主要数据集概览3.2 数据清洗3.2.1 多余列删除3.2.2 数据类型转换3.2.3 缺失值...

    1、明确需求和目的

    • 现代社会,越来越多的人使用信用卡进行消费,大部分人使用信用卡之后会按时还款,但仍然有少部分人不能在约定时间进行还款,这大大的增加了银行或者金融机构的风险。
    • 本文以某金融机构的历史数据进行建模分析,对客户的还款能力进行评估,以预测新客户是否有信用卡的违约风险,从而决定是否贷款给新客户使用。
    • 本文使用AUC(ROC)作为模型的评估标准。

    2、 数据收集

    • 本文使用的数据集来源于kaggle平台,主要有两份数据集。
    • application_trainapplication_test:训练集和测试集数据,包括每个贷款申请的信息。每笔贷款都有自己的行,并由特性SK_ID_CURR标识。训练集的TARGET 0:贷款已还清,1:贷款未还清。

    3、数据预处理

    3.1 数据整合
    3.1.1 加载相关库和数据集
    • 使用的库主要有:pandas、numpy、matplotlib、seaborn
    • 使用的数据集:kaggle平台提供的数据集文件
    import numpy as np
    import pandas as pd 
    import os
    import matplotlib.pyplot as plt
    import seaborn as sns
    import warnings
    
    warnings.filterwarnings('ignore')
    
    print(os.listdir("../input/"))		# List files available
    -------------------------------------------------
    ['sample_submission.csv', 'credit_card_balance.csv', 'installments_payments.csv', 'HomeCredit_columns_description.csv', 'previous_application.csv', 'POS_CASH_balance.csv', 'bureau_balance.csv', 'application_test.csv', 'bureau.csv', 'application_train.csv']
    
    3.1.2 主要数据集概览

    首先看一下训练集数据:

    # Training data
    app_train = pd.read_csv('../input/application_train.csv')
    print('Training data shape: ', app_train.shape)
    --------------------------------------
    Training data shape:  (307511, 122)
    
    app_train.head()
    

    在这里插入图片描述

    从上面可以看出,训练集数据有122个特征,307511条数据。

    再来看一下测试集数据:

    # Testing data 
    app_test = pd.read_csv('../input/application_test.csv')
    print('Testing data shape: ', app_test.shape)
    ---------------------------------------------
    Testing data shape:  (48744, 121)
    
    app_test.head()
    

    在这里插入图片描述
    从上面可以看出,测试集数据有121个特征,48744条数据,相比训练集,少了一个特征 TARGET,即我们需要预测的目标值(0表示贷款按时偿还,1表示贷款未按时偿还。)。

    检查一下TARGET列的分布,看看每一类贷款的数量:

    app_train['TARGET'].value_counts()
    ----------------------------------------
    0    282686
    1     24825
    Name: TARGET, dtype: int64
    

    可以看出按时还款的类别明显要比未按时还款的类别多, 属于样本不均衡的问题,后续可以考虑使用权重法或采样法等办法来进行解决。

    转化成图形更直观的对比一下:

    app_train['TARGET'].astype(int).plot.hist()
    

    在这里插入图片描述

    3.2 数据清洗
    3.2.1 多余列的删除

    首先删除空白值超过一半的列 :

    app_train = app_train.dropna(thresh=len(app_train) / 2 , axis=1) 
    

    定义一个函数,看一下剩余数据的缺失值情况:

    # Function to calculate missing values by column# Funct 
    def missing_values_table(df):
            # Total missing values
            mis_val = df.isnull().sum()
            
            # Percentage of missing values
            mis_val_percent = 100 * df.isnull().sum() / len(df)
            
            # Make a table with the results
            mis_val_table = pd.concat([mis_val, mis_val_percent], axis=1)
            
            # Rename the columns
            mis_val_table_ren_columns = mis_val_table.rename(
            columns = {0 : 'Missing Values', 1 : '% of Total Values'})
            
            # Sort the table by percentage of missing descending
            mis_val_table_ren_columns = mis_val_table_ren_columns[
                mis_val_table_ren_columns.iloc[:,1] != 0].sort_values(
            '% of Total Values', ascending=False).round(1)
            
            # Print some summary information
            print ("Your selected dataframe has " + str(df.shape[1]) + " columns.\n"      
                "There are " + str(mis_val_table_ren_columns.shape[0]) +
                  " columns that have missing values.")
            
            # Return the dataframe with missing information
            return mis_val_table_ren_columns
    
    # Missing values statistics
    missing_values = missing_values_table(app_train)
    ---------------------------------------------------
    Your selected dataframe has 81 columns.
    There are 26 columns that have missing values.
    
    missing_values.head(10)
    

    在这里插入图片描述

    从上面可以看出,还有好几列的值缺失将近50%,缺失比例较高,我们一并将这些列进行删除。当然,也可以选择进行缺失值填充,这里选择删除。

    drop_columns = ["FLOORSMAX_AVG","FLOORSMAX_MODE","FLOORSMAX_MEDI","YEARS_BEGINEXPLUATATION_AVG","YEARS_BEGINEXPLUATATION_MODE",
                    "YEARS_BEGINEXPLUATATION_MEDI","TOTALAREA_MODE","EMERGENCYSTATE_MODE"]
    app_train = app_train.drop(drop_columns, axis=1) 
    

    删除了缺失值较多的列之后,还有其它列的缺失值需要处理,我们可以先进行数据类型转换,后面再统一采用填充的方式进行处理。

    3.2.2 数据类型转换

    先来看一下各个类型的数据有多少:

    # Number of each type of column
    app_train.dtypes.value_counts()
    ----------------------------------
    int64      41
    float64    20
    object     12
    dtype: int64
    

    object类型的有12个,需要将其转换成数值类型,我们先看一下它们各自的特征类别有多少:

    注意 nunique 不考虑空值。

    # Number of unique classes in each object column
    app_train.select_dtypes('object').apply(pd.Series.nunique, axis = 0)
    -------------------------------------
    NAME_CONTRACT_TYPE             2
    CODE_GENDER                    3
    FLAG_OWN_CAR                   2
    FLAG_OWN_REALTY                2
    NAME_TYPE_SUITE                7
    NAME_INCOME_TYPE               8
    NAME_EDUCATION_TYPE            5
    NAME_FAMILY_STATUS             6
    NAME_HOUSING_TYPE              6
    OCCUPATION_TYPE               18
    WEEKDAY_APPR_PROCESS_START     7
    ORGANIZATION_TYPE             58
    dtype: int64
    
    • 标签编码( Label Encoding):它给类别一个任意的顺序。分配给每个类别的值是随机的,不反映类别的任何固有方面。所以我们在只有两个类别的时候使用标签编码。例如上面的‘NAME_CONTRACT_TYPE’等,我们就可以使用标签编码。
    • 独热编码(One-Hot Encoding):为分类变量中的每个类别创建一个新列。当类别>2的时候,我们将使用独热编码。例如上面的‘CODE_GENDER’等。当然独热编码的缺点也很明显,就是特征可能会暴增,但我们可以使用PCA或其他降维方法来减少维数。

    对于类别只有2个的特征,我们使用 Label Encoding 进行数据的转换(注意测试集也同样需要进行转换):

    from sklearn.preprocessing import LabelEncoder
    
    # Create a label encoder object
    le = LabelEncoder()
    le_count = 0
    
    # Iterate through the columns
    for col in app_train:
        if app_train[col].dtype == 'object':
            # If 2 or fewer unique categories
            if len(list(app_train[col].unique())) <= 2:
                # Train on the training data
                le.fit(app_train[col])
                # Transform both training and testing data
                app_train[col] = le.transform(app_train[col])
                app_test[col] = le.transform(app_test[col])
                
                # Keep track of how many columns were label encoded
                le_count += 1
                
    print('%d columns were label encoded.' % le_count)
    -------------------------------------------------
    3 columns were label encoded.
    

    从上面可以看出3个类别全部完成了转换,接下来使用 One-Hot Encoding 进行剩余数据的转换,此处选择使用pandas的get_dummies()函数,直接映射为数值型(测试集一并进行转换):

    # one-hot encoding of categorical variables
    app_train = pd.get_dummies(app_train)
    app_test = pd.get_dummies(app_test)
    
    print('Training Features shape: ', app_train.shape)
    print('Testing Features shape: ', app_test.shape)
    ----------------------------------------------------
    Training Features shape:  (307511, 182)
    Testing Features shape:  (48744, 239)
    

    从上面可以看出,此时测试集列数多于训练集,因为训练集删除了一些多余的列,我们对两份数据取并集,只需要处理共同拥有的列即可:

    train_labels = app_train['TARGET']
    
    # Align the training and testing data, keep only columns present in both dataframes
    app_train, app_test = app_train.align(app_test, join = 'inner', axis = 1)
    
    # Add the target back in
    app_train['TARGET'] = train_labels
    
    print('Training Features shape: ', app_train.shape)
    print('Testing Features shape: ', app_test.shape)
    ------------------------------------------------
    Training Features shape:  (307511, 179)
    Testing Features shape:  (48744, 178)
    
    3.2.3 缺失值处理

    数据类型转换完成,我们就可以统一进行缺失值处理,可以采用中位数进行填充:

    from sklearn.preprocessing import Imputer
    
    imputer = Imputer(strategy = 'median')
    train = app_train.drop(columns = ['TARGET'])
    
    column_list = train.columns.tolist()
    
    # fit with Training_data, fill both Training_data and Testing_data
    imputer.fit(train)
    train = imputer.transform(train)
    test = imputer.transform(app_test)
     
    train = pd.DataFrame(train, columns = column_list)
    app_train = pd.concat([train, app_train['TARGET']], axis=1)
    app_test = pd.DataFrame(test, columns = column_list)
    print('Training data shape: ', app_train.shape)
    print('Testing data shape: ', app_test.shape)
    --------------------------------------------------
    Training data shape:  (307511, 179)
    Testing data shape:  (48744, 178)
    

    检查是否还有缺失值:

    print(app_train.isnull().sum())
    print(app_test.isnull().sum())
    

    需要注意的是,此处"SK_ID_CURR" 经过处理之后变成float类型,需要重新转换成 int类型:

    app_train["SK_ID_CURR"] = app_train["SK_ID_CURR"].astype(int)
    app_test["SK_ID_CURR"] = app_test["SK_ID_CURR"].astype(int)
    
    3.2.4 异常值处理

    对年龄进行异常值检查(原始数据为天,需要除以365,并且取负数):

    (app_train['DAYS_BIRTH'] / -365).describe()
    -----------------------------------------------
    count    307511.000000
    mean         43.936973
    std          11.956133
    min          20.517808
    25%          34.008219
    50%          43.150685
    75%          53.923288
    max          69.120548
    Name: DAYS_BIRTH, dtype: float64
    

    看起来很正常,无异常,再看一下在职天数:

    app_train['DAYS_EMPLOYED'].describe()
    -----------------------------------------
    count    307511.000000
    mean      63815.045904
    std      141275.766519
    min      -17912.000000
    25%       -2760.000000
    50%       -1213.000000
    75%        -289.000000
    max      365243.000000
    Name: DAYS_EMPLOYED, dtype: float64
    

    最大值为365243天,换算成年即100年,明显不合理,属于异常值。

    出于好奇,对异常客户进行分析,看看他们的违约率比其他客户高还是低。

    anom = app_train[app_train['DAYS_EMPLOYED'] == 365243]
    non_anom = app_train[app_train['DAYS_EMPLOYED'] != 365243]
    print('The non-anomalies default on %0.2f%% of loans' % (100 * non_anom['TARGET'].mean()))
    print('The anomalies default on %0.2f%% of loans' % (100 * anom['TARGET'].mean()))
    print('There are %d anomalous days of employment' % len(anom))
    -------------------------------------------------------------
    The non-anomalies default on 8.66% of loans
    The anomalies default on 5.40% of loans
    There are 55374 anomalous days of employment
    

    可以看到,这些异常值的客户违约率比其他客户还要低,且数量还不少。

    我们需要对异常值进行处理,处理异常值取决于具体情况,没有固定的规则。最安全的方法之一就是将异常值视为缺失值处理,然后在使用算法之前填充它们。这里我们将用(np.nan)填充异常值,然后创建一个新的布尔列,指示该值是否异常。

    # Create an anomalous flag column
    app_train['DAYS_EMPLOYED_ANOM'] = app_train["DAYS_EMPLOYED"] == 365243
    
    # Replace the anomalous values with nan
    app_train['DAYS_EMPLOYED'].replace({365243: np.nan}, inplace = True)
    

    同样对测试集进行异常值处理:

    app_test['DAYS_EMPLOYED_ANOM'] = app_test["DAYS_EMPLOYED"] == 365243
    app_test["DAYS_EMPLOYED"].replace({365243: np.nan}, inplace = True)
    
    print('There are %d anomalies in the test data out of %d entries' % (app_test["DAYS_EMPLOYED_ANOM"].sum(), len(app_test)))
    ---------------------------------------------------
    There are 9274 anomalies in the test data out of 48744 entries
    

    使用中位数对异常值转换后的缺失值进行填充:

    from sklearn.preprocessing import Imputer
    
    imputer = Imputer(strategy = 'median')
    train = app_train['DAYS_EMPLOYED'].values.reshape(-1, 1)
    
    imputer.fit(train)
    train = imputer.transform(app_train['DAYS_EMPLOYED'].values.reshape(-1, 1))
    test = imputer.transform(app_test['DAYS_EMPLOYED'].values.reshape(-1, 1))
     
    app_train['DAYS_EMPLOYED'] = train
    app_test['DAYS_EMPLOYED'] = test
    
    print(app_train['DAYS_EMPLOYED'].describe())
    print(app_test['DAYS_EMPLOYED'].describe())
    ---------------------------------------------
    count    307511.000000
    mean      -2251.606131
    std        2136.193492
    min      -17912.000000
    25%       -2760.000000
    50%       -1648.000000
    75%        -933.000000
    max           0.000000
    Name: DAYS_EMPLOYED, dtype: float64
    count    48744.000000
    mean     -2319.063639
    std       2102.150130
    min     -17463.000000
    25%      -2910.000000
    50%      -1648.000000
    75%      -1048.000000
    max         -1.000000
    Name: DAYS_EMPLOYED, dtype: float64
    

    从上面可以看出,已经没有异常值了。

    3.2.5 重复值处理

    看一下有没有重复值,有则直接删除:

    print(app_train.duplicated().sum())    # 查看重复值的数量
    ------------------------------------------
    0
    

    没有重复值,不需要进行处理。

    4、数据分析

    4.1 相关系数分析

    使用.corr方法计算每个变量与目标之间的相关系数。
    相关系数并不是表示特征“相关性”的最佳方法,但它确实让我们了解了数据中可能存在的关系。

    # Find correlations with the target and sort
    correlations = app_train.corr()['TARGET'].sort_values()
    
    # Display correlations
    print('Most Positive Correlations:\n', correlations.tail(15))
    print('\nMost Negative Correlations:\n', correlations.head(15))
    ---------------------------------------------------------------
    Most Positive Correlations:
     OCCUPATION_TYPE_Laborers                             0.043019
    FLAG_DOCUMENT_3                                      0.044346
    REG_CITY_NOT_LIVE_CITY                               0.044395
    FLAG_EMP_PHONE                                       0.045982
    NAME_EDUCATION_TYPE_Secondary / secondary special    0.049824
    REG_CITY_NOT_WORK_CITY                               0.050994
    DAYS_ID_PUBLISH                                      0.051457
    CODE_GENDER_M                                        0.054713
    DAYS_LAST_PHONE_CHANGE                               0.055218
    NAME_INCOME_TYPE_Working                             0.057481
    REGION_RATING_CLIENT                                 0.058899
    REGION_RATING_CLIENT_W_CITY                          0.060893
    DAYS_EMPLOYED                                        0.063368
    DAYS_BIRTH                                           0.078239
    TARGET                                               1.000000
    Name: TARGET, dtype: float64
    
    Most Negative Correlations:
    EXT_SOURCE_2                           -0.160295
    EXT_SOURCE_3                           -0.155892
    NAME_EDUCATION_TYPE_Higher education   -0.056593
    CODE_GENDER_F                          -0.054704
    NAME_INCOME_TYPE_Pensioner             -0.046209
    DAYS_EMPLOYED_ANOM                     -0.045987
    ORGANIZATION_TYPE_XNA                  -0.045987
    AMT_GOODS_PRICE                        -0.039623
    REGION_POPULATION_RELATIVE             -0.037227
    NAME_CONTRACT_TYPE                     -0.030896
    AMT_CREDIT                             -0.030369
    FLAG_DOCUMENT_6                        -0.028602
    NAME_HOUSING_TYPE_House / apartment    -0.028555
    NAME_FAMILY_STATUS_Married             -0.025043
    HOUR_APPR_PROCESS_START                -0.024166
    Name: TARGET, dtype: float64
    

    从上面看出,和目标值有较大正相关性的有 DAYS_BIRTH 这个特征,有较大负相关性的有 EXT_SOURCE_2 和 EXT_SOURCE_3 这两个特征,可以进一步进行分析:

    plt.figure(figsize=(10, 8))
    # KDE图中按时偿还的贷款
    sns.kdeplot(app_train.loc[app_train['TARGET'] == 0, 'DAYS_BIRTH'] / -365, label = 'target == 0')
    # KDE图中未按时偿还的贷款
    sns.kdeplot(app_train.loc[app_train['TARGET'] == 1, 'DAYS_BIRTH'] / -365, label = 'target == 1')
    plt.xlabel('Age (years)')
    plt.ylabel('Density')
    plt.title('Distribution of Ages')
    plt.show()
    

    在这里插入图片描述

    target == 1曲线向范围的较年轻端倾斜,说明随着客户年龄的增长,他们往往会更经常地按时偿还贷款。虽然这不是一个显著的相关性(-0.07相关系数),但这个变量很可能在机器学习模型中有用,因为它确实会影响目标。

    对于其余两个特征,也可以进行相应的分析,并可以利用这几个特征进行特征工程的选择。(本文为简单起见,未进行特征工程)

    5、模型训练

    5.1 数据标准化
    • 在使用算法之前,进行 数据标准化处理,将数据集中的特征转换成相同的量纲,从而消除不同量纲对算法造成的负面影响。
    from sklearn.preprocessing import Imputer, MinMaxScaler
    
    imputer = Imputer(strategy = 'median')
    scaler = MinMaxScaler(feature_range = [0,1])
    train = app_train.drop(columns = ['TARGET'])
    
    scaler.fit(train)
    train = scaler.transform(train)
    test = scaler.transform(app_test)
    print('Training data shape: ', train.shape)
    print('Testing data shape: ', test.shape)
    --------------------------------------------
    Training data shape:  (307511, 183)
    Testing data shape:  (48744, 183)
    
    5.2 使用逻辑回归训练
    • 直接使用简单的逻辑回归
    from sklearn.linear_model import LogisticRegression
    
    log_reg = LogisticRegression()
    log_reg.fit(train, train_labels)
    
    log_reg_pred = log_reg.predict_proba(test)[:, 1]
    submit = app_test[['SK_ID_CURR']]
    submit['TARGET'] = log_reg_pred
    submit.head()
    submit.to_csv('log_reg_baseline.csv', index = False)
    

    提交之后,分数如下:

    Private Score:0.72683, Public Score:0.73322
    
    • 使用网格交叉验证计算出最佳参数的逻辑回归:
    from sklearn.linear_model import LogisticRegression
    from sklearn.model_selection import GridSearchCV
    param_grid = {'C' : [0.01,0.1,1,10,100],
                  'penalty' : ['l1','l2']}
    log_reg = LogisticRegression()
    grid_search = GridSearchCV(log_reg, param_grid, scoring = 'roc_auc', cv = 5)
    grid_search.fit(train, train_labels)
    
    # Train on the training data
    log_reg_best = grid_search.best_estimator_
    log_reg_pred = log_reg_best.predict_proba(test)[:, 1]
    submit = app_test[['SK_ID_CURR']]
    submit['TARGET'] = log_reg_pred
    submit.head()
    submit.to_csv('log_reg_baseline_gridsearch2.csv', index = False)
    

    使用交叉验证,效果有一点提升,分数如下:

    Private Score:0.72770, Public Score:0.73452
    
    5.3 简单优化

    增加领域知识特征,我们可以创建几个特性,试图捕捉我们认为对于判断客户是否会拖欠贷款可能很重要的信息。

    • CREDIT_INCOME_PERCENT: 信贷金额占客户收入的百分比
    • ANNUITY_INCOME_PERCENT: 贷款年金占客户收入的百分比
    • CREDIT_TERM: 以月为单位支付的期限(因为年金是每月到期的金额)
    • DAYS_EMPLOYED_PERCENT: 就职天数占客户年龄的百分比
    app_train_domain = app_train.copy()
    
    app_train['CREDIT_INCOME_PERCENT'] = app_train_domain['AMT_CREDIT'] / app_train_domain['AMT_INCOME_TOTAL']
    app_train['ANNUITY_INCOME_PERCENT'] = app_train_domain['AMT_ANNUITY'] / app_train_domain['AMT_INCOME_TOTAL']
    app_train['CREDIT_TERM'] = app_train_domain['AMT_ANNUITY'] / app_train_domain['AMT_CREDIT']
    app_train['DAYS_EMPLOYED_PERCENT'] = app_train_domain['DAYS_EMPLOYED'] / app_train_domain['DAYS_BIRTH']
    

    测试集进行同样处理:

    app_test_domain = app_test.copy()
    
    app_test['CREDIT_INCOME_PERCENT'] = app_test_domain['AMT_CREDIT'] / app_test_domain['AMT_INCOME_TOTAL']
    app_test['ANNUITY_INCOME_PERCENT'] = app_test_domain['AMT_ANNUITY'] / app_test_domain['AMT_INCOME_TOTAL']
    app_test['CREDIT_TERM'] = app_test_domain['AMT_ANNUITY'] / app_test_domain['AMT_CREDIT']
    app_test['DAYS_EMPLOYED_PERCENT'] = app_test_domain['DAYS_EMPLOYED'] / app_test_domain['DAYS_BIRTH']
    

    增加领域特征之后,再次使用简单的逻辑回归进行训练(交叉验证太耗时间,用简单的比较看看效果):

    from sklearn.linear_model import LogisticRegression
    
    log_reg = LogisticRegression()
    log_reg.fit(train, train_labels)
    
    log_reg_pred = log_reg.predict_proba(test)[:, 1]
    submit = app_test[['SK_ID_CURR']]
    submit['TARGET'] = log_reg_pred
    submit.head()
    submit.to_csv('log_reg_baseline_domain.csv', index = False)
    

    增加领域特征之后,效果有一点提升,分数如下:

    Private Score:0.72805, Public Score:0.73434
    
    5.4 使用随机森林训练
    • 增加领域特征之后,使用随机森林训练,看看效果怎么样
    from sklearn.ensemble import RandomForestClassifier
    # 随机森林
    random_forest = RandomForestClassifier(n_estimators = 100, random_state = 50, verbose = 1, n_jobs = -1)
    random_forest.fit(train, train_labels)
    predictions = random_forest.predict_proba(test)[:, 1]
    
    submit = app_test[['SK_ID_CURR']]
    submit['TARGET'] = predictions
    submit.to_csv('random_forest_baseline_domain.csv', index = False)
    

    使用随机森林,效果比逻辑回归还要差一些:

    Private Score:0.70975, Public Score:0.70120 
    

    6、总结

    • 本文仅仅使用一个数据集进行模型训练,并使用逻辑回归和随机森林分别预测,并通过简单优化提升了模型效果。
    • 如果进一步进行特征分析,并且使用其它数据集进行训练的话,应该会得到更好的训练模型。
    展开全文
  • 基于python的信用卡评分模型

    万次阅读 多人点赞 2018-05-24 01:25:32
    信用风险指的是交易对手未能履行约定合同中的义务造成经济损失的风险,即受信人不能履行还本付息的责任而使授信人的预期收益与实际收益发生偏离的可能性,它是金融风险的主要类型。 借贷场景中的评分卡是一种以分数...
  • 信用风险信用风险是指由于信用活动中存在不确定性而导致银行遭受损失可能性,确切地说,是所有因客户违约而引起风险。 市场风险:市场风险通常是由金融资产价格变化而产生,市场风险一般又可分为利率...
  • 交易对手未能履行约定契约中的义务而造成经济损失的风险,即受信人不能履行还本付息的责任而使授信人的预期收益与实际收益发生偏离的可能性它是金融风险的主要类型。 巴塞尔协议定义金融风险类型:市场风险、作业...
  • 结果表明,中国保险业仍然存在资产负债错配,流动性隐患和信用风险增加等问题。 此外,这也表明中国保险基金投资投资结构仍有改善空间。 这一结果不仅为中国保险业风险管理提供了相关政策建议,而且填补了...
  • 信用卡评分模型

    2019-05-21 14:32:46
    信用风险指的是交易对手未能履行约定合同中的义务造成经济损失的风险,即受信人不能履行还本付息的责任而使授信人的预期收益与实际收益发生偏离的可能性,它是金融风险的主要类型。 借贷场景中的评分卡是一种以...
  • ·信用风险评分卡类型 ·信用评分模型建立基本流程 1.信用风险定义 ①风险管理概念 风险管理最早起源于美国。1930年由美国管理协会保险部最先倡导风险管理,后面在全球流行开来,随着互联网迅猛发展,大数据、...
  • 信用卡评分模型开发

    2020-06-18 11:06:15
    信用风险指的是交易对手未能履行约定合同中的义务造成经济损失的风险,即受信人不能履行还本付息的责任而使授信人的预期收益与实际收益发生偏离可能性,为金融风险的主要类型 借贷的评分卡,是一种以分数的形式来...
  • 据了解,“信用支付”额度为1-5000元,通过考虑支付宝用户家庭地址、工作性质、手机号码、购买产品类型、性别、年龄等信息综合评定其具体的信用支付额度规模。贷款资金全部由合作银行提供,阿里巴巴旗下成立...
  • 信用评分是一个数字,帮助贷款人评估一个人信用报告,估计其信用风险。信用评分会影响一个人能力,以符合不同类型的信贷和利率变化。一个具有较高信用评分人,可能有资格获得更长贷款期限和更低利率,从...
  • 信用标准评分卡模型开发及实现

    万次阅读 多人点赞 2017-08-03 02:07:58
    一、信用风险评级模型的类型信用风险计量体系包括主体评级模型和债项评级两部分。主体评级和债项评级均有一系列评级模型组成,其中主体评级模型可用“四张卡”来表示,分别是A卡、B卡、C卡和F卡;债项评级模型通常...
  •  秦苍科技数据科学家沈赟:AI在消费金融产品优化以及风险控制中应用(附PPT+视频) | 硬创公开课 ...中国消费金融市场用户大致可以划分为...白领和自雇人群往往拥有央行征信报告,主要使用银行信用卡,以
  • 一、信用风险评级模型的类型 信用风险计量体系包括主体评级模型和债项评级两部分。主体评级和债项评级均有一系列评级模型组成,其中主体评级模型可用“四张卡”来表示,分别是A卡、B卡、C卡和F卡;债项评级模型通常...
  • 信用卡葵花宝典》第三篇阅读笔记是关于收单业务基础知识以及风险管理。银行卡业务从大概念上可以分为发卡业务和收单业务。收单业务通过为商户提供银行卡支付结算服务来获取商户回佣收入,同时通过开展特色收单...
  • 本文主要参考 《数据挖掘与数据化运营实战 思路、方法、技巧与应用》,作者总结了在数据化运营中常见数据分析项目类型。 在这里结合自己理解,简单介绍下图所示分析项目,涉及算法或技术原理可能在后续笔记...
  • (信贷风控一)互联网金融业申请评分卡介绍

    千次阅读 多人点赞 2019-01-20 14:50:10
    互联网金融业申请评分卡的...交易对手未能履行约定契约中的义务而造成经济损失的风险,即受信人不能履行还本付息的责任而使授信人的预期收益与实际收益发生偏离的可能性,它是金融风险的主要类型。 业界常用衡量信...
  • 构建信用风险类型的特征 特征分箱 WOE编码 也就是对应图中(数据预处理、特征构造) 这篇文章我们主要讲解特征选择,要学习特征选择,就要学习以下知识点 特征信息度计算和意义 信用风险单变量分析和...
  • 构建信用风险类型的特征 特征分箱 WOE编码 构建信用风险类型的特征 在我们运用模型之前,我们首先要进行特征工程,其本质是一项工程活动,目的是最大限度地从原始数据中提取特征以供算法和模型使用。特征处理是...
  • 为了满足现代信用风险管理一个主要需求,我们提出了一种非参数生存方法,用于对违约交易对手回收率和回收时间进行建模,通过引入我们所说回收强化 Urn 过程,一种特殊类型的组合随机过程. 新模型允许引出和...
  • 风控策略连载系列 @hefox 互联网金融风控体系及政策设计 1.风控体系介绍 2.风控政策的制定逻辑与关注点 3.场景下量化风险政策设定 ...信用风险的量化逻辑:损失期望/预期损失 损失期望/预期损失 通过...
  • 详细申请评分卡模型

    2019-12-23 22:51:54
    本篇文章将以以下四个主题来进行介绍说明...交易对手未能履行约定契约中的义务而造成经济损失的风险,即受信人不能履行还本付息的责任而使授信人的预期收益与实际收益发生偏离的可能性它是金融风险的主要类型。 坏样...
  • 1.政策与定价

    2021-03-21 09:26:18
    信用风险的量化逻辑上其实主要是量化它的这个损失,这个损失有两大部分: 1)损失期望:就是预期的一个损失, 即损失的平均的一个情况 2)极端损失:在恒定的一个几率里面,或者是在固定的一个观测几率里面,我们...

空空如也

空空如也

1 2 3
收藏数 51
精华内容 20
关键字:

信用风险的主要类型