题目嘛,大概就是就是一个信用评分预测,评判指标为AUC。(官网已经查不到了,大家找找别的帖子看看吧)
一、数据预处理部分
(一)缺失值
- 处理的较为粗糙,tag表中\N和~都当做缺失值处理了。(可改进)
- 三个和教育相关的列,其中两个缺失值较多,删除处理。
- 字符编码转数字:采用LabelEncoder()编码。注意,要把train和test合并再进行处理,否则会出现编码不同的情况。
- 数字缺失值填充:分析字段含义,大部分根据众数填充;小部分0~1标识类缺失直接填2,构造一个“缺失类”;有一些直接按照经验填充。例如:贷款标识我认为如果在招行贷款,招行忘了标记,这不太现实,所以就填0。(借了其他银行的贷款就另说了hhh)
def pre_data(data):
data.replace("\\N", np.NaN, inplace=True)
data.replace("~", np.NaN, inplace=True)
data.drop(['edu_deg_cd', 'deg_cd'], axis=1, inplace=True) # 删除两个教育特征(缺失值多+属性重复)
lab = LabelEncoder()
str_col = ['gdr_cd', 'mrg_situ_cd', 'acdm_deg_cd', 'atdd_type']
data[str_col] = data[str_col].fillna('None') # 填充缺失值为None,否则报错
# 字符编码转化为数字
data["gdr_cd"] = lab.fit_transform(data.gdr_cd)
data["mrg_situ_cd"] = lab.fit_transform(data.mrg_situ_cd)
data["acdm_deg_cd"] = lab.fit_transform(data.acdm_deg_cd)
data["atdd_type"] = lab.fit_transform(data.atdd_type.astype(str))
# 数字缺失值填充
col_012 = ['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'] # 0,1二分类特征
data[col_012] = data[col_012].fillna('2')
col_11 = ['frs_agn_dt_cnt', 'fin_rsk_ases_grd_cd', 'confirm_rsk_ases_lvl_typ_cd',
'tot_ast_lvl_cd', 'pot_ast_lvl_cd', 'hld_crd_card_grd_cd'] # 用众数-1填充缺失值
data[col_11] = data[col_11].fillna('-1')
data['cust_inv_rsk_endu_lvl_cd'] = data['cust_inv_rsk_endu_lvl_cd'].fillna('1') # 用众数1填充
data = data.fillna('0')
return data
(二)数据合并拆分
针对上面第3,先合并后进入pre_data函数,再拆分。
data=pd.concat([train_tag,test_tag],axis=0,ignore_index=True,sort=False)
data['flag']=data['flag'].fillna(-1)
data=pre_data(data)
train_tag=data[data.flag != -1].copy()
test_tag=data[data.flag == -1].copy()
test_tag.drop(['flag'],axis=1,inplace=True)
test_tag=test_tag.reset_index(drop=True)
二、特征工程
(一)tag表特征——强特增益
强特:信用卡天数、借记卡天数、信用卡等级等一系列特征。对这些特征进行相乘,目的使用户之间的差距增大,强特增益。
(B榜构造的,助我从0.777–>0.779)
def tag(data):
#信用卡:持卡天数*等级
data['credit_level1']=data['cur_credit_min_opn_dt_cnt']*pd.to_numeric(data['l1y_crd_card_csm_amt_dlm_cd'])
data['credit_level2']=data['cur_credit_min_opn_dt_cnt']*pd.to_numeric(data['perm_crd_lmt_cd'])
data['credit_level3']=data['cur_credit_min_opn_dt_cnt']*pd.to_numeric(data['hld_crd_card_grd_cd'])
data['level_level']=pd.to_numeric(data['l1y_crd_card_csm_amt_dlm_cd'])*pd.to_numeric(data['perm_crd_lmt_cd']) #等级*等级
data['credit_amount']=data['cur_credit_min_opn_dt_cnt']*data['cur_credit_cnt'] #持卡天数*持卡数量
#信用卡:持卡数量*等级
data['amount_level1']=data['cur_credit_cnt']*pd.to_numeric(data['perm_crd_lmt_cd'])
data['amount_level2']=data['cur_credit_cnt']*pd.to_numeric(data['l1y_crd_card_csm_amt_dlm_cd'])
data['amount_level3']=data['cur_credit_cnt']*pd.to_numeric(data['hld_crd_card_grd_cd'])
return data
(二)trd表特征
trd表是交易流水表,能够挖掘很多统计特征,可以说是本次最重要的一个表。
- 收入、支出、交易额统计特征
此处注意,一定要先合并ID最全的表,防止左连接后数值丢失。
def trd(data):
data['trx_tm'] = pd.to_datetime(data['trx_tm'], format='%Y/%m/%d') # 转变为8位时间字符
data['trx_tm'] = data['trx_tm'].dt.strftime('%Y%m%d')
#收支统计特征:总和、最大、最小、均值、标准差、数目
temp1 = data[data['cny_trx_amt'] > 0].groupby(by=['id'], as_index=False)['cny_trx_amt'].agg(
{
'income_sum': 'sum', 'income_max': 'max', 'income_min': 'min', 'income_mean': 'mean', 'income_count': 'count',
'income_std': 'std'})
temp2 = data[data['cny_trx_amt'] < 0].groupby(by=['id'], as_index=False)['cny_trx_amt'].agg( # 支出为负,min、max互换
{
'expend_sum': 'sum', 'expend_max': 'min', 'expend_min': 'max', 'expend_mean': 'mean', 'expend_count': 'count',
'ecpend_std': 'std'})
temp3 = data.groupby(by=['id'], as_index=False)['cny_trx_amt'].agg({
'trd_mean': 'mean', 'trd_std': 'std'})
#收支交易天数
temp4 = data.groupby(by=['id'], as_index=False)['trx_tm'].agg({
'trd_day_count': 'nunique'}) # 交易天数
temp5 = data[data['cny_trx_amt'] > 0].groupby(by=['id'], as_index=False)['trx_tm'].agg(
{
'income_day_count': 'nunique'}) # 收入天数
temp6 = data[data['cny_trx_amt'] < 0].groupby(by=['id'], as_index=False)['trx_tm'].agg(
{
'expend_day_count': 'nunique'}) # 支出天数
data_t = pd.merge(temp3, temp1, on=['id'], how='left')
data_t = pd.merge(data_t, temp2, on=['id'], how='left')
data_t = pd.merge(data_t, temp4, on=['id'], how='left')
data_t = pd.merge(data_t, temp5, on=['id'], how='left')
data_t = pd.merge(data_t, temp6, on=['id'], how='left')
# 求总和
data_t['trd_sum'] = data_t['income_sum'] + data_t['expend_sum'] # 余额
data_t['trd_total'] = data_t['income_sum'