【机器学习】金融风控贷款违约预测--数据分析处理

目录

        0.前言

        1.数据分析处理

         1.1 导入训练集和测试集

         1.2 检查是否有可舍去的数据

         1.3 利用IV值挑选特征

         1.4 数值特征 & 类别特征

         1.5 缺失值填充

         1.6 类别特征处理

                1.6.1 grade 贷款等级

                1.6.2 subGrade 贷款等级之子级

                1.6.3 issueDate 贷款发放日期

                1.6.4 earliesCreditLine 借款人最早报告的信用额度开立的月份

         1.7 数值特征处理

                1.7.1 离散型变量

                1.7.2 连续型变量

2.总结

0.前言

        又是苦恼毕设的一天......好想出去玩啊/(ㄒoㄒ)/~~

        因为这两天拿到了一个数据集,但一看有20来个特征,又完全没有清洗过,很脏很脏的数据,一时不知如何下手,又因为之前一直都在做NLP,机器学习的东西又忘得差不多了,现在回过头来看,特征处理,真的非常麻烦。

        该博客出于记录拿到一个新的数据该如何着手去分析,分析之后又该如何处理成可以输入进模型的数据。

1.数据分析处理

        默认拿到了一个数据集,已经划分好了训练集和测试集,这里以金融风控-贷款违约预测为例。该任务取自Datawhale与天池联合发起的金融风控赛事。 

零基础入门金融风控-贷款违约预测_学习赛_天池大赛-阿里云天池的赛制 (aliyun.com)

        下图所示是整个数据分析处理的框架。

1.1 导入训练集和测试集

import pandas as pd
train_data = pd.read_csv("./data/train.csv")  # 导入训练集
test_data = pd.read_csv("./data/test.csv")    # 导入测试集
train_data.head()                             # 打印DataFrame的前5行

        这里一般会打印前5行数据来看看,但对于这种有47列的数据,我觉得......我打印完,看了一下,还不如不看,没看出个啥。

        这里其实建议打印所有的列名看看,其中“isDefault”为该数据集的目标值,然后再看看各列的数据是怎样的,有个大致的印象就可以了。这里以‘loanAmnt’为例,可以大概看看,这应该是一个连续数值的特征。

print(train_data.columns)        # 打印数据的所有列名
train_data['loanAmnt'].head(10)  # loanAmnt前10个数据

1.2 检查是否有可舍去的数据

        1.对于序号、id这类特征,对最结果没有影响,可以删除。

        2.缺失值存在过多的特征,可以删除。

        【这里可以谨慎处理,因为缺失值也可以通过填充处理】

        3.该特征只有一种值,对结果没有影响,可以删除。

# 查看训练集,测试集中特征属性只有一值的特征
one_value_fea = [col for col in train_data.columns if train_data[col].nunique() <= 1]
one_value_test_fea = [col for col in test_data.columns if test_data[col].nunique() <= 1]

有一个值的列
train_data.drop('id', axis=1, inplace = True)            # id列对最终的结果并无影响,删除,但为了最终提交结果,保留test_data的id
train_data.drop('policyCode', axis=1, inplace = True)    # 该列只有一个值,所以对结果并不能提供有用信息,删除
test_data.drop('policyCode', axis=1, inplace = True)
train_data.isnull().sum()                                # 查看缺失值情况

1.3 利用IV值挑选特征

        IV值:用来表示特征对目标预测的贡献程度,即特征的预测能力,一般来说,IV值越高,该特征的预测能力越强,信息贡献程度越高。

        由于这次也是初次接触金融风控这块,特征挑选其实还有很多其他的算法,这里就留到后面慢慢探索吧~

import toad  
toad.quality(train_data, target='isDefault', cpu_cores=0, iv_only=False)
# PS:若只想参考IV值,可以将iv_only=True,不然需要耗费很多时间

        因为IV值 < 0.02 判定为该特征无预测能力,所以在这里就选择保存IV >= 0.02的特征。

# 删除无预测能力的特征
for data in [train_data, test_data]:
    data.drop('n5', axis=1, inplace = True)            
    data.drop('n0', axis=1, inplace = True)
    data.drop('regionCode', axis=1, inplace = True)            
    data.drop('n4', axis=1, inplace = True)
    data.drop('n13', axis=1, inplace = True)            
    data.drop('n6', axis=1, inplace = True)
    data.drop('pubRec', axis=1, inplace = True)            
    data.drop('n8', axis=1, inplace = True)
    data.drop('revolBal', axis=1, inplace = True)            
    data.drop('openAcc', axis=1, inplace = True)
    data.drop('postCode', axis=1, inplace = True)            
    data.drop('pubRecBankruptcies', axis=1, inplace = True)
    data.drop('delinquency_2years', axis=1, inplace = True)            
    data.drop('totalAcc', axis=1, inplace = True)
    data.drop('applicationType', axis=1, inplace = True)            
    data.drop('n12', axis=1, inplace = True)
    data.drop('initialListStatus', axis=1, inplace = True)            
    data.drop('n11', axis=1, inplace = True)
    data.drop('purpose', axis=1, inplace = True)            
    data.drop('n1', axis=1, inplace = True)
    data.drop('employmentLength', axis=1, inplace = True)            
    data.drop('n7', axis=1, inplace = True)          
    data.drop('n10', axis=1, inplace = True)

 1.4 数值特征 & 类别特征

        对于上一步处理好剩下的特征,我们将其分成数值特征类别特征。由于数值特征中包含了“isDefault”,这是目标值,不做任何的特征处理,所以去除。(注:这里只是在numerical_fea这个列表中去除了,表示后续不对这个特征进行处理,而不是在数据集中去除了它)

numerical_fea = list(train_data.select_dtypes(exclude=['object']).columns)                # 数值特征
category_fea = list(filter(lambda x: x not in numerical_fea, list(train_data.columns)))  # 类别特征 

# 将 label 去除
label = 'isDefault'
numerical_fea.remove(label)

1.5 缺失值填充

        数值特征:中位数填充。

        类别特征:众数填充。

# 按照中位数,填充数值型特征
train_data[numerical_fea] = train_data[numerical_fea].fillna(train_data[numerical_fea].median())
test_data[numerical_fea] = test_data[numerical_fea].fillna(test_data[numerical_fea].median())
# 按照众数,填充类别型特征
for cate_fea in category_fea:
    train_data[cate_fea] = train_data[cate_fea].fillna(train_data[cate_fea].mode().values[0])
    test_data[cate_fea] = test_data[cate_fea].fillna(test_data[cate_fea].mode().values[0])

        当然,除了上述两种填充方法还有很多其他处理缺失值的方法,比如,对于数据集中缺失值较少的情况,可以直接删除缺失值所在的行;对于数值特征,也可以使用平均值、近似值来填充;还有更复杂的填充方法,先训练一个模型来预测这个缺失值。

1.6 类别特征处理

        该数据集的类别特征有:

        grade、subGrade、issueDate、earliesCreditLine

        1.6.1 grade 贷款等级

        首先,我们先统计一下该样本,整体来看看:

train_data['grade'].value_counts()

        对于等级这种类别特征,是有优先级的,可以采用自映射编码。

# 1.grade
for data in [train_data, test_data]:
    data['grade'] = data['grade'].map({'A':1,'B':2,'C':3,'D':4,'E':5,'F':6,'G':7})

        1.6.2 subGrade 贷款等级之子级

        ''等级之子级''和''等级''的处理方式一样。

# 该函数用于将 subGrade 转换为数值等级
def get_sub_grade(grade, sub):
    return grade*10+int(sub[1])

# 2.subGrade
for data in [train_data, test_data]:
    data['subGrade'] = data.apply(lambda row: get_sub_grade(row['grade'],row['subGrade']), axis=1)
        1.6.3 issueDate 贷款发放日期

        这里将贷款发放日期转变成时间差,变成一个连续数值。

# 3.issueDate
import datetime
for data in [train_data, test_data]:
    data['issueDate'] = pd.to_datetime(data['issueDate'],format='%Y-%m-%d') # 将原始数据转换为 Pandas 的日期时间格式
    startdate = datetime.datetime.strptime('2007-06-01', '%Y-%m-%d') # '2007-06-01'设定为开始日期
    # 每个样本相对于 2007-06-01 的天数
    data['issueDateDT'] = data['issueDate'].apply(lambda x: x-startdate).dt.days # dt.days 将 Timedelta 对象转换为天数
        1.6.4 earliesCreditLine 借款人最早报告的信用额度开立的月份

        我们先打印几个特征的样本来看看:

train_data['earliesCreditLine'].sample(5)

        这里处理的比较粗暴,就只保留年份。 

# 4.earliesCreditLine
for data in [train_data, test_data]:
    data['earliesCreditLine'] = data['earliesCreditLine'].apply(lambda s: int(s[-4:])) # 只保留年份

        好的!!!!!!做到这里,恭喜你!!!!!!!成功使类别特征(string、time啊......这些)转换为了数值特征。 

1.7 数值特征处理

        我们首先划分数值型变量中的:连续变量和离散型变量。通过统计该特征不同种类的数值个数来判断,若该特征的数值种类 <= 10,则认为其是离散型变量。

# 划分数值型变量中的:连续变量和离散型变量
def get_numerical_serial_fea(data,feas):
    numerical_serial_fea = []                 # 连续变量
    numerical_noserial_fea = []               # 离散变量
    for fea in feas:
        temp = data[fea].nunique()
        if temp <= 10:
            numerical_noserial_fea.append(fea)
        else:
            numerical_serial_fea.append(fea)
    return numerical_serial_fea,numerical_noserial_fea
numerical_serial_fea,numerical_noserial_fea = get_numerical_serial_fea(train_data,numerical_fea)

       1.7.1 离散型变量

        对于离散型变量,我们不做任何处理,这里我觉得它是跟类别变量替换为数值之后是相同类型的。 

        1.7.2 连续型变量

        对于连续型变量,我这里只做了分箱处理,分箱主要是为了降低变量的复杂性,减少变量噪音对模型的影响,提高自变量和因变量的相关度,从而使模型更加稳定。

        具体做法就是,比如将age在0-5的分入一个箱子中,age在6-10的又分入另外一个箱子中。

        另外,这十几个连续数值特征也不是每一个都进行了分箱操作,(我参照了大佬的选择需要分箱的数据,但具体是什么原因选择这些数据进行分箱,我也不太懂......)通常来说,取决于:

特征的分布情况: 对于近似正态分布或者接近线性关系的特征,不一定需要进行分箱操作。但对于偏态分布或者存在非线性关系的特征,分箱操作可能会有所帮助。

特征的重要性: 在特征选择过程中,通常会评估每个特征对目标变量的重要性。如果某个连续型数值特征对目标变量的影响较大,那么对其进行分箱操作可能会提高模型性能。

# 分箱操作
for data in [train_data, test_data]:
    data['loanAmnt'] = pd.qcut(data['loanAmnt'], 10, labels=False)
    data['interestRate'] = pd.qcut(data['interestRate'].rank(method='first'), 100, labels=False)
    data['installment'] = pd.qcut(data['installment'], 100, labels=False)
    data['annualIncome'] = pd.qcut(data['annualIncome'], 10, labels=False)
    data['dti'] = pd.qcut(data['dti'], 100, labels=False)
    data['revolUtil'] = pd.qcut(data['revolUtil'], 100, labels=False)

2.总结

        至此,该任务的数据分析处理就到此结束了,建模与评估请移步至:

【机器学习】金融风控贷款违约预测--建模与评估-CSDN博客

        在本篇中,其实也有很多不足之处,比如,没有做特征交互,对于类别特征可以做更高维的映射,对于一些比较重要的特征其实并没有取出来好好分析,然后更好地做特征处理,因为在机器学习中,特征工程真的非常重要,在业界有一个很流行地说法:数据和特征工程决定了模型的上限,改进算法只不过是逼近这个上限而已。但本文也是我的初步探索金融风控,至少搞明白了拿到一份数据,分析处理的步骤是怎样的,后面再慢慢进步吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值