用户贷款逾期预测

前言:去年参加了数据城堡的算法竞赛,一直没时间记录下来,趁今天来梳理下这个竞赛项目的方方面面。赛题为用户贷款风险预测,目标是利用用户基本信息、用户银行流水、用户信用卡账单以及用户浏览行为4个表的数据预测用户贷款后逾期的概率,其中带标签数据55596条,无标签数据13899条,个人最好成绩是排名前8%。

解决方案概述

此次大赛目标是从用户行为数据分析借款用户的信用状况,来判断其是否逾期。针对需要解决的问题和数据特征,主要从三个方面进行处理:数据预处理,特征工程,模型训练。

首先,由于数据中存在缺失值,因此需要对缺失值数据进行预处理。其次,采用基于学习模型的特征排序方法做了特征选择。然后,针对类别不平衡问题,主要是对少量样本过采样,针对过程中出现的过拟合问题,采用了pca降维以及对特征进行选择的方法。

本文框架如下:

  1. 好坏样本定义说明
  2. 样本概述
  3. 缺失值处理
  4. 构建新特征
  5. 特征选择
  6. 模型
  7. 最终结果

1.好坏样本定义

样本有55596条带标签数据,其中标签为0,1,1表示用户逾期。
正负样本分布如下:

print('训练集中各类别数据的个数:', trains.groupby('标签').size())
训练集中各类数据的个数: 标签
0.0    48413
1.0     7183

可以看出正负样本并不平衡,正样本大概是负样本的7倍,因此存在一个样本不平衡问题。

2.样本概述

提供的近7w条数据中,主要为四个表,分别是用户信息表,银行流水记录,用户浏览行为,信用卡账单。其中字段名如下:
用户信息表:

用户id 性别 职业 教育程度 婚姻状态 户口类型

银行流水记录表:

用户id 时间戳 交易类型 交易金额 工资收入标记

用户浏览行为表:

用户id 时间戳 浏览行为数据 浏览子行为编号

信用卡账单表:

用户id 时间 银行标识 上期账单金额 上期还款金额
调整金额 循环利息 可用余额 预借现金额度 还款状态
信用卡额度 本期账单余额 本期账单最低还款额 消费笔数 本期账单金额

共计27个字段。字段数据都经过举办方脱敏处理,业务信息缺失。

3.缺失值处理

赛题数据中大部分样本都有缺失值,常用的缺失值处理方法是缺失值填充(用同类别数据的特征均值,中值等)

feature=dataset[:]
dataset=dataset.fillna(-1)
d=feature['用户银行流水记录缺失统计']=(dataset==-1).sum(axis=1)

用均值填充缺失值

feature.fillna(feature.mean(),inplace=True)

4.构建新特征

赛题数据含有类别特征,很多算法(如逻辑回归,SVM)只能处理数值型特征,这种情况下需要对类别特征进行编码,这里采用了 One-Hot 编码,得到了 01 特征,解决了分类器不能处理类别特征的问题。

dataset=pd.get_dummies(dataset,
                       columns=dataset[['用户性别','用户职业','用户教育程度',
                                                '用户婚姻状态','用户户口类型']]).drop(['标签'],axis=1)

根据放款时间来划分时间窗口,构建每个表的放款前特征和放款后特征。

# ----------------------------------------银行流水特征------------------------------------------#
print('银行流水记录')
feature = pd.read_csv('../feature/训练放款时间表')
d = pd.read_csv('../feature/银行流水记录表')
d=pd.merge(d,feature,how='left', on = '用户标识')
# ----------------------------------------放款前特征统计------------------------------------------#
print('放款前特征统计')
t = d[(d['流水时间'] <= d['放款时间'])] 
gb1 = t[(t['交易类型'] == 0)].groupby(['用户标识'], as_index=False)  # 收入统计
gb2 = t[(t['交易类型'] == 1)].groupby(['用户标识'], as_index=False)  # 支出统计
gb3 = t[(t['工资收入标记'] == 1)].groupby(['用户标识'], as_index=False)  # 工资收入统计
x1 = gb1['交易金额'].agg({'放款前用户收入笔数': 'count', '放款前用户收入总计': 'sum'})
x2 = gb2['交易金额'].agg({'放款前用户支出笔数': 'count', '放款前用户支出总计': 'sum'})
x3 = gb3['交易金额'].agg({'放款前用户工资收入笔数': 'count', '放款前用户工资收入总计': 'sum'})

feature = pd.merge(feature, x1, how='left', on='用户标识')
feature = pd.merge(feature, x2, how='left', on='用户标识')
feature = pd.merge(feature, x3, how='left', on='用户标识')

feature['放款前用户收入支出笔数差值'] = feature['放款前用户收入笔数'] - feature['放款前用户支出笔数']
feature['放款前用户收入支出总计差值'] = feature['放款前用户收入总计'] - feature['放款前用户支出总计']
feature['放款前用户非工资收入笔数'] = feature['放款前用户收入笔数'] - feature['放款前用户工资收入笔数']
feature['放款前用户非工资收入总计'] = feature['放款前用户收入总计'] - feature['放款前用户工资收入总计']

构建新特征后特征维度达到164维。

5.特征选择

构建特征后,特征维度达到164维,多维特征一方面可能会导致维数灾难,另一方面很容易导致过拟合,因此需要做降维处理,常见的降维方法有 PCA。除了采用降维算法之外,也可以用特征选择来降低特征维度。特征选择的方法很多:卡方检验、皮尔森相关系数、正则化方法(L1, L2)、基于模型的特征选择方法。

# 特征选择,基于卡方检验
# trains=SelectKBest(chi2,k=20).fit_transform(trains,target)

# 基于惩罚项的特征选择法
# trains=SelectFromModel(LogisticRegression(penalty='l1',C=0.1)).fit_transform(trains,target)

# 基于树模型的特征选择

# trains=SelectFromModel(GradientBoostingClassifier()).fit_transform(trains,target)

# 降维,基于pca

pca=PCA(n_components=50)

trains=pca.fit_transform(trains)
test=pca.fit_transform(test)

6.模型

这里主要尝试了LR和XGB,在效果上XGB更好,可能是因为XGB在训练的同时会进行特征选择。

parameters= [{
                  'max_depth':[3,5,7], ##5)
                  'learning_rate':[0.1,0.5, 1.0],#0.1
                  'subsample':[0.75,0.8,0.85,0.9],#0.8
                  'min_child_weight':[1,3,5]#5

                  }]
#parameters= [{'n_estimators':[100,200,500,1000]
#                  }]
clf = GridSearchCV(xgb.XGBClassifier(n_estimators=100,gamma=0,scale_pos_weight=1),
                   param_grid=parameters,scoring='roc_auc',n_jobs=4,iid=False,cv=5)
print('开始训练')
clf.fit(x_train, y_train)

参数解释:
learning_rate:学习速率
min_child_weight :这个参数用来控制过拟合,如果数值太大可能会导致欠拟合。
max_depth:设置树的最大深度,控制过拟合,如果树的深度太大会导致过拟合
subsample:对原数据集进行随机采样来构建单个树。这个参数代表了在构建树时候对原数据集采样的百分比。eg:如果设为0.8表示随机抽取样本中80%的个体来构建树
scale_pos_weight:在样本类别十分不平衡时,参数设定为一个正值,可以使算法更快收敛
模型结果:

AUC:0.87

特征重要性输出:

image.png

可见最重要特征有用户性别、用户职业、用户婚姻状态、用户教育程度、用户户口类型、放款前浏览行为数据、放款前浏览行为数据最小值、放款前浏览子行为编号_8
可见除了基本信息外,用户的浏览行为是强有力的特征。

7.最终结果

不同方法及模型线下表现效果:

预处理 AUC(LR) AUC(XGB)
标准化处理 0.8726 0.8722
特征选择(卡方检验) 0.8742 0.8723
基于惩罚项的特征选择 0.8741 0.8723
基于树模型 0.8741 0.8711

构建新特征后:

预处理 AUC(LR) AUC(XGB)
构建放款前后新特征 0.8973
优化用户特征 0.9172

最终结果以逾期概率的形式上传到平台:

userid,probability
55597,0.3506719172000885
55598,0.3657565116882324
55599,0.3827580213546753
55600,0.36820918321609497
55601,0.34563612937927246
55602,0.36067867279052734
55603,0.36357182264328003
55604,0.3907186985015869
55605,0.34469443559646606
55606,0.3836720585823059
55607,0.3370608389377594
55608,0.38630616664886475
55609,0.3718336224555969

提交结果
image.png

第一名成绩为0.4746,与之相比我还有很大差距,但经过这次比赛我学到了很多,主要是关于解决问题的思路,感谢诸位大神的博客,这次主要参考了微额借款用户人品预测大赛冠军的解决方案。
以上就是这次比赛的大概内容了!

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

推荐阅读更多精彩内容