1、寫在模組化前
盡管,現在有很多優秀的模型已經在金融風控領域中得到廣泛應用,且效果較好,但是,經典的評分模型依然是風控的基礎,是最常見的金融風控手段,通常來對信貸使用者進行信用風險評估,據此決定是否給予授信以及授信的額度、利率。
評分卡一般分類:
- 貸前:申請評分卡(Application scorecard),又稱為A卡
- 貸中:行為評分卡(Behavior scorecard),又稱為B卡
- 貸後:催收評分卡(Collection scorecard),又稱為C卡 評
分卡一般模組化流程:信用評分模型開發流程
那我們先看一下,一張簡單的評分卡長什麼樣子吧。
那麼,一個申請使用者的總得分就等于各個變量的得分之和,即總分=baseScore + score(age) +score(phoneAge) +score(incomeOfYear) +score(sex) +score(marrySate) +score(education),這樣來看,評分卡也不是那麼複雜的模型。但是,建立一張貼合業務、區分能力好的評分模型并不是一件簡單的事情,下面我們進行評分卡的模組化步驟,揭開評分模組化的神秘面紗!
2、評分卡模型建立
參照之前寫過的模組化步驟(),現在選取資料集進行評分卡模型建立的全過程。這裡的資料集的好壞定義以及觀察期、表現期是參照了()文章做了滾動率分析以及賬齡分析來判定和選取的。
#### 定義路徑與環境 ####
rm(list = ls()) #清除所有變量
setwd("C:\\Users\\Desktop")
#### 資料集準備 ####
library(openxlsx)
datatable<-read.xlsx("data.xlsx",1,colNames = TRUE)
str(datatable)
dim(datatable)
從讀入的資料集結構來看,該資料共有160940條記錄,41個變量,其中cedit字段為好壞辨別字段(0-好使用者,1-壞使用者),其餘x1~x40均為使用者屬性(字段含義這裡不做詳細說明)。
2.1 特征預處理
拿到資料集,了解了大緻的資料集結構以及字段含義之後,下面開始資料預處理階段,主要是對資料特征進行缺失值、異常點、單一值等做相應處理,清洗資料。
缺失率統計與删除
#### 計算變量缺失值個數以及确實比例 ####
findNaFunc<-function(dataFrame,file){
# param:dataFrame 資料框
# param:file 把缺失情況寫出檔案中
count<-0
# 定義資料框,使用者存儲資料
naViewData<-data.frame(varName="title",count=0,rate="0%")
# 若有缺失值,則顯示确實變量以及确實比例
for(i in 1:ncol(dataFrame)){
# 缺失值個數統計
sumT<-sum(is.na(dataFrame[,i]) | dataFrame[,i]=='')
# 缺失比例
rate<-round(sumT/length(dataFrame[,i]),4)
rate<-paste(rate*100,"%",sep ="")
if(sumT!=0){
count=count+1 #要放在print或者return之前
temporaryData<-data.frame(varName=names(dataFrame[i]),count=sumT,rate=rate)
naViewData<-rbind(naViewData,temporaryData)
# print(paste(paste(names(dataFrame[i]),sumT,sep=" "),rate,sep=" "))
}
}
# 若無缺失,則顯示沒有确實變量
if(count==0){
print("no variable contain NA!")
}else{
library(openxlsx)
write.xlsx(naViewData,file = file ,colNames=TRUE,rowNames=TRUE)
print(naViewData)
}
}
# 調用函數
findNaFunc(datatable,'dataNaRate.xlsx')
從缺失比例統計來看,絕大部分特征缺失率是在30%以下的,這裡我們采取去除缺失率在30%以上的特征的政策。
#### 删除缺失值比例大于a%以上的變量 ####
naRateDeleteFunc<-function(dataFrame,rate){
# param:dataFrame 資料集
# param:rate 缺失比例
col_num=ncol(dataFrame)
row_num=nrow(dataFrame)
vec<-vector(mode ='integer',length=col_num)
# 1) 形成一個裝滿索引(缺失值比例較大列)的向量
for(i in 1:col_num){
# 每列缺失值個數
sumT<-sum(is.na(dataFrame[,i]) | dataFrame[,i]=='')
# 每列缺失比例
NA_rate<-sumT/row_num
if(NA_rate>rate){
vec[i]<-i
}
}
# 2) 把索引向量中不為0的元素篩選出來
index<-vec>0
vec_no_zero<-vec[index]
# 3) 從資料框中取出缺失值比例較大的列
# 但是這裡要做一個判斷,如果vec_no_zero為空(就是說資料框沒有一個空值),
# 則-NA會把所有的變量都去掉
if(length(vec_no_zero)==0){
dataSet<-dataFrame
} else{
dataSet<-dataFrame[,-vec_no_zero]
}
return(dataSet) # return傳回的對象要放在()中
}
# 調用函數,傳回資料集
dataNew30Rate<-naRateDeleteFunc(datatable,0.3)
缺失比例高的變量進行删除處理,傳回dataNew30Rate資料集。
異常點檢測
在後面我們将采用均值填充的方式處理剩餘缺失變量,異常點對變量均值影響較大,是以此處先采用蓋帽法處理異常值。
#### 蓋帽法處理異常值 ####
# 四分位數極差(IQR)定義為Q3-Q1。比Q1小1.5倍的IQR或者比Q3大1.5倍的IQR的任何對象都視為離群點,
# 因為Q1-1.5*IQR和Q3+1.5*IQR之間的區域包含了99.3%的對象。
outlierDetectionFunc<-function(dataframe){
ncols<-dim(dataframe)[2]
for(i in 1:ncols){
if(is.numeric(dataframe[,i])){
q25<-quantile(dataframe[,i],0.25,na.rm = T)
q75<-quantile(dataframe[,i],0.75,na.rm = T)
IQR15<-1.5*IQR(dataframe[,i], na.rm = T)
dataframe[,i][which(dataframe[,i] < (q25-IQR15))] <- quantile(dataframe[,i],0.01, na.rm = T)
dataframe[,i][which(dataframe[,i] > (q75+IQR15))] <- quantile(dataframe[,i],0.99, na.rm = T)
}
}
return(dataframe)
}
dataWithNoOuterlier<-outlierDetectionFunc(dataNew30Rate)
未完。。。