1. 程式人生 > >評分卡模型開發--主標尺設計及模型驗證

評分卡模型開發--主標尺設計及模型驗證

轉自:https://blog.csdn.net/lll1528238733/article/details/76601930

上一步中開發的信用風險評分卡模型,得到的是不同風險等級客戶對應的分數,我們還需要將分數與違約概率和評級符號聯絡起來,以便差異化管理證券公司各面臨信用風險敞口的客戶,這就需要對證券公司各面臨信用風險敞口業務中的個人客戶開發一個一致的主標尺。最容易理解、最容易操作的方式就是根據違約概率從低到高分為不同的區間,這就相當於把違約概率這把尺子標上刻度,用這把尺子可以把證券公司需承擔信用風險敞口的不同業務中的個人客戶劃分到不同的信用等級,這樣各項業務中個人客戶的信用等級分佈差異、信用風險分佈高低,就可以一目瞭然地展現出來了。這種違約概率和信用等級之間的對映關係就稱為主尺標。

由邏輯迴歸方程原理的分析可知,客戶的違約概率p=Odds/(1+Odds),由式 Score=A-Blog(Odds)中得分與違約概率和Odds之間的對應關係,我們可計算出客戶得分對應的違約概率。

由信用風險標準評分卡可知,該評分卡的最高分是89分,最低分是-41分。因此,我們可以計算出該評分卡所有得分範圍對應的違約概率:

根據表3.22的結果可見,我們可簡單地將每10分對應一個信用等級,並用每相鄰得分對應的違約概率(這種方法計算得出的違約概率只能用作風險排序,而不是客戶的真實違約概率)的算術平均值作為該信用風險等級對應的平均違約概率,得到最終的主尺標及其內部信用等級對照表3.23:

在主標尺和內部信用等級確定後,接下來我們需要進行模型的區分能力、預測準確度和穩定性等模型的驗證工作了。回顧模型開發的過程,在模型開發時我們採用隨機抽樣的方法將資料分為樣本集和測試集,並用樣本集開發模型,用測試集做模型驗證。因此,做模型驗證時,我們應當首先用開發好的模型對測試集中的每一個樣本評級一遍,並根據評級結果來計算模型的區分能力和預測準確度。 用已開發好的模型對測試集中所有樣本重新評級一遍的程式碼如下:

tmp1<-test_kfolddata[,-21]
credit_risk1<-ifelse(test_kfolddata[,"credit_risk"]=="good",0,1)
data_tmp<-as.matrix(cbind(tmp1,credit_risk1))
##降維purpose(對測試集中的樣本做同樣的降維處理)##
for(i in 1:nrow(data_tmp))
{
  #合併car(new)、car(used)
  if(as.character(data_tmp[i,"purpose"])=="car (new)")  
  {
    data_tmp[i,"purpose"]<-as.character("car(new/used)")
  }
  if(as.character(data_tmp[i,"purpose"])=="car (used)")
  {
    data_tmp[i,"purpose"]<-as.character("car(new/used)")
  }
  #合併radio/television、furniture/equipment
  if(as.character(data_tmp[i,"purpose"])=="radio/television") 
  {
    data_tmp[i,"purpose"]<-as.character("radio/television/furniture/equipment")
  }
  if(as.character(data_tmp[i,"purpose"])=="furniture/equipment")
  {
    data_tmp[i,"purpose"]<-as.character("radio/television/furniture/equipment")
  }
  #合併others、repairs、business
  if(as.character(data_tmp[i,"purpose"])=="others")
  {
    data_tmp[i,"purpose"]<-as.character("others/repairs/business")
  }
  if(as.character(data_tmp[i,"purpose"])=="repairs")
  {
    data_tmp[i,"purpose"]<-as.character("others/repairs/business")
  }
  if(as.character(data_tmp[i,"purpose"])=="business")
  {
    data_tmp[i,"purpose"]<-as.character("others/repairs/business")
  }
  #合併retraining、education
  if(as.character(data_tmp[i,"purpose"])=="retraining")
  {
    data_tmp[i,"purpose"]<-as.character("retraining/education")
  }
  if(as.character(data_tmp[i,"purpose"])=="education")
  {
    data_tmp[i,"purpose"]<-as.character("retraining/education")
  }
}
##purpose變數降維結束##
###用R程式碼實現打分卡模型###
data1<-as.data.frame(data_tmp)
tot<-nrow(data1)
score<-list()
for(i in 1:tot)
{
  lst<-as.matrix(data1[i,])
  #duration
  score_duration<-NA
  if(lst[,"duration"]<=8)
  {
    score_duration<-14
  }else
  if(lst[,"duration"]>8&lst[,"duration"]<=33)
  {
    score_duration<-1
  }else
  if(lst[,"duration"]>33)
  {
    score_duration<--7
  }
  #amount
  score_amount<-NA
  if(lst[,"amount"]<=3913)
  {
    score_amount<-3
  }else
    if(lst[,"amount"]>3913&lst[,"amount"]<=9283)
    {
      score_amount<--5
    }else
      if(lst[,"amount"]>9283)
      {
        score_amount<--14
      }
  #age
  score_age<-NA
  if(lst[,"age"]<=34)
  {
    score_age<--2
  }else
    if(lst[,"age"]>34)
    {
      score_age<-3
    }
  #installment_rate
  score_installment_rate<-NA
  if(lst[,"installment_rate"]==1)
  {
    score_installment_rate<-2
  }else
    if(lst[,"installment_rate"]==2)
    {
      score_installment_rate<-5
    }else
      if(lst[,"installment_rate"]==3)
      {
        score_installment_rate<--1
      }else
        if(lst[,"installment_rate"]==4)
        {
          score_installment_rate<--6
        }
  #status
  score_status<-NA
    if(lst[,"status"]=="... < 100 DM")
    {
      score_status<--10
    }else
      if(lst[,"status"]=="0 <= ... < 200 DM")
      {
        score_status<--5
      }else
      if(lst[,"status"]=="... >= 200 DM / salary for at least 1 year")
      {
        score_status<-5
      }else
        if(lst[,"status"]=="no checking account")
        {
          score_status<-14
        }
  #credit_history
  score_credit_history<-NA
  if(lst[,"credit_history"]=="critical account/other credits existing")
  {
    score_credit_history<-8
  }else
    if(lst[,"credit_history"]=="existing credits paid back duly till now")
    {
      score_credit_history<--1
    }else
      if(lst[,"credit_history"]=="all credits at this bank paid back duly")
      {
        score_credit_history<--10
      }else
        if(lst[,"credit_history"]=="delay in paying off in the past")
        {
          score_credit_history<-0
        }else
          if(lst[,"credit_history"]=="no credits taken/all credits paid back duly")
          {
            score_credit_history<--16
          }
  #savings
  score_savings<-NA
  if(lst[,"savings"]=="... < 100 DM")
  {
    score_savings<--3
  }else
    if(lst[,"savings"]=="... >= 1000 DM")
    {
      score_savings<-13
    }else
      if(lst[,"savings"]=="500 <= ... < 1000 DM")
      {
        score_savings<-9
      }else
        if(lst[,"savings"]=="unknown/no savings account")
        {
          score_savings<-9
        }else
          if(lst[,"savings"]=="100 <= ... < 500 DM")
          {
            score_savings<--2
          }
  #property
  score_property<-NA
  if(lst[,"property"]=="unknown/no property")
  {
    score_property<--4
  }else
    if(lst[,"property"]=="real estate")
    {
      score_property<-3
    }else
      if(lst[,"property"]=="building society savings agreement/life insurance")
      {
        score_property<--1
      }else
        if(lst[,"property"]=="car or other")
        {
          score_property<-1
        }
  #purpose
  score_purpose<-NA
  if(lst[,"purpose"]=="domestic appliances")
  {
    score_purpose<-6
  }else
    if(lst[,"purpose"]=="radio/television/furniture/equipment")
    {
      score_purpose<--3
    }else
      if(lst[,"purpose"]=="car(new/used)")
      {
        score_purpose<--1
      }else
        if(lst[,"purpose"]=="retraining/education")
        {
          score_purpose<--5
        }else
          if(lst[,"purpose"]=="others/repairs/business")
          {
            score_purpose<--1
          }
  score[i]<-sum(20,score_duration,score_amount,score_age,score_installment_rate,
                score_status,score_credit_history,score_savings,
                score_property,score_purpose)
  rm(lst)
}
###用R程式碼實現打分卡模型結束###
#合併處理測試集樣本得分,並輸出到指定的CSV檔案中#
score_M<-as.matrix(score,ncol=1)
score_data<-cbind(data1,score_M)
score_risk<-score_data[,c("credit_risk1","score_M")]
write.csv(as.matrix(score_risk),"C:/Users/ZL/Desktop/creditcard_model/2.csv")

從理論上說,信用評級無法給出主體是否違約的判斷,只能給出主體違約的概率,而評級符號對應的就是主體發生違約的平均違約概率。但對評級結果的實際應用中,實在存在評級結果是否“準確”的質疑。那麼,通常情況下如果某主體被評級為投資級(BBB及以上),但發生了違約,則被認為“不準確”或者“誤判”。如果某主體被評級為投機級(BB及以下),且發生了違約,則被認為“預測準確”。如果被評級為投機級的主體沒發生違約事件(並不是每個被評級為投機級的主體都會發生違約),則可以用概率去解釋,那就是“大概率事件並不一定發生,小概率事件也並不一定不發生”。 我們採用ROC作為模型區分能力的驗證指標,採用AR(accuracy ratio,準確率)作為模型預測準確性的驗證指標,並且兩者存在AR=2×ROC-1的關係式。驗證模型的穩定性需要多年的歷史資料,由於資料原因此處略去。

由內部等級與主尺標的對應關係可知,投資級和投機級的分界點為20分,即大於20分的主體發生發生了違約,我們認為是“誤判”,小於20分的主體為發生違約,我們也認為是“誤判”。則經統計圖 中的資料可知,誤判的主體總數為50個,則AR=1-50/200=0.75,此時ROC=(1+AR)/2=0.875。此時模型的預測準確度和區分能力均達到了較好地要求,可以進行部署使用。

上述模型的驗證方法採用的是將測試樣本集中的所有樣本在生成的評分卡中全部評級一遍的方法,當然也可以採用直接將WOE變數的邏輯迴歸方程作為評級模型的方法。此時,也需要將測試樣本集中的所有入模變數計算其WOE,並代入上述邏輯迴歸方程。