《武汉工程大学学报》  2020年01期 113-118   出版日期:2021-01-25   ISSN:1674-2869   CN:42-1779/TQ
Spark集群中还贷问题的逻辑回归模型研究


近几年,随着移动互联网的迅猛发展及互联网+向服务、金融、通讯、娱乐、物流、共享经济等各个行业的渗透,数据已经由被动产生过渡到了主动产生及自动产生阶段,大数据的概念已经是无所不在[1-2]。行业数据量越大,其蕴含的信息也就越多,通过有效的数据挖掘手段,从大数据中获得知识的可能性也就越大。传统的数据挖掘及分析技术,一般需要将挖掘的数据全部载入计算机内存,由单个或多个CPU进行计算,其所能处理的数据规模及构建挖掘模型的速度已经远远不能满足大数据时代的需要。大数据环境下的数据挖掘需要解决3个核心问题:1)构建有效的大数据存储结构。2)在存储结构的基础上,进行大规模数据的并行或分布式计算,提高构建挖掘模型的速度。3)适合于大数据挖掘的语言、挖掘算法模型库及可视化结果展示[3-5]。大数据的分析及挖掘技术,目前也是业界研究的热点,大规模数据的分类模型[6-8]及逻辑回归分类问题[9-11]已经得到了广泛的研究。构建在Spark分布式计算平台上的MLib等大数据挖掘模型库已经得到一定程度的应用[12-14],本文就如何在Spark集群环境下,使用R语言对大规模银行贷款数据进行逻辑回归分类建模进行了深入的研究,数据来自https://packages.revolutionanalytics.com /datasets/中的mortDefault.zip文件,文件解压后按贷款人申请贷款年份共10个文件,每个文件有1×106个记录。1 Spark集群环境 Apache Spark是专为大规模数据处理而设计的快速通用的分布式计算引擎,经过优化的DAG执行引擎使得在同等数据规模下,Spark的处理速度要比Hadoop MapReduce至少快10倍以上。Spark包含数据查询分析库,机器学习库(machine learning library,Mlib),并行图形计算库及大规模实时流数据处理库等,开发人员可以使用R、Pathon、Java、Scala等语言在这些通用库的支持下进行并行应用程序的开发。目前Spark可以以独立集群方式运行,也可以运行在Hadoop Yarn或Apache Mesos上,且能访问HDFS、HBase、Hive等多种数据源。由于Spark分布式计算引擎具有快速的数据处理能力、多语言支持、丰富的通用库及可跨平台等特点,使得其得到快速的应用,正在形成一个高速发展应用广泛的生态系统。R语言是能够进行数据处理、计算、统计分析和绘图[15-16],在目前大数据环境下得到广泛应用的一种语言,RStudio Server对R语言进行了扩展,使其可以运行在Spark集群环境下。Sparklyr是一个基于R语言,面向大规模数据分析及挖掘的工具包,通过该工具包,用户可利用RStudio Web客户端:1)进行Spark集群远程连接管理。2)使用dplyr包对来源于HDFS、HBase、Hive的数据进行查询、筛选、排序、分组、聚集、连接等操作。3)调用MLib库中的算法进行大规模数据挖掘,建立模型。4)对模型进行评价及预测结果的可视化展示。2  Spark集群环境下的逻辑回归分类逻辑回归是一种分类方法,主要用于二分类问题(即输出只有两种1或者0,分别代表两个类别),逻辑回归使用非线性的Sigmoid函数进行分类预测,函数形式为:[g(z)=11+e-z] (1)设影响预测结果的输入特征变量为[X(x1,x2,][…,xn)],回归系数向量为[θ][(θ0,θ1,θ2,…,θn)],则[θ0+θ1x1+,…,+θnxn=i=1nθixi=θTx] (2)构造预测函数为:[hθx=gθTx=11+e-θTx] (3)若[θ]已知,使用[hθx]计算某个输入特征变量[X],一般认为若结果大于0.5,则预测其属于分类1,否则为分类0。需要在Spark集群环境下进行逻辑回归分类的银行贷款数据存储在HDFS文件系统中。Sparklyr首先通过RStudio客户端远程连接到Spark集群,读取银行贷款数据文件;然后使用dplyr对数据进行处理,划分训练集及测试集,最后调用MLib库中的逻辑回归算法对训练集进行监督学习,得到能判断客户是否能按期归还贷款的逻辑回归模型。在集群环境下得到的模型仅包含回归系数,而缺少对模型评估的参数,对此本文补充了几个重要的性能指标来对模型进行评估,从而深入研究模型的可信性。2.1 逻辑回归模型的获取2.1.1 数据的读取 以csv格式存储抵押贷款数据文件按申请年份共10个,每个文件含106条记录,将文件存储在Hadoop集群的HDFS文件系统后,可使用spark_read_csv函数读取文件到Spark集群,格式为:spark_read_csv(sc, name, path, memory = TRUE/FALSE ...)其中sc为Spark集群的连接对象,name为读入到Spark集群中的表对象名,path为数据文件在HDFS文件系统中的路径,memory选项表示读入到Spark集群中的表对象是否缓存到集群节点的内存中。例如读入2000年抵押贷款的数据文件的语句为:spark_read_csv(sc, "mortYear0”,"hdfs://datanode:9000/mortDefault/mortYear0.csv")按上述语句格式,依次读入其它年份的数据后,使用dplyr的union操作,将所有数据组合成为一个表对象allMort,组合2000年至2004年这5个年份的语句描述如下:allMort <- tbl(sc, “mortYear0) %>%union(tbl(sc, ”mortYear2“)) %>%…%>% union(tbl(sc, ”mortYear4))用户在将大规模的数据读入到Spark集群时,可以根据数据的规模使用memory选项控制数据是否在Spark集群节点的内存中缓存,若整个Spark集群中的工作节点内存可以容纳所有数据,则选择memory 为TRUE(默认),将数据放入节点内存,从而加快数据挖掘分析的速度。若大规模数据超过了所有节点的内存容量,则选择memory 为FALSE,将数据存放在HDFS文件系统中,Sparklyr仅仅读入数据的定义进入节点内存,在使用MLib模型库对数据进行挖掘和分析时,根据节点内存的大小,从HDFS文件系统中读入需要的数据,从而实现大规模数据挖掘及分析的可扩展化。2.1.2 类别特征的处理 需要进行逻辑回归分类的原始抵押贷款数据格式如表1所示。表1 抵押贷款数据格式Tab. 1 Format of mortgage data[数据名称\&含义\&数据类型\&credit\&抵押贷款人信用评级\&int\&house\&抵押房屋的使用年限\&int\&Employ\&抵押贷款人的工作年限\&int\&Debt\&抵押贷款人信用卡债务数额\&int\&year\&抵押贷款人申请贷款的年份\&int\&default\&0或1,0表示按期归还贷款,1表示逾期归还\&int\&]default为逻辑回归模型需要预测的输出变量,其它为输入特征变量,建立逻辑回归模型需要输入特征变量均为数值型,如果输入特征变量表现为类别特征如颜色、性别、年份,则需要对类别特征进行编码,规则如下:[Ii=I(x=xi)=1 if x=xi0 if x≠xi] (4)通过上述的编码方式,抵押贷款数据中的year输入特征会被映射为[N]个二进制量,对于每条记录,只有一个指示特征的值为1,其余为0。在实际应用中,通过选择一个类别为参考类别,可用[N-1]个二进制量对有[N]个类别的输入变量进行编码,当观测数据的值与参考类别值相等时,对应的其它类别的[N-1]个二进制量全部取值为0。对于抵押贷款数据,其year输入变量从2000至2004共5个特征,逻辑回归模型系数仅包含c(year2001:year2004)这4个年份系数,若某条记录的year值为2000,则c(year2001:year2004)对应的二进制量取值为c(0,0,0,0),若year为2003,则对应的二进制量取值为c(0,0,1,0)。2.1.3 逻辑回归分类模型的获取 逻辑回归分类的任务就是以credit、house 、Employ、Debt、year为输入特征变量,根据训练集得到回归模型来预测输出变量default,从而回答抵押贷款人是否会拖欠贷款。在Spark 集群环境下的逻辑回归分类模型的算法描述如下:算法1: GetMortModel 输入: 抵押贷款文件集合mortFilePathlist输出:逻辑回归模型mortModelsc ←spark_connect(master= ’spark集群Master节点’,spark_home =’集群中spark的安装目录’,config=’集群环境配置对象’)[ ;]//连接spark集群环境for(i=0;mortFile inmortFilePathLst;i++ )//读取每个年份的抵押贷款文件mortYeari← spark_read_csv(sc,’mortYeari’,hdfs://datanode:9000/’+mortFile’);allMort← union(tbl(sc, mortYeari)); //组合文件end forallMort$year ←sdf_mutate(year = ftbucketizer(year ,c(startYear:endYear+1)))%>%mutate(year = as.character(as.integer(year)));//设置输入变量[year]为类别变量mlformula←formula(default~credit+ house+Employ+Debt+year);//划分训练集及测试集,调用[MLib]中的逻辑回归算法得到回归模型mortPartition←sdf_partition(allMort,training = 0.9,test = 0.1,seed = 1788);dfMortTrain ← mortPartition$training; dfMortTest ← mortPartition$test;mortModel←ml_logistic_regression(dfMortTrain,ml_formula) //得到回归模型return mortModel根据算法1 ,取2000年至2004年这5个年份的抵押贷款文件,得到的逻辑回归模型的系数如表2所示。2.2 逻辑回归模型的评估得到的逻辑回归模型是否可信任,分类效果如何,分类阈值如何确定,是否能满足实际应用,需要进行评估,而在集群环境下得到的模型仅包含回归系数,缺少对模型评估的参数。因此为了验证获得的模型的可信性, 从以下几个方面对模型进行评估。2.2.1 伪判定系数R2 设抵押贷款训练集中的记录数量为[m],记录[i, i∈1,m]的似然函数[Li]定义为:[Li=hθ(xi)yi[1-hθ(xi)]1-yi] (5)则记录[i]的对数似然函数为:[logLi=yilog[hθ(xi)]+(1-yi)log[1-hθ(xi)]] (6)其中[yi]为该记录的是否按期归还贷款的输出值,[hθxi]为根据回归模型[mortModel]计算得到的预测值。回归模型的偏差定义为[Dm]:[Dm=-i=1mlog (Li)2=] [-2×i=1myilog [hθ(xi)]+(1-yi)log[1-hθ(xi)]] (7)由于逻辑回归模型是基于极大似然估计得到的,因此将训练集的对数似然最大化也就等同于将模型偏差最小化。根据回归模型[mortModel]得到训练集预测值如算法2所示。算法2: Predict输入:回归模型mortModel,训练集dfMortTrain输出:回归模型预测值向量yPreds1. [θ←mortModel$coefficients;]//取模型系数向量2. [for(i=0;i≤ nrow(dfMortTrain);i++)]3. [x’i←dfMortTraini,c1:4;]//取每个记录的前4个输入特征变量4. year←根据类别特征取值规则, 生成输入变量 year的二进制向量;5. [xi←cbind(x’i,year);] //列绑定[x’i]及[year]生成输入特征变量6. [ yPreds[i]←hθxi;]//根据预测函数计算预测值7. [end for]8. return [yPreds;]得到回归模型[mortModel]的偏差Dm的过程如算法3所示。算法3: [GetModelDeviance]输入:回归模型mortModel,训练集dfMortTrain输出:回归模型偏差[Dm]1.[yLabels←dfMortTrain[’default’];] //得到训练集中是实际输出值2. yPreds←Predictmort(Model, dfMortTrain); //调用算法2得到预测值3.[Dm←0; i←1;]4.[for(i=0;i≤ nrow(dfMortTrain;i++ )] //计算模型偏差5.[Dm+=-2*(yLabelsi*logyPredsi+][1-yLabelsi*log1-yPredsi);] 6.[end for]7. return [Dm;]//返回模型偏差空模型是不使用任何输入特征变量训练出来的模型,空偏差Dn表示空模型的预测值与实际输出值之间的模型偏差,空模型的预测值为一个常数概率,一般取训练集中所有输出值为1的记录所占的百分比。根据算法3计算[Dn],只需要将 yPreds的计算更改为yPreds←mean(dfMortTain[[’default’])。伪判定系数R2 定义为:[R2=1-DmDn] (8)伪判定系数R2 用于衡量回归模型相比于默认模型在解释数据时的效果,其值应该小于1,若值大于1,则得到的回归模型就不能被信任,数据集就不适合采用逻辑回归算法进行分类预测。根据算法3得到的[Dm]为48 153,[Dn]为92 750,[R2]为0.481,说明回归模型mortModel是可信任的。从统计学的角度来检查模型偏差和空偏差之间的差值是否显著,可以认为差值近似服从卡方分布,即:[X~X2p-1, (其中X=Dn-Dm)] (9)其中[p]为模型中参数的个数,对于mortModel模型,[X]值为44 597,自由度p-1为8,使用R语言计算pchisq(X,p-1,lower.tail=F)得到的[p]值为0,说明mortModel的预测效果明显优于空模型。2.2.2 分类评价指标 确定用户是否能按期归还贷款属于二元分类问题,因此可以以混淆矩阵为基础来评价分类评价指标。将得到的逻辑回归模型用于预测银行抵押贷款的训练集,以0.5为分类阈值(预测结果小于0.5,则default为0,否则default为1),将预测值与训练集中的实际default进行比较,得到的混淆矩阵为:[c=4 482 1574565 535505][c[1,1]]表示正确预测default为0的记录个数;[c[2,2]]表示正确预测default为1的记录个数;[c[1,2]]表示将值为0的default错误地预测为1的记录个数;[c[2,1]]表示将值为1的default错误[地]预测为0的记录个数。根据混淆矩阵可以得到准确率(accuracy, A),其值用A表示;真阳性率(true positive rate, TPR)即正确预测default为1的比例,值用T表示;假阳性率(false positive rate, FPR)即将default错误预测为1的比例,值用F表示;3个分类评价指标,其计算过程及值如下: [A=c1,1+c[2,2]sum(c)= 0.998 6] (10)[T=c2,2sumc2,=0.084 ] (11) [F=c1,2sum(c[1,])=0.000 1] (12)将ROCR包加载到运行在集群环境中的RStudio Server中后,使用包中的prediction及performance函数可以得到[F]与[T]的不同取值的变化曲线,如图1 (a)所示,该曲线称为接受者操作特征曲线(receiver operating characteristic, ROC),根据银行抵押贷款训练集得到的逻辑回归模型曲线下的区域面积(area under the curve, AUC)值为0.987 9。通过上述评价指标,可以知道模型有高的准确率,低的假阳性率及几乎接近于1的AUC值,说明使用模型能准确的对用户是否能按时归还贷款进行分类。与结论相矛盾的问题是,以阈值H等于0.5进行预测分类判断,真阳性率只有不到9%,说明模型不能对用户未按时归还贷款(default值为1)进行判断,产生矛盾的原因在于训练集中的大多数记录的default的值为0,从而使得在进行模型训练中,产生了倾向性。模型在不同阈值H下的[FPR]与[TPR]的对应关系如图1(b)所示,从图中可以发现当H取0时,[T]与F均为1,表示所有记录都被预测为default等于1;随着H的增加,[F]迅速降低到几乎接近0,[T]则缓慢降低;当H取1时,[T]与[F]都为0,表示所有记录都被预测default为0。因此, 若在实际应用中要求模型能较准确的预测用户能否按时归还贷款, 则可将H从0.5的位置向左移取较小值, 在提高[T]的同时, 保持较低的[F]。2.2.3 测试集性能 将通过训练集得到逻辑回归分类模型对测试集中的记录进行预测,可以模拟检验模型在实际应用中的表现,对测试集进行预测并计算评价指标如算法4所示。算法4: PrdictMortTest输入:回归模型mortModel,测试集dfMortTest输出:测试集评价指标A, T, F和模型曲线下区域面积S1. yPredsTest←Predictmort(Model, dfMortTest );//调用算法2得到测试集预测值2. yPredsTest←as.numeric(yPredsTest>0.05) //取分类阈值为0.053. cTest←table(dfMortTest$default,yPredsTest ); //得到测试集混淆矩阵4. Get(A,T,F); //根据式(10)~(12)计算A,T,F;5. predObjTest ← prediction(yPredsTest, dfMortTest$default);6. S←performance(predObjTest , measure=’auc’)7. [@y.values1; ] //计算测试集里的S8. return A, T, F, S;根据算法4返回的测试集评价指标如下:A值为0.995,TPR值为0.504,FPR值为0.004,S值为0.987。当将分类阈值设置为0.05用于与测试集时,TRP得到显著的提高,而其它分类指标却没有降低太多,所以认为0.05为该模型合适的分类阈值。各项评价指标与回归模型基本吻合,因此说明可以将该模型进行实际应用。3 实 验实验用服务器为DELL PowerEdge R720, 其配置为两个物理CPU(Intel Xeon E5-2620 V2 2.10 GHz,每个CPU含6个内核,共12个内核),32 GB内存,8 TB硬盘,4个物理网卡。服务器安装VMWare esxi6.0.0操作系统,虚拟化整个服务器环境。客户端使用VMWare VSphere client 6.0.0将服务器划分为4个虚拟机,每个虚拟机的配置为3内核CPU,8 GB内存,2 TB硬盘,1个物理网卡。每个虚拟机安装ubuntu-16.04.1-server-amd64操作系统,Hadoop 2.7.3分布式计算平台,组成含1个主节点,4个数据节点(主节点也是数据节点)的集群,集群中安装的Spark版本为2.1.1,同样配置为4个工作节点。实验将R中串行的glm算法与MLib中并行的ml_logistic_regression算法在逻辑回归模型的获取时间上进行比较,具体过程为首先将抵押贷款的10个文件合并为allMort数据集,依次划分训练集为allMort的10%至90%;然后对每一个划分的训练集分别使用glm算法及ml_logistic_regression算法进行模型的获取,每个算法运行3次,取平均时间为算法获取模型的时间。两种算法获取模型时间t与训练数据量d的关系比较如图2所示。由实验结果分析:当数据量在6×106条以下时,串行算法glm获取模型的速度比并行算法ml_logistic_regression快,但当数据量超过6×106条时,并行算法获取模型的速度就优于串行算法。除此以外,这一实验结果也说明了集群环境适合在大规模数据下进行机器学习,构建模型,这也是符合了在大数据时代的实际应用特征。4 结 论在增加了几个模型评估系数从而验证了模型可信性的基础上,通过实验证明了当数据量大到一定阈值后,在集群环境下并行的算法获得逻辑回归分类模型的速度要快于对应的串行算法。但在构建逻辑回归模型前,需要对各个输入特征变量进行相关性分析,规避变量间的多重线性,对输入特征进行正则化分析,去掉对预测结果影响不显著的特征。获取逻辑回归模型后,还需要对获得的每个回归系数计算其标准误差,求出[Z]统计量,对系数与预测结果的显著性水平进行评价,以确定是否在回归模型中使用该系数。以上几点,都是在Spark集群环境下对大规模数据进行逻辑回归模型构建的后续研究中需要完善的地方。