数据简介
此次分享的数据案例是我的同学参加的2020年招商银行fintech项目时碰到的案例,我就正好拿这个案例来进行了一下评分卡的建模练习,首先此次数据主要包括三个数据集,分别是行为数据、标签数据、交易数据。
训练集和测试集都已经分好,最终的目的如下所示。
数据预处理
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import matplotlib as mpl
import scipy
mpl.rcParams['figure.figsize'] = (8, 5)
train_beh = pd.read_csv('data/训练数据集_beh.csv')
train_trade = pd.read_csv('data/训练数据集_trd.csv')
train_tag = pd.read_csv('data/训练数据集_tag.csv')
test_beh = pd.read_csv('data/评分数据集_beh_a.csv')
test_trade = pd.read_csv('data/评分数据集_trd_a.csv')
test_tag = pd.read_csv('data/评分数据集_tag_a.csv')
首先观察beh数据集,该数据集中包含字段如下:
我们这里构造两个特征,每个用户的app浏览时长,以及浏览次数最多的页面。
#统计客户最爱浏览网页和网页浏览次数
def most_like_page(df):
dic = {}
dic['app_use_times'] = df['page_no'].count()
dic['most_like_page']= df['page_no'].value_counts().index[0]
s = pd.Series(dic, index = ['app_use_times','most_like_page'])
return s
train_beh_1 = train_beh.groupby('id').apply(most_like_page)
trade数据集字段主要有以下
我们统计每个用户总的交易金额,平均交易金额,最多的交易方向、最多的收支一级分类、最多的收支二级分类。
def trade_amt(df):
dic = {}
dic['trade_amt'] = df['cny_trx_amt'].sum()
dic['most_Dat_Flg3_Cd'] = df['Dat_Flg3_Cd'].value_counts().index[0]
dic['most_Trx_Cod1_Cd'] = df['Trx_Cod1_Cd'].value_counts().index[0]
dic['most_Trx_Cod2_Cd'] = df['Trx_Cod2_Cd'].value_counts().index[0]
dic['avg_trade_amt'] = df['cny_trx_amt'].sum() / len(df)
s = pd.Series(dic, index = ['trade_amt','most_Dat_Flg3_Cd','most_Trx_Cod1_Cd','most_Trx_Cod2_Cd','avg_trade_amt'])
return s
train_trade_1 = train_trade.groupby('id').apply(trade_amt)
最终我们可以得到合并后的train_data:
all_tag = train_tag.merge(train_beh_1, how = 'inner', on = 'id').merge(train_trade_1, how = 'inner', on = 'id')
观察整个数据,发现deg_cd这一列数据缺失较多,于是我们选择舍弃这一列,并将edu_deg_cd和atdd_type这两列数据缺失不多的特征将nan也作为一个特征
#删除deg_cd这一列特征
all_tag.drop('deg_cd', axis = 1, inplace = True)
all_tag.loc[all_tag['edu_deg_cd'].isnull(),'edu_deg_cd'] = 'nan'
all_tag.loc[all_tag['atdd_type'].isnull(), 'atdd_type'] = 'nan'
做好上述处理后,我们将对剩下来的特征分连续型和离散型进行处理。
#连续型变量
continues_variables = ['age','job_year','frs_agn_dt_cnt','l12mon_buy_fin_mng_whl_tms','l12_mon_fnd_buy_whl_tms',
'l12_mon_insu_buy_whl_tms','l12_mon_gld_buy_whl_tms','ovd_30d_loan_tot_cnt','his_lng_ovd_day',
'cur_debit_cnt','cur_credit_cnt','cur_debit_min_opn_dt_cnt','cur_credit_min_opn_dt_cnt','app_use_times'
,'trade_amt','avg_trade_amt' ]
#分类型变量
classified_variation = ['cur_debit_crd_lvl','hld_crd_card_grd_cd','crd_card_act_ind','l1y_crd_card_csm_amt_dlm_cd',
'atdd_type','perm_crd_lmt_cd','gdr_cd','mrg_situ_cd','ic_ind','fr_or_sh_ind','dnl_mbl_bnk_ind',
'dnl_bind_cmb_lif_ind','hav_car_grp_ind','hav_hou_grp_ind','l6mon_agn_ind','vld_rsk_ases_ind',
'fin_rsk_ases_grd_cd','confirm_rsk_ases_lvl_typ_cd','cust_inv_rsk_endu_lvl_cd','l6mon_daim_aum_cd',
'tot_ast_lvl_cd','pot_ast_lvl_cd','bk1_cur_year_mon_avg_agn_amt_cd','loan_act_ind','most_like_page',
'most_Dat_Flg3_Cd','most_Trx_Cod1_Cd','most_Trx_Cod2_Cd','pl_crd_lmt_cd','acdm_deg_cd', 'edu_deg_cd']
all_tag[classified_variation] = all_tag[classified_variation].astype(str)
变量筛选
我们对缺失值进行处理后,接下来就是进行变量的筛选,这里我们选用的woe值编码后通过IV值的筛选方法。
我们使用WoE值代替原始的分组值,WoE的计算公式如下:
W o E i = l n ( # G i / # G T # B i / # B T ) WoE_i = ln\left(\displaystyle \frac {^{\# G_i} / _{\# G_T}}{^{\# B_i} / _{\# B_T}}\right) WoEi=ln(#Bi/#BT<