(信贷风控九)行为评分卡模型python实现(详细代码+注释+讲解)

本文详细讲解了行为评分卡模型的Python实现,包括数据预处理、特征衍生、筛选、变量分箱、参数估计、特征选择、模型性能测试和概率转分数等步骤。代码中使用GBDT和LASSO进行变量挑选,适用于贷中风险管理。
摘要由CSDN通过智能技术生成

(九)行为评分卡模型python实现(详细代码+注释+讲解)

 

浅谈行为评分卡

我们知道行为评分卡只要用在信贷的贷中环节,贷中指的是贷款发放之后到期之前的时间段,其实行为评分卡和申请评分卡在实现上没有太大的差别,主要是数据集不一样。因为前一篇博客已经介绍过行为评分卡,这里就不过多去讨论了,主要以代码为主

 

行为评分卡建模步骤

  • 数据预处理
  • 特征衍生
  • 特征处理与筛选
  • 变量分箱
  • 模型的参数估计
  • 特征挑选
  • 模型性能测试
  • 概率转换为分数

 

代码如下:

和申请评分卡代码有一些不同的地方在于,由于行为逻辑回归结果后有存在符号为正的系数和不显著的变量,变量挑选使用了GBDT评估重要性和LASSO。由于数据集不一样,代码中可能后面有一些变量挑选的地方对不上,不过整体代码是没有问题的,思路和流程在代码中均可以体现,数据集可以在我的博客资源下载。

 

import pandas as pd
import numpy as np
import pickle
from statsmodels.stats.outliers_influence import variance_inflation_factor
import statsmodels.api as sm
from sklearn import ensemble
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.metrics import roc_auc_score


'''
时间:20190227
作者:小象学院
'''

#################################
#由于数据已经经过一定的清洗了,非一手数据,所以我们忽略了一些步骤,进行变量衍生
#   1, 读取数据,衍生初始变量   #
'''
Loan_Amount:总额度
OS:未还金额
Payment:还款金额
Spend:使用金额
Delq:逾期情况
'''
#################################
folderOfData = 'H:'
trainData = pd.read_csv(folderOfData+'/训练集.csv',header = 0,engine ='python')
testData = pd.read_csv(folderOfData+'/测试集.csv',header = 0,engine ='python')


#衍生逾期类型的特征的函数
def DelqFeatures(event,window,type):
    '''
    :parms event 数据框
    :parms windows 时间窗口
    :parms type 响应事件类型
    '''
    current = 12
    start = 12 - window + 1
    #delq1、delq2、delq3为了获取window相对应的dataframe范围
    delq1 = [event[a] for a in ['Delq1_' + str(t) for t in range(current, start - 1, -1)]]
    delq2 = [event[a] for a in ['Delq2_' + str(t) for t in range(current, start - 1, -1)]]
    delq3 = [event[a] for a in ['Delq3_' + str(t) for t in range(current, start - 1, -1)]]
    if type == 'max delq':
        if max(delq3) == 1:
            return 3
        elif max(delq2) == 1:
            return 2
        elif max(delq1) == 1:
            return 1
        else:
            return 0
    if type in ['M0 times','M1 times', 'M2 times']:
        if type.find('M0')>-1:
            return sum(delq1)
        elif type.find('M1')>-1:
            return sum(delq2)
        else:
            return sum(delq3)

allFeatures = []

'''
逾期类型的特征在行为评分卡(预测违约行为)中,一般是非常显著的变量。
通过设定时间窗口,可以衍生以下类型的逾期变量:
'''

# 考虑过去1个月,3个月,6个月,12个月
for t in [1,3,6,12]:
    # 1,过去t时间窗口内的最大逾期状态
    allFeatures.append('maxDelqL'+str(t)+"M")
    trainData['maxDelqL'+str(t)+"M"] = trainData.apply(lambda x: DelqFeatures(x,t,'max delq'),axis=1)

    # 2,过去t时间窗口内的,M0,M1,M2的次数
    allFeatures.append('M0FreqL' + str(t) + "M")
    trainData['M0FreqL' + str(t) + "M"] = trainData.apply(lambda x: DelqFeatures(x,t,'M0 times'),axis=1)

    allFeatures.append('M1FreqL' + str(t) + "M")
    trainData['M1FreqL' + str(t) + "M"] = trainData.apply(lambda x: DelqFeatures(x, t, 'M1 times'), axis=1)

    allFeatures.append('M2FreqL' + str(t) + "M")
    trainData['M2FreqL' + str(t) + "M"] = trainData.apply(lambda x: DelqFeatures(x, t, 'M2 times'), axis=1)



#衍生额度使用率类型特征的函数
def UrateFeatures(event, window, type):
    '''
    :parms event 数据框
    :parms windows 时间窗口
    :parms type 响应事件类型
    '''
    current = 12
    start = 12 - window + 1
    #获取在数据框内有效区域
    monthlySpend = [event[a] for a in ['Spend_' + str(t) for t in range(current, start - 1, -1)]]
    #获取授信总额度
    limit = event['Loan_Amount']
    #月使用率
    monthlyUrate = [x / limit for x in monthlySpend]
    if type == 'mean utilization rate':
        return np.mean(monthlyUrate)
    if type == 'max utilization rate':
        return max(monthlyUrate)
    #月额度使用率增加的月份
    if type == 'increase utilization rate':
        #val[0:-1]表示第一个元素到倒数第二个元素的切片
        currentUrate = monthlyUrate[0:-1]
        #val[1:]表示第二个元素到最后一个元素的切片
        previousUrate = monthlyUrate[1:]
        compareUrate = [int(x[0]>x[1]) for x in zip(currentUrate,previousUrate)]
        return sum(compareUrate)


'''
额度使用率类型特征在行为评分卡模型中,通常是与违约高度相关的
'''
# 考虑过去1个月,3个月,6个月,12个月
for t in [1,3,6,12]:
    # 1,过去t时间窗口内的最大月额度使用率
    allFeatures.append('maxUrateL' + str(t) + "M")
    trainData['maxUrateL' + str(t) + "M"] = trainData.apply(lambda x: UrateFeatures(x,t,'max utilization rate'),axis = 1)

    # 2,过去t时间窗口内的平均月额度使用率
    allFeatures.append('avgUrateL' + str(t) + "M")
    trainData['avgUrateL' + str(t) + "M"] = trainData.apply(lambda x: UrateFeatures(x, t, 'mean utilization rate'),axis=1)

    # 3,过去t时间窗口内,月额度使用率增加的月份。该变量要求t>1
    if t > 1:
        allFeatures.append('increaseUrateL' + str(t) + "M")
        trainData['increaseUrateL' + str(t) + "M"] = trainData.apply(lambda x: UrateFeatures(x, t, 'increase utilization rate'),axis=1)


#衍生还款类型特征的函数
def PaymentFeatures(event, window, type):
    current = 12
    start = 12 - window + 1
    #月还款金额
    currentPayment = [event[a] for a in ['Payment_' + str(t) for t in range(current, start - 1, -1)]]
    #月使用金额,错位一下
    previousOS = [event[a] for a in ['OS_' + str(t) for t in range(current-1, start - 2, -1)]]
    monthlyPayRatio = []
    for Pay_OS in zip(currentPayment,previousOS):
        #前一个月使用了才会产生还款
        if Pay_OS[1]>0:
            payRatio = Pay_OS[0]*1.0 / Pay_OS[1]
            monthlyPayRatio.append(payRatio)
        #前一个月没使用,就按照100%还款
        else:
            monthlyPayRatio.append(1)
    if type == 'min payment ratio':
        return min(monthlyPayRatio)
    if type == 'max payment ratio':
        return max(monthlyPayRatio)
    if type == 'mean payment ratio':
        total_payment = sum(currentPayment)
        total_OS = sum(previousOS)
        if total_OS > 0:
            return total_payment / total_OS
        else:
            return 1

'''
还款类型特征也是行为评分卡模型中常用的特征
'''
# 考虑过去1个月,3个月,6个月,12个月
for t in [1,3,6,12]:
    # 1,过去t时间窗口内的最大月还款率
    allFeatures.append('maxPayL' + str(t) + "M")
    trainData['maxPayL' + str(t) + "M"] = trainData.apply(lambda x: PaymentFeatures(x, t, 'max payment ratio'),axis=1)
    # 2,过去t时间窗口内的最小月还款率
    allFeatures.append('minPayL' + str(t) + "M")
    trainData['minPayL' + str(t) + "M"] = trainData.apply(lambda x: PaymentFeatures(x, t, 'min payment ratio'),axis=1)
    # 3,过去t时间窗口内的平均月还款率
    allFeatures.append('avgPayL' + str(t) + "M")
    trainData['avgPayL' + str(t) + "M"] = trainData.apply(lambda x: PaymentFeatures(x, t, 'mean payment ratio'),axis=1)



###函数########
#计算变量分箱之后各分箱的坏样本率
def BinBadRate(df, col, target, grantRateIndicator=0):
    '''
    :param df: 需要计算好坏比率的数据集
    :param col: 需要计算好坏比率的特征
    :param target: 好坏标签
    :param grantRateIndicator: 1返回总体的坏样本率,0不返回
    :return: 每箱的坏样本率,以及总体的坏样本率(当grantRateIndicator==1时&#x
  • 18
    点赞
  • 202
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 37
    评论
评论 37
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路易三十六

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值