博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
R语言绘制KS曲线
阅读量:7049 次
发布时间:2019-06-28

本文共 3707 字,大约阅读时间需要 12 分钟。

更多风控建模、大数据分析等内容请关注公众号《bigdatafengkong

将代码封装在函数PlotKS_N里,Pred_Var是预测结果,可以是评分或概率形式;labels_Var是好坏标签,取值为1或0,1代表坏客户,0代表好客户;descending用于控制数据按违约概率降序排列,如果Pred_Var是评分,则descending=0,如果Pred_Var是概率形式,则descending=1;N表示在将数据按风险降序排列后,等分N份后计算KS值。

PlotKS_N函数返回的结果为一列表,列表中的元素依次为KS最大值、KS取最大值的人数百分位置、KS曲线对象、KS数据框。

代码如下:

1 ####################   PlotKS_N ################################ 2 PlotKS_N<-function(Pred_Var, labels_Var, descending, N){ 3   # Pred_Var is prop: descending=1 4   # Pred_Var is score: descending=0 5   library(dplyr) 6    7   df<- data.frame(Pred=Pred_Var, labels=labels_Var) 8    9   if (descending==1){10     df1<-arrange(df, desc(Pred), labels)11   }else if (descending==0){12     df1<-arrange(df, Pred, labels)13   }14   15   df1$good1<-ifelse(df1$labels==0,1,0)16   df1$bad1<-ifelse(df1$labels==1,1,0)17   df1$cum_good1<-cumsum(df1$good1)18   df1$cum_bad1<-cumsum(df1$bad1)19   df1$rate_good1<-df1$cum_good1/sum(df1$good1)20   df1$rate_bad1<-df1$cum_bad1/sum(df1$bad1)21   22   if (descending==1){23     df2<-arrange(df, desc(Pred), desc(labels))24   }else if (descending==0){25     df2<-arrange(df, Pred, desc(labels))26   }27   28   df2$good2<-ifelse(df2$labels==0,1,0)29   df2$bad2<-ifelse(df2$labels==1,1,0)30   df2$cum_good2<-cumsum(df2$good2)31   df2$cum_bad2<-cumsum(df2$bad2)32   df2$rate_good2<-df2$cum_good2/sum(df2$good2)33   df2$rate_bad2<-df2$cum_bad2/sum(df2$bad2)34   35   rate_good<-(df1$rate_good1+df2$rate_good2)/236   rate_bad<-(df1$rate_bad1+df2$rate_bad2)/237   df_ks<-data.frame(rate_good,rate_bad)38   39   df_ks$KS<-df_ks$rate_bad-df_ks$rate_good40   41   L<- nrow(df_ks)42   if (N>L) N<- L43   df_ks$tile<- 1:L44   qus<- quantile(1:L, probs = seq(0,1, 1/N))[-1]45   qus<- ceiling(qus)46   df_ks<- df_ks[df_ks$tile%in%qus,]47   df_ks$tile<- df_ks$tile/L48   df_0<-data.frame(rate_good=0,rate_bad=0,KS=0,tile=0)49   df_ks<-rbind(df_0, df_ks)50   51   M_KS<-max(df_ks$KS)52   Pop<-df_ks$tile[which(df_ks$KS==M_KS)]53   M_good<-df_ks$rate_good[which(df_ks$KS==M_KS)]54   M_bad<-df_ks$rate_bad[which(df_ks$KS==M_KS)]55   56   library(ggplot2)57   PlotKS<-ggplot(df_ks)+58     geom_line(aes(tile,rate_bad),colour="red2",size=1.2)+59     geom_line(aes(tile,rate_good),colour="blue3",size=1.2)+60     geom_line(aes(tile,KS),colour="forestgreen",size=1.2)+61     62     geom_vline(xintercept=Pop,linetype=2,colour="gray",size=0.6)+63     geom_hline(yintercept=M_KS,linetype=2,colour="forestgreen",size=0.6)+64     geom_hline(yintercept=M_good,linetype=2,colour="blue3",size=0.6)+65     geom_hline(yintercept=M_bad,linetype=2,colour="red2",size=0.6)+66     67     annotate("text", x = 0.5, y = 1.05, label=paste("KS=", round(M_KS, 4), "at Pop=", round(Pop, 4)), size=4, alpha=0.8)+ 68     69     scale_x_continuous(breaks=seq(0,1,.2))+70     scale_y_continuous(breaks=seq(0,1,.2))+71     72     xlab("of Total Population")+73     ylab("of Total Bad/Good")+74     75     ggtitle(label="KS - Chart")+76     77     theme_bw()+78     79     theme(80       plot.title=element_text(colour="gray24",size=12,face="bold"),81       plot.background = element_rect(fill = "gray90"),82       axis.title=element_text(size=10),83       axis.text=element_text(colour="gray35")84     )85   86   result<-list(M_KS=M_KS,Pop=Pop,PlotKS=PlotKS,df_ks=df_ks)87   return(result)88 }

接下来以实际数据为例查看该函数的运行结果。

pred_train是建模得到的预测结果,这里是概率形式:

> pred_train

   [1] 0.40418112 0.35814193 0.45220572 0.53482002 0.12923573 ...

labels_train是好坏标签:

> labels_train

   [1] 0 0 0 0 0 ...

函数运行的结果存放在train_ks里:

train_ks<-PlotKS_N(pred_train, labels_train, 1, 100)

我们来查看train_ks中的每一元素:

1、KS最大值

> train_ks$M_KS

[1] 0.4492765

2、KS取最大值的人数百分位置

> train_ks$Pop

[1] 0.3803191

3、KS曲线对象

转载于:https://www.cnblogs.com/bigdatafengkong/p/9076251.html

你可能感兴趣的文章
九宫格
查看>>
手把手教你写一个 VSCode 插件
查看>>
cookie和session
查看>>
使用 multipart/x-mixed-replace 实现 http 实时视频流
查看>>
史上最牛内推小组(持续更新)
查看>>
现实中的路由规则,可能比你想象中复杂的多
查看>>
nginx配置gzip中的坑
查看>>
Javascript中的函数声明与函数表达式
查看>>
Python学习笔记 - queue
查看>>
茶器漫谈 高逼格 or 真内涵?
查看>>
HTML5学习之Web Storage基础知识
查看>>
tab切换
查看>>
垃圾回收及内存调试工具的介绍
查看>>
你的接口,真的能承受高并发吗?
查看>>
自定义View实用小技巧
查看>>
iOS CALayer anchorPoint 的应用场景
查看>>
如何變聰明?訓練自己變成結構化思維型的人!- TechMoon 科技月球
查看>>
超好用的VueJs调试工具——vue-devtools
查看>>
到底怎么才算“懂”python的twisted框架?
查看>>
Flutter 基础布局Widgets之Expanded详解
查看>>