一、项目介绍

阿里天池数据挖掘学习赛:贷款违约预测
学习赛主要为初学者准备的,论坛里有详细的项目建模过程。这里,仅记录一下自己在做这个项目时的一些思路。

二、数据分析

这里的数据分析过程主要参考有:
Datawhale零基础入门金融风控 Task2 数据分析
「机器学习」天池比赛:金融风控贷款违约预测
上面两个帖子讲述的已经非常详细,在这里就不在赘述了。

三、特征工程

1. 缺失值处理

先导入需要的库

import pandas as pd
import datetime
import warnings
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
warnings.filterwarnings('ignore')from sklearn.model_selection import StratifiedKFold
from sklearn.metrics import roc_auc_score
from sklearn.model_selection import train_test_split # 分训练集和测试集
from catboost import CatBoostClassifierimport time
from sklearn.tree import DecisionTreeClassifier

首先,通过data.info()可知数据的特征类型分为数值型特征和类别型特征,并且这两种都存在缺失值;对于数值型特征直接采用中位数填充缺失值;类别型特征只有employLength存在缺失值,这里采用决策树去预测缺失值的方法进行填充。
然后,将类别型的特征(贷款等级/子等级、就业时长)通过编码转换为数值型。
最后,对日期型数据进行处理(发行日期、信用额度开立的月份),issue_days主要记录距离最早发行日期的天数。

import time
from sklearn.tree import DecisionTreeClassifierdef gradeTrans(x):dict = {'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5, 'F': 6, 'G': 7}result = dict[x]return resultdef subGradeTrans(x):dict = {'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5, 'F': 6, 'G': 7}result = dict[x[0]]result = result * 5 + int(x[1])return resultdef employmentLength_deal(x):if x == '< 1 year':result = 0.5elif x == '10+ years':result = 12else:result = int(x.split(' ')[0][0])# print(result)return resultdef transform_day(date1):date2 = "2007-06-01"date1 = time.strptime(date1, "%Y-%m-%d")date2 = time.strptime(date2, "%Y-%m-%d")# 根据上面需要计算日期还是日期时间,来确定需要几个数组段。下标0表示年,小标1表示月,依次类推...# date1=datetime.datetime(date1[0],date1[1],date1[2],date1[3],date1[4],date1[5])# date2=datetime.datetime(date2[0],date2[1],date2[2],date2[3],date2[4],date2[5])date1 = datetime.datetime(date1[0], date1[1], date1[2])date2 = datetime.datetime(date2[0], date2[1], date2[2])# 返回两个变量相差的值,就是相差天数# print((date2 - date1).days)  # 将天数转成int型return (date1 - date2).daysdef earliesCreditLine_month_deal(x):x = x.split('-')[0]# print(x)dict = {'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4, 'May': 5, 'Jun': 6, 'Jul': 7, 'Aug': 8, 'Sep': 9, 'Oct': 10,'Nov': 11, 'Dec': 12}result = dict[x]return result# 预处理
def data_preprocess():# 加载数据train_label = pd.read_csv('train.csv')['isDefault']train = pd.read_csv('train.csv')test = pd.read_csv('testA.csv')# 拼接数据data = pd.concat([train, test], axis=0, ignore_index=True) # 将训练数据与测试数据进行拼接print('初始拼接后:', data.shape)# 处理缺失值# 数值型numerical_fea = list(data.select_dtypes(exclude=['object']).columns) # 获取数值型特征对应的列numerical_fea.remove('isDefault') # 将标签列移除print(numerical_fea)data[numerical_fea] = data[numerical_fea].fillna(data[numerical_fea].median()) # 用中位数填充缺失值# 类别型# 用决策树填补就业年限empLenNotNullInd = data.employmentLength.notnull() # 不是空的行,返回Truecolumns = ['postCode','regionCode','employmentTitle','annualIncome'] # 用四个特征来预测employmentLengthdata_empLen_X  = data.loc[empLenNotNullInd,columns] # 取不为空的行,以及上述四列data_empLen_y = data.employmentLength[empLenNotNullInd] # 取行不为空的标签(雇佣年限)DTC = DecisionTreeClassifier() # 实例化DTC.fit(data_empLen_X ,data_empLen_y) # 训练print('决策树训练分数:',DTC.score(data_empLen_X ,data_empLen_y))empLenIsNullInd = data.employmentLength.isnull() # 取就业年限为空的行test_empLen_X  = data.loc[empLenIsNullInd,columns] empLen_pred = DTC.predict(test_empLen_X)data.employmentLength[empLenIsNullInd] = empLen_predprint('缺失值情况:', data.isnull().sum()) data['grade'] = data['grade'].apply(lambda x: gradeTrans(x)) # 对贷款等级进行编码 A:1 ...data['subGrade'] = data['subGrade'].apply(lambda x: subGradeTrans(x)) # 对贷款子等级进行编码print('1data.shape', data.shape)data['employmentLength'] = data['employmentLength'].apply(lambda x: employmentLength_deal(x)) # 将就业时长(类别特征)转换为数值特征data['issueDate_year'] = data['issueDate'].apply(lambda x: int(x.split('-')[0])) # 将贷款发行的时间拆分为年月天数(距离最早发行日期的天数2007-6-1data['issueDate_month'] = data['issueDate'].apply(lambda x: int(x.split('-')[1]))data['issueDate_day'] = data['issueDate'].apply(lambda x: transform_day(x)) # 到最早发行日2007-6-1的天数
#     data['issueDate_week'] = data['issueDate_day'].apply(lambda x: int(x % 7) + 1)print('2_data.shape', data.shape)data['earliesCreditLine_year'] = data['earliesCreditLine'].apply(lambda x: 2022 - (int(x.split('-')[-1]))) # 最早信用额度开户时间距离现在的年数data['earliesCreditLine_month'] = data['earliesCreditLine'].apply(lambda x: earliesCreditLine_month_deal(x)) # data['earliesCreditLine_Allmonth'] = data['earliesCreditLine_year'] * 12 - data['earliesCreditLine_month'] # 最早信用额度开户时间距离现在的月数del data['issueDate'], data['earliesCreditLine']print('预处理完毕', data.shape)return data, train_label
data, train_label = data_preprocess()

2. 自定义特征

# 自定义可解释特征
def gen_basicFea(data):data['avg_income'] = data['annualIncome'] / data['employmentLength'] data['total_income'] = data['annualIncome'] * data['employmentLength'] # 入职以来的总收入data['avg_loanAmnt'] = data['loanAmnt'] / data['term'] # 平均贷款金额data['mean_interestRate'] = data['interestRate'] / data['term'] # 平均利率data['all_installment'] = data['installment'] * data['term'] # 总的付款金额data['rest_money_rate'] = data['avg_loanAmnt'] / (data['annualIncome'] + 0.1)  # 287个收入为0data['rest_money'] = data['annualIncome'] - data['avg_loanAmnt'] # 每年还款之后的剩余存款data['closeAcc'] = data['totalAcc'] - data['openAcc'] #  档案中已结信用额度数量data['ficoRange_mean'] = (data['ficoRangeHigh'] + data['ficoRangeLow']) / 2 # 借款人在贷款发放时的fico所属的均值del data['ficoRangeHigh'], data['ficoRangeLow']data['rest_pubRec'] = data['pubRec'] - data['pubRecBankruptcies'] # 未清除的贬损公共记录数量data['rest_Revol'] = data['loanAmnt'] - data['revolBal'] #  ????data['dis_time'] = data['issueDate_year'] - (2022 - data['earliesCreditLine_year']) #???data['rato']=data['totalAcc']/data['loanAmnt']
#     for col in ['employmentTitle', 'grade', 'subGrade', 'regionCode', 'issueDate_day', 'postCode','term','homeOwnership']:
#         data['{}_count'.format(col)] = data.groupby([col])['id'].transform('count')return data
data = gen_basicFea(data)

这里主要参考了博客天池安泰杯金融科技挑战赛冠军方案,文章中提到了对匿名特征(n0-n14)进行暴力处理,以及进行组合交叉特征,因为我主要用的是catboost算法可以自行对指定的类别特征进行交叉,所以并没有进行处理。

3. 特征编码

由于catboost能够对指定的类别特征进行编码(包括one-hot方法、目标编码等),所以在这里并没有进行处理。如果想要使用xgboost算法则需要进行编码,编码方式可参照上述提到的天池安泰杯金融科技挑战赛冠军方案。

四、模型创建

这里主要参考博客阿里天池金融风控baseline

train = data[~data['isDefault'].isnull()].copy() # 训练数据
target = train_label # 标签
test = data[data['isDefault'].isnull()].copy() # 测试数据sub=test[['id']].copy()
sub['isDefault']=0train = train.drop(['isDefault','id','policyCode'],axis=1) # 训练数据
test=test.drop(['isDefault','id','policyCode'],axis=1)
print(train.shape)
print(test.shape)# 定义需要编码的类别特征
col=['grade','subGrade','employmentTitle','homeOwnership','verificationStatus','purpose','postCode','regionCode','initialListStatus','applicationType','title']
# 将类别特征的数据类型转换为整型(也可转换为字符型)
for i in train.columns:if i in col:train[i] = train[i].astype('int64')
for i in test.columns:if i in col:test[i] = test[i].astype('int64')
# 创建模型
model=CatBoostClassifier(loss_function="Logloss",eval_metric="AUC",task_type="CPU",learning_rate=0.1,iterations=1000,random_seed=2020,od_type="Iter",depth=7)
# 采用十折交叉验证
answers = []
mean_score = 0
n_folds = 10
sk = StratifiedKFold(n_splits=n_folds, shuffle=True, random_state=2021)for train_, test_ in sk.split(train, train_label):x_train = train.iloc[train_]y_train = train_label.iloc[train_]x_test = train.iloc[test_]y_test = train_label.iloc[test_]clf = model.fit(x_train,y_train, eval_set=(x_test,y_test),verbose=500,cat_features=col)yy_pred_valid=clf.predict(x_test,prediction_type='Probability')[:,-1]print('cat验证的auc:{}'.format(roc_auc_score(y_test, yy_pred_valid)))mean_score += roc_auc_score(y_test, yy_pred_valid) / n_foldsy_pred_valid = clf.predict(test,prediction_type='Probability')[:,-1]answers.append(y_pred_valid)
print('mean valAuc:{}'.format(mean_score))
# 存储预测结果
cat_pre=sum(answers)/n_folds
sub['isDefault']=cat_pre
sub.to_csv('金融预测.csv',index=False)

总结

  1. 没有进行异常值检测和特征选择,当特征数目过多时会影响评分速度
  2. catboost的参数没有进行细调(主要因为懒)
  3. 没有尝试模型融合,效果能达到0.742左右,感兴趣的小伙伴可以尝试一下模型融合看效果是否会提升。

金融风控-贷款违约预测项目记录相关推荐

  1. 阿里天池学习赛-金融风控-贷款违约预测

    阿里天池学习赛-金融风控-贷款违约预测 1 赛题理解 1.1 赛题数据 1.2 评测标准 2 探索性分析(EDA) 2.1 初窥数据 2.2 查看缺失值占比 2.3 数值型变量 2.3.1 数据分布 ...

  2. 数据挖掘实践(金融风控-贷款违约预测)(二):数据分析

    数据挖掘实践(金融风控-贷款违约预测)(二):数据分析 目录 数据挖掘实践(金融风控-贷款违约预测)(二):数据分析 1.引言 2.基本知识点 2.1缺失值(Missing data) 2.1.1缺失 ...

  3. 数据挖掘实践(金融风控-贷款违约预测)(三):特征工程

    数据挖掘实践(金融风控-贷款违约预测)(三):特征工程 目录 数据挖掘实践(金融风控-贷款违约预测)(三):特征工程 1.引言 2.特征预处理 2.1缺失值填充 2.2时间格式处理 2.3类别特征处理 ...

  4. 数据挖掘之金融风控-贷款违约预测 02数据分析

    数据挖掘之金融风控-贷款违约预测 02数据分析 数据挖掘之金融风控-贷款违约预测 02数据分析 1. 学习目标 2. 学习内容 3. 学习过程 3.1 导入库并读取数据集 3.2 数据集基本信息 3. ...

  5. 基于机器学习与深度学习的金融风控贷款违约预测

    基于机器学习与深度学习的金融风控贷款违约预测 目录 一.赛题分析 1. 任务分析 2. 数据属性 3. 评价指标 4. 问题归类 5. 整体思路 二.数据可视化分析 1. 总体数据分析 2. 数值型数 ...

  6. 笔记之零基础入门金融风控-贷款违约预测

    零基础入门金融风控-贷款违约预测 赛题描述 赛题概况 数据概况 合理的创建标题,有助于目录的生成 预测指标 赛题流程 评分卡 笔记记录转载 赛题描述 赛题以金融风控中的个人信贷为背景,要求选手根据贷款 ...

  7. 「机器学习」天池比赛:金融风控贷款违约预测

    一.前言 1.1 赛题背景 赛题以金融风控中的个人信贷为背景,要求选手根据贷款申请人的数据信息预测其是否有违约的可能,以此判断是否通过此项贷款,这是一个典型的分类问题. 任务:预测用户贷款是否违约 比 ...

  8. DataWhale天池-金融风控贷款违约预测-Task01赛题理解

    目录 一.赛题概况 二.数据集介绍 三.预测指标 理解 通过ROC曲线评估分类器 最佳阈值点选择 一.赛题概况 本次新人赛是Datawhale与天池联合发起的0基础入门系列赛事第四场 -- 零基础入门 ...

  9. 零基础入门金融风控-贷款违约预测-机器学习-数据分析

    零基础入门金融风控-贷款违约预测 一.赛题数据 赛题以预测用户贷款是否违约为任务,数据集报名后可见并可下载,该数据来自某信贷平台的贷款记录,总数据量超过120w,包含47列变量信息,其中15列为匿名变 ...

最新文章

  1. 写代码:输入一年份,判断该年份是否是闰年并输出结果。
  2. Oracle GoldenGate 之--异构平台同步(Mysql到Oracle)
  3. Android调试工具_ Stetho
  4. 好玩的Scratch
  5. bzoj1556 (DP)
  6. vue进入页面执行的钩子函数_解决VUE mounted 钩子函数执行时 img 未加载导致页面布局的问题...
  7. ajax的post方式传数组参数
  8. 小米“祭出” AIoT 神器!| 技术头条
  9. 第二章 Javac编译原理
  10. 弥补Reflector反编译对中文支持的不足
  11. 极简代码(二)—— 转置 list of lists
  12. mysql oldaltertable_MySQL5.6 ALTER TABLE 分析和测试
  13. vsftpd配置(虚拟用户、匿名用户登录)
  14. 数据库软件access mysql对比_access数据库软件优缺点对比
  15. java对接dhl_DHL接口—数据交互
  16. 制作业信息化为什么难施行?
  17. Mysql横向分组统计
  18. HTML超链接怎么设置下拉菜单,html超链接怎么设置
  19. 【前端基础知识】最基础的render渲染函数知识,一看就会
  20. 怎么申请邮箱?163邮箱如何注册使用?

热门文章

  1. oracle 基础dbms错误,更改对 DBMS 错误的响应
  2. 什么是cve什么是cwe_什么是CVE 2020 0601又名Curveball,为何如此危险
  3. python中xpath使用案例_python爬虫学习笔记:XPath语法和使用示例
  4. 中国卫生材料及医药用品行业发展前景与投资战略规划分析报告2022-2028年
  5. Seagate-保修验证(za25shrx)
  6. Flutter强制某个页面横屏
  7. bilibili封面
  8. 使用python画k均值分类图
  9. 把Ubuntu主机加入Window工作组
  10. Android应用内换肤