金融风控AI—评分卡模型算法(2)

上一篇地址

2、探索分析

探索 数据 分析(Exploratory Data Analysis)是为了更好的了解数据之间的有没有啥关联和关联大小。而在多变量分析中根据相关性大小,可以把相关性强的参数剔除。常用的探索 数据 分析方法有:直方图、散点图、折线图、热度图和箱线图等。

a、单变量分析

就是分析参数变量和结果的函数关系,可以做图形象的观看变化趋势,我们看看年龄和违约的关系

age_cut=pd.cut(data['age'],10)

age_cut_group=data['SeriousDlqin2yrs'].groupby(age_cut).count()

age_cut_groupbad=data["SeriousDlqin2yrs"].groupby(age_cut).sum()

age_cut_groupbadrate=age_cut_groupbad/age_cut_group

ax1=age_cut_groupbadrate.plot(figsize=(15,15))

ax1.set_xticklabels(age_cut_groupbadrate.index)

ax1.set_ylabel("bad ratio")

ax1.set_title("age-badratio")

plt.show()

违约客户率随着年龄增大而逐步下降,但是最后有个翘尾

现在看看月收入对违约的影响,将月收入划分为以下几个级别:1000,3000,5000,8000,12000,16000,20000,100000,500000.由下面两图可知,刚开始随着收入增加违约率降低,而在2w-10w,最低,而收入再增加时,违约客户率又随收入增高发生递增。

再来看看逾期30-59天次数与违约客户率之间的关系,可以这个情况比较复杂。

同理可以其他参数逐个看看

b、多变量分析

多变量分析主要看变量之间的相关系数大小,最大是1,相关强的变量可以考虑去重,python中可采用corr()函数计算各变量间的相关性。一般相关系数大于0.6可以进行变量剔除去重。

    corr = data.corr()#计算各变量的相关性系数

    xticks = list(corr.index)#x轴标签

    yticks = list(corr.index)#y轴标签

    fig = plt.figure(figsize=(15,10))

    ax1 = fig.add_subplot(1, 1, 1)

    sns.heatmap(corr, annot=True, cmap="rainbow",ax=ax1,linewidths=.5, annot_kws={'size': 9, 'weight': 'bold', 'color': 'blue'})

    ax1.set_xticklabels(xticks, rotation=35, fontsize=15)

    ax1.set_yticklabels(yticks, rotation=0, fontsize=15)

    plt.show()

图如下

这个图看起来各个变量之间相关性不大。上篇文章提到违约次数异常如果置之不理会对这个图有很大影响,那我把异常数据放进去后再来看看 变量关系。

可见有3个变量有强相关,这就是异常值对模型的干扰,而到底该剔除还是保留,最好还是都测试一下效果。

c、数据切分

因为只有一份数据,为了训练和验证评估模型效果,我们把数据集进行切分,分成训练集和测试集。

from sklearn.model_selection import train_test_split

if __name__ == '__main__':

    #载入数据

    data = pd.read_csv('MissingData.csv')

    Y = data['SeriousDlqin2yrs']

    X = data.iloc[:, 1:]

    #测试集占比20%

    X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=0)

    #print(Y_train)

    train = pd.concat([Y_train, X_train], axis=1)

    test = pd.concat([Y_test, X_test], axis=1)

    #clasTest = test.groupby('SeriousDlqin2yrs')['SeriousDlqin2yrs'].count()

    train.to_csv('TrainData.csv',index=False)

    test.to_csv('TestData.csv',index=False)

3、特征选择

特征选择就是分析出哪些变量对违约率影响大,选出来作为模型的变量。而评估特征的方法有很多,常用的就是iv值法评估。为计算变量的iv值,需要对变量分箱、woe值计算最后是iv值计算。

a、变量分箱

变量分箱(binning)就是对变量离散化(discretization)的一种称呼。特征离散化后,模型会更稳定,降低了模型过拟合的风险。同时分箱之后可以降低数据量,使模型泛化能力增强。一般常用的分箱有:等距分箱、等深分箱、最优分箱等。等距是指区间是一致的,比如年龄以十年作为一个分箱;等深是先确定分箱数量,然后令每个分箱中数据数量大致相等;最优分箱(Optimal Binning)又叫有监督分箱(supervised discretizaion),如使用递归划分(Recursive Partitioning)将连续变量分箱。这些分箱方式都可以逐个试试效果。

在pd里cut是等距分箱,qcut是等深分箱。简单点的话直接用等距等深处理。最好么各种分箱算法都试试。

分箱代码:

    cut1=pd.qcut(train["RevolvingUtilizationOfUnsecuredLines"],5,labels=False)

    cut2=pd.qcut(train["age"],8,labels=False)

    bins3=[-1,0,1,3,5,13]

    cut3=pd.cut(train["NumberOfTime30-59DaysPastDueNotWorse"],bins3,labels=False)

    cut4=pd.qcut(train["DebtRatio"],5,labels=False)

    cut5=pd.qcut(train["MonthlyIncome"],5,labels=False)

    cut6=pd.qcut(train["NumberOfOpenCreditLinesAndLoans"],5,labels=False)

    bins7=[-1, 0, 1, 3,5, 20]

    cut7=pd.cut(train["NumberOfTimes90DaysLate"],bins7,labels=False)

    bins8=[-1, 0,1,2, 3, 33]

    cut8=pd.cut(train["NumberRealEstateLoansOrLines"],bins8,labels=False)

    bins9=[-1, 0, 1, 3, 12]

    cut9=pd.cut(train["NumberOfTime60-89DaysPastDueNotWorse"],bins9,labels=False)

    bins10=[-1, 0, 1, 2, 3, 5, 21]

    cut10=pd.cut(train["NumberOfDependents"],bins10,labels=False)

b,woe值计算

WOE(Weight of Evidence)翻译成证据权重。可以评估变量值的重要性。woe的概念细节这里不展开讲了。

要计算变量的WOE值,首先把这个变量进行分箱。WOE的计算公式如下:

woe=ln(分箱里坏好比/总量数据里坏好比)

表示的是分箱中违约客户和好客户的比值,与所有样本中这个比值的差异。再取对数。WOE越大,说明这种差异越大,说明这个分箱的价值就越大,WOE越小,差异越小,说明这个分箱的价值越小。

py代码

#计算woe值

def get_woe_data(data,cut):

    rate=data["SeriousDlqin2yrs"].sum()/(data["SeriousDlqin2yrs"].count()-data["SeriousDlqin2yrs"].sum())

    grouped=data["SeriousDlqin2yrs"].groupby(cut,as_index = True).value_counts()

    woe=np.log(grouped.unstack().iloc[:,1]/grouped.unstack().iloc[:,0]/rate)

    return woe



c,iv值计算

IV全称是Information Value,翻译成信息价值。IV用来确定变量的预测能力。iv可以看作是woe的加权求和。

#计算iv值

def get_IV_data(data,cut,cut_woe):

    grouped=data["SeriousDlqin2yrs"].groupby(cut,as_index = True).value_counts()

    cut_IV=((grouped.unstack().iloc[:,1]/data["SeriousDlqin2yrs"].sum()-grouped.unstack().iloc[:,0]/(data["SeriousDlqin2yrs"].count()-data["SeriousDlqin2yrs"].sum()))*cut_woe).sum()   

    return cut_IV

各变量的iv

    #计算各分组的IV值

    cut1_IV=get_IV_data(train,cut1,cut1_woe)

    cut2_IV=get_IV_data(train,cut2,cut2_woe)

    cut3_IV=get_IV_data(train,cut3,cut3_woe)

    cut4_IV=get_IV_data(train,cut4,cut4_woe)

    cut5_IV=get_IV_data(train,cut5,cut5_woe)

    cut6_IV=get_IV_data(train,cut6,cut6_woe)

    cut7_IV=get_IV_data(train,cut7,cut7_woe)

    cut8_IV=get_IV_data(train,cut8,cut8_woe)

    cut9_IV=get_IV_data(train,cut9,cut9_woe)

    cut10_IV=get_IV_data(train,cut10,cut10_woe)

结果

IV

可用额度比值      0.855609

年龄          0.190955

逾期30-59天笔数  0.609889

负债率        0.058016

月收入        0.073055

信贷数量        0.050973

逾期90天笔数    0.782562

固定资产贷款量    0.048099

逾期60-89天笔数  0.475483

家属数量        0.035488

看图

通过IV值判断变量的标准通常是:

< 0.02: unpredictive

0.02 to 0.1: weak

0.1 to 0.3: medium

0.3 to 0.5: strong

> 0.5: suspicious

一般选取IV大于0.02的特征变量进行后续训练,从以上可以看出所有变量均满足。但我们可以尝试更高点的标准来测试一下,比如选用0.1以上的。

本文完

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353