本文档描述申请评分卡开发中贷款成熟期分析阶段的流程,本阶段的结果用来确定表现窗口长度


1. 数据导入与数据处理

# 载入所需包 
library(data.table)
library(pipeR)
library(ggplot2)
library(lubridate)
# 读入数据
data <- fread("mob.HP.txt", drop = 1)

数据概览:

head(data) 
     月末日期             合同号 放款金额 期限             部门
1: 2010-09-30 HT0010003010000176     4999   12 产品与渠道拓展部
2: 2010-10-31 HT0010003010000176     4999   12 产品与渠道拓展部
3: 2010-11-30 HT0010003010000176     4999   12 产品与渠道拓展部
4: 2010-12-31 HT0010003010000176     4999   12 产品与渠道拓展部
5: 2011-01-31 HT0010003010000176     4999   12 产品与渠道拓展部
6: 2011-02-28 HT0010003010000176     4999   12 产品与渠道拓展部
             渠道     用途     还款方式 支付方式   放款日期 月末余额
1: 大中电器马甸店 贬值耐用 等额本息还款 受托支付 2010-04-16  2998.52
2: 大中电器马甸店 贬值耐用 等额本息还款 受托支付 2010-04-16  2584.50
3: 大中电器马甸店 贬值耐用 等额本息还款 受托支付 2010-04-16  2166.94
4: 大中电器马甸店 贬值耐用 等额本息还款 受托支付 2010-04-16  1743.93
5: 大中电器马甸店 贬值耐用 等额本息还款 受托支付 2010-04-16  1316.98
6: 大中电器马甸店 贬值耐用 等额本息还款 受托支付 2010-04-16   885.26
   核销日期 月末逾期天数
1:                     0
2:                     0
3:                     0
4:                     0
5:                     0
6:                     0
str(data)
Classes 'data.table' and 'data.frame':  2301792 obs. of  13 variables:
 $ 月末日期    : chr  "2010-09-30" "2010-10-31" "2010-11-30" "2010-12-31" ...
 $ 合同号      : chr  "HT0010003010000176" "HT0010003010000176" "HT0010003010000176" "HT0010003010000176" ...
 $ 放款金额    : num  4999 4999 4999 4999 4999 ...
 $ 期限        : int  12 12 12 12 12 12 12 12 12 12 ...
 $ 部门        : chr  "产品与渠道拓展部" "产品与渠道拓展部" "产品与渠道拓展部" "产品与渠道拓展部" ...
 $ 渠道        : chr  "大中电器马甸店" "大中电器马甸店" "大中电器马甸店" "大中电器马甸店" ...
 $ 用途        : chr  "贬值耐用" "贬值耐用" "贬值耐用" "贬值耐用" ...
 $ 还款方式    : chr  "等额本息还款" "等额本息还款" "等额本息还款" "等额本息还款" ...
 $ 支付方式    : chr  "受托支付" "受托支付" "受托支付" "受托支付" ...
 $ 放款日期    : chr  "2010-04-16" "2010-04-16" "2010-04-16" "2010-04-16" ...
 $ 月末余额    : num  2999 2584 2167 1744 1317 ...
 $ 核销日期    : chr  "" "" "" "" ...
 $ 月末逾期天数: int  0 0 0 0 0 0 0 0 0 0 ...
 - attr(*, ".internal.selfref")=<externalptr> 
summary(data)
   月末日期            合同号             放款金额           期限      
 Length:2301792     Length:2301792     Min.   :   600   Min.   : 3.00  
 Class :character   Class :character   1st Qu.:  4999   1st Qu.:12.00  
 Mode  :character   Mode  :character   Median : 12000   Median :18.00  
                                       Mean   : 13359   Mean   :18.48  
                                       3rd Qu.: 16800   3rd Qu.:24.00  
                                       Max.   :500000   Max.   :60.00  
     部门               渠道               用途          
 Length:2301792     Length:2301792     Length:2301792    
 Class :character   Class :character   Class :character  
 Mode  :character   Mode  :character   Mode  :character  
                                                         
                                                         
                                                         
   还款方式           支付方式           放款日期            月末余额     
 Length:2301792     Length:2301792     Length:2301792     Min.   :     0  
 Class :character   Class :character   Class :character   1st Qu.:  1982  
 Mode  :character   Mode  :character   Mode  :character   Median :  5160  
                                                          Mean   :  8821  
                                                          3rd Qu.: 14553  
                                                          Max.   :500000  
   核销日期          月末逾期天数     
 Length:2301792     Min.   :   0.000  
 Class :character   1st Qu.:   0.000  
 Mode  :character   Median :   0.000  
                    Mean   :   9.941  
                    3rd Qu.:   0.000  
                    Max.   :1664.000  
data[, ":="(放日期 = ymd(放日期),
            月末日期 = ymd(月末日期))]

data[, ":="(放年 = year(放日期),
            放月 = month(放日期),
            表现年 = year(月末日期),
            表现月 = month(月末日期)
            )]

data[, ":="(mob = (表现年 - 放款年) * 12 + 表现月 - 放款月)]

2. 自定义函数

PlotVintage <- function(bad, settledyear, settledmonth){
# 绘制vintage图(ever).
# 参数:
  # bad:          坏的定义, 格式为"90+","180+"
  # settledyear:  放款年
  # settledmonth: 放款月
  threshold <- sub(x = bad, pattern = "\\+", replacement = "") %>>%  # 坏的阈值
               as.integer
    BadFlag <- function(x){  # 生成是否为坏的标志
      y <- vector(length = length(x))
      y[] <- 0
      index <- which(x > threshold)[1]  # 找到第一个大于bad阈值的位置
      if (!is.na(index)) y[index:length(x)] <- 1  # 若index不为NA(即x中有大于阈值的值), 此位置之后都赋值为1
      return(y)
    }
  data[放年 %in% settledyear & 放款月 %in% settledmonth,
       # 按(放款年, 放款月, 合同号)分组, 在每个分组内按mob升序排列, 判断在在每个mob中是否为坏 
       .SD[order(mob), list(mob, 月末期天数, bad.flag = BadFlag(月末期天数))],  
       by = list(放年, 放月, 合同号)] %>>%
  (~ badaccount <- .[, list(badcount = sum(bad.flag)), by = 合同号][badcount > 0, 合同号]) %>>%  # 找出所有坏账户
  (.[合同号 %in% badaccount, list(放年月 = paste(放年, 放月, sep = "-"),
                                  bad.rate = sum(bad.flag) / .N), 
                                  by = list(放年, 放月, mob)]) %>>% 
  with(ggplot(., aes(x = factor(mob), y = bad.rate, group =年月, color =年月)) + 
       geom_line() +
       geom_point(size = 4, shape = 21, fill = "white") +
       labs(title = paste("vintage", bad, "ever" ,sep = " "), x = "mob", y = "坏账率") + 
       ylim(0, 1)  # 固定y轴范围
       )
}

3. Vintage Analyse

PlotVintage("90+", settledyear = 2013, settledmonth = 1:9)