一、写在前面的话
这是我的第一篇博客,希望写好。我几乎是一个编程小白,只有一点点C和Java的经验,一路懵头懵脑的成为了一名经济学渣硕(真的是渣)。研一下学期开了一门《数据挖掘与分析》的课,虽然我也不知道经济学为什么会开这种课,也许是因为学院顶了一个“大数据”的高大上(假大空)头衔,无论怎样,我与机器学习的缘分从此结下。之后开启了一路踩坑的自学之旅,到了今天总算能自己独立写出一个数据挖掘的流程了,虽然很烂,但我相信以后会更好。。。
二、赛题介绍
本次比赛是天池的学习赛,赛题为预测用户贷款是否违约,是一个典型的分类问题。数据来自某信贷平台的贷款记录,总数据量超过120w,包含47列变量信息,其中15列为匿名变量。为了保证比赛的公平性,将会从中抽取80万条作为训练集,20万条作为测试集A,20万条作为测试集B,同时对employmentTitle、purpose、postCode和title等信息进行脱敏。其中isDefault字段为标签。
数据集包含三个下载文件
train.csv:训练集
test.csv:测试集
sample_submit.csv:提交文件样式
三、数据探索&数据预处理
先导入一些必要的包,并读取数据集。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import datetime
from lightgbm.sklearn import LGBMClassifier
from sklearn.metrics import roc_auc_score
from sklearn.model_selection import StratifiedKFold
import warnings
warnings.filterwarnings('ignore')
%matplotlib inline
train=pd.read_csv('DataSet/贷款违约预测/train.csv')
test=pd.read_csv('DataSet/贷款违约预测/testA.csv')
我们一开始最关心的倒不是各个特征的分布,而是各特征的数据类型以及每个特征有多少种不同的取值。
train.info()
test.info()
for feature in train.columns:
print("{}特征有个{}不同的值".format(feature,train[feature].nunique()))
output1:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 800000 entries, 0 to 799999
Data columns (total 47 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 id 800000 non-null int64
1 loanAmnt 800000 non-null float64
2 term 800000 non-null int64
3 interestRate 800000 non-null float64
4 installment 800000 non-null float64
5 grade 800000 non-null object
6 subGrade 800000 non-null object
7 employmentTitle 799999 non-null float64
8 employmentLength 753201 non-null object
9 homeOwnership 800000 non-null int64
10 annualIncome 800000 non-null float64
11 verificationStatus 800000 non-null int64
12 issueDate 800000 non-null object
13 isDefault 800000 non-null int64
14 purpose 800000 non-null int64
15 postCode 799999 non-null float64
16 regionCode 800000 non-null int64
17 dti 799761 non-null float64
18 delinquency_2years 800000 non-null float64
19 ficoRangeLow 800000 non-null float64
20 ficoRangeHigh 800000 non-null float64
21 openAcc 800000 non-null float64
22 pubRec 800000 non-null float64
23 pubRecBankruptcies 799595 non-null float64
24 revolBal 800000 non-null float64
25 revolUtil 799469 non-null float64
26 totalAcc 800000 non-null float64
27 initialListStatus 800000 non-null int64
28 applicationType 800000 non-null int64
29 earliesCreditLine 800000 non-null object
30 title 799999 non-null float64
31 policyCode 800000 non-null float64
32 n0 759730 non-null float64
33 n1 759730 non-null float64
34 n2 759730 non-null float64
35 n3 759730 non-null float64
36 n4 766761 non-null float64
37 n5 759730 non-null float64
38 n6 759730 non-null float64
39 n7 759730 non-null float64
40 n8 759729 non-null float64
41 n9 759730 non-null float64
42 n10 766761 non-null float64
43 n11 730248 non-null float64
44 n12 759730 non-null float64
45 n13 759730 non-null float64
46 n14 759730 non-null float64
dtypes: float64(33), int64(9), object(5)
memory usage: 286.9+ MB
output2:
id特征有个800000不同的值
loanAmnt特征有个1540不同的值
term特征有个2不同的值
interestRate特征有个641不同的值
installment特征有个72360不同的值
grade特征有个7不同的值
subGrade特征有个35不同的值
employmentTitle特征有个248683不同的值
employmentLength特征有个11不同的值
homeOwnership特征有个6不同的值
annualIncome特征有个44926不同的值
verificationStatus特征有个3不同的值
issueDate特征有个139不同的值
isDefault特征有个2不同的值
purpose特征有个14不同的值
postCode特征有个932不同的值
regionCode特征有个51不同的值
dti特征有个6321不同的值
delinquency_2years特征有个30不同的值
ficoRangeLow特征有个39不同的值
ficoRangeHigh特征有个39不同的值
openAcc特征有个75不同的值
pubRec特征有个32不同的值
pubRecBankruptcies特征有个11不同的值
revolBal特征有个71116不同的值
revolUtil特征有个1286不同的值
totalAcc特征有个134不同的值
initialListStatus特征有个2不同的值
applicationType特征有个2不同的值
earliesCreditLine特征有个720不同的值
title特征有个39644不同的值
policyCode特征有个1不同的值
n0特征有个39不同的值
n1特征有个33不同的值
n2特征有个50不同的值
n3特征有个50不同的值
n4特征有个46不同的值
n5特征有个65不同的值
n6特征有个107不同的值
n7特征有个70不同的值
n8特征有个102不同的值
n9特征有个44不同的值
n10特征有个76不同的值
n11特征有个5不同的值
n12特征有个5不同的值
n13特征有个28不同的值
n14特征有个31不同的值
这里只列出训练集,测试集与此相似。考虑到训练集有80万个样本,可以考虑使用一些集成算法。结合赛题背景,我们发现:
1.employmentLength应为连续特征,我们需要把它变成数值类型。
2.issueDate和earliesCreditLine虽然是时间,但我们可以把它们减去一个基期时间,变成一个连续特征。
3.离散特征没有缺失,部分连续特征存在缺失,考虑回归填充。
4.id特征是无意义的,直接剔除。
5.policyCode特征只有一个取值,直接剔除。
接下来按照惯例继续查看数据集基本信息
train.describe()
test.describe()
train.head()
test.head()
好吧,并没有什么新的发现,果然还是info最有用。
通过上面的探索,结合金融背景,我们已经可以把离散特征和连续特征分开了
cat_features=['grade','subGrade','employmentTitle','homeOwnership','verificationStatus','purpose',
'postCode','regionCode','initialListStatus','applicationType']
num_features=['loanAmnt','term',