贷款违约预测3-特征工程

2020-09-21  本文已影响0人  木头里有虫911

在上一期的文章中,前面我们对数据集进行了详细的探索性分析(https://www.jianshu.com/p/b797b043e9b6),本期我们开始最重要的特征工程的内容。
首先我们要明白为什么要进行特征工程。
机器学习项目中有一句非常著名的话: 数据决定了模型的上限,算法只是逼近这个上限而已。
由此我们可以知道数据在机器学习项目中的重要性。数据的质量对模型的精度和质量有决定性的影响。但是在实际中,原始数据有如下几个问题,必须经过处理后才能用于建模和训练使用:

可以毫不夸张的说,特征工程至少占了一个机器学习项目40%的工作量,甚至更多!提高数据质量是特征工程的终极目标。一个完整的特征工程分为数据预处理(Data Preprocessing)、特征构造(Feature Construction)、特征抽取(Feature Extraction)和特征选择(Feature Selection)等几个步骤,每个步骤间没有明显的顺序之分,往往需要根据需求反复执行,甚至也没有严格区分的概念边界,例如特征构造可能会与数据预处理使用同样的数据变换技术等。

下面我们就总结缺省值/异常值处理、时间序列处理、特征编码和特征选择等常用方法,并使用贷款违约预测的数据集进行代码演示

导包:

from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import MinMaxScaler
from catboost import CatBoostRegressor
import warnings
from sklearn.metrics import accuracy_score, f1_score, roc_auc_score, log_loss
warnings.filterwarnings('ignore')

缺省值查看:

numerical_fea = list(train.select_dtypes(exclude=['object']).columns)
category_fea = list(filter(lambda x: x not in numerical_fea,list(train.columns)))
label = 'isDefault'
numerical_fea.remove(label)
train.isnull().sum()

>>>id                        0
loanAmnt                  0
term                      0
interestRate              0
installment               0
grade                     0
subGrade                  0
employmentTitle           1
employmentLength      46799
homeOwnership             0
annualIncome              0
verificationStatus        0
issueDate                 0
isDefault                 0
purpose                   0
postCode                  1
regionCode                0
dti                     239
delinquency_2years        0
ficoRangeLow              0
ficoRangeHigh             0
openAcc                   0
pubRec                    0
pubRecBankruptcies      405
revolBal                  0
revolUtil               531
totalAcc                  0
initialListStatus         0
applicationType           0
earliesCreditLine         0
title                     1
policyCode                0
n0                    40270
n1                    40270
n2                    40270
n3                    40270
n4                    33239
n5                    40270
n6                    40270
n7                    40270
n8                    40271
n9                    40270
n10                   33239
n11                   69752
n12                   40270
n13                   40270
n14                   40270
issueDateDT               0
dtype: int64

1. 缺省值填充:

一般来说,缺失值是不可以直接删除的,因为:

基于此,在机器学习项目中,都是对缺省值做填充处理。常见的填充方法有:

#按照平均数填充数值型特征
train[numerical_fea] = train[numerical_fea].fillna(train[numerical_fea].median())
test[numerical_fea] = test[numerical_fea].fillna(train[numerical_fea].median())
#按照众数填充类别型特征
train[category_fea] = train[category_fea].fillna(train[category_fea].mode())
test[category_fea] = test[category_fea].fillna(train[category_fea].mode())

train.isnull().sum()

id                        0
loanAmnt                  0
term                      0
interestRate              0
installment               0
grade                     0
subGrade                  0
employmentTitle           0
employmentLength      46799
homeOwnership             0
annualIncome              0
verificationStatus        0
issueDate                 0
isDefault                 0
purpose                   0
postCode                  0
regionCode                0
dti                       0
delinquency_2years        0
ficoRangeLow              0
ficoRangeHigh             0
openAcc                   0
pubRec                    0
pubRecBankruptcies        0
revolBal                  0
revolUtil                 0
totalAcc                  0
initialListStatus         0
applicationType           0
earliesCreditLine         0
title                     0
policyCode                0
n0                        0
n1                        0
n2                        0
n3                        0
n4                        0
n5                        0
n6                        0
n7                        0
n8                        0
n9                        0
n10                       0
n11                       0
n12                       0
n13                       0
n14                       0
issueDateDT               0
dtype: int64

可以看到数值型的特征已被处理

2. 时间序列数据处理:

# 其中的issue为时间格式,需要转化
#转化成时间格式
for data in [train, test]:
    data['issueDate'] = pd.to_datetime(data['issueDate'],format='%Y-%m-%d')
    startdate = datetime.datetime.strptime('2007-06-01', '%Y-%m-%d')
    #构造时间特征
    data['issueDateDT'] = data['issueDate'].apply(lambda x: x-startdate).dt.days

下面在对类别型的数据进行编码,即映射成数值型数据,以便于后期的模型使用

category_fea
>>>['grade','subGrade','employmentLength','homeOwnership','verificationStatus','purpose']

下面直接调用sk-learn下面的preprocessing模块处理:

from sklearn.preprocessing import LabelEncoder, OneHotEncoder
le = LabelEncoder()
train['grade'] = le.fit_transform(train['grade'])
train['subGrade'] = le.fit_transform(train['subGrade'])
train['employmentLength'] = train['employmentLength'].apply(lambda x : str(x))
train['employmentLength'] = le.fit_transform(train['employmentLength'])
test['grade'] = le.fit_transform(test['grade'])
test['subGrade'] = le.fit_transform(test['subGrade'])
test['employmentLength'] = test['employmentLength'].apply(lambda x : str(x))
test['employmentLength'] = le.fit_transform(data['employmentLength'])

最后是对类别型特征进行转换,使其变为数值特征。包括两种情况:一种是对非数值特征数值化;另一种是对数值(这里的数值其实并没有 “数” 所代表的意义,只是个代码,所以要重新编码)编码。

具体有以下几种方法:

经过上面一通操作操作后,在查看一下现在数据样式,可以发现所有特征已经妆化成数值型的数据了,
至此特征工程初步结束,后期可以根据模型训练的效果,反复此步骤构建新的特征等。

另外,在实际应用中,随着对业务的深入理解我们可以通过现有的数据特征,创造新的特征,包括:

  1. 衍生(升维)
  2. 筛选(降维)
    说起来简单,实际中,衍生和筛选都是困难重重,甚至需要非常专业的专家知识。这个也是一个高级分析师和初级分析师之间的壁垒。因为很多时候,资深的数据分析师就是体现在对业务深入理解方面。这个是需要在实践不断摸索锤炼的技能。

通过上面对特征工程的简要概述我们看到特征工程是一个庞大的工程,并且融入了自身的业务知识。想要做好一个特征工程,精通业务是前提。这个也是一个高级分析师和初级分析师之间的壁垒。因为很多时候,资深的数据分析师就是体现在对业务深入理解方面。特征工程做好了,也可以把自己和调参侠、调包侠区分开来了。

上一篇下一篇

猜你喜欢

热点阅读