1. 案例介绍¶
国内某贷款机构的车贷业务面临借款人拖欠还款或拒不还款,导致该机构的不良贷款率居高不下的问题。该机构将部分贷款数据开放,诚邀大家帮助他们建立风险识别模型来预测可能违约的借款人(敏感信息已脱敏)
- 给定某机构实际业务中的相关借款人信息,包含53个与客户相关的字段
- 其中loan_default字段表明借款人是否会拖欠付款
- 任务目标是通过训练集训练模型,来预测测试集中loan_default字段的具体值,即借款人是否会拖欠付款,以此为依据,降低贷款风险。
2. 数据集介绍¶
customer_id 客户标识符
main_account_loan_no 主账户申请贷款数量
main_account_active_loan_no 主账户申请的有效贷款数量
main_account_overdue_no 主账号逾期数量
main_account_outstanding_loan 主账户未偿还的贷款余额
main_account_sanction_loan 主账户所有贷款被批准的贷款金额
main_account_disbursed_loan 主账户所有贷款已发放的贷款金额
sub_account_loan_no 二级账户申请贷款数量
sub_account_active_loan_no 二级账户申请的有效贷款数量
sub_account_overdue_no 二级账户逾期数量
sub_account_outstanding_loan 二级账户未偿还的贷款金额
sub_account_sanction_loan 二级账户所有贷款被批准的贷款金额
sub_account_disbursed_loan 二级账户所有贷款已发放的贷款金额
disbursed_amount 已发放贷款金额
asset_cost 资产成本
branch_id 发放贷款的分行
supplier_id 发放贷款的车辆经销商
manufacturer_id 汽车制造商
year_of_birth 客户出生日期
disbursed_date 贷款日期
area_id 付款区域
employee_code_id 记录付款的对接员工
mobileno_flag 是否填写手机号
idcard_flag 是否填写身份证
Driving_flag 是否出具驾驶证
passport_flag 是否填写护照
credit_score 信用评分
main_account_monthly_payment 主账户月供金额
sub_account_monthly_payment 二级账户的月供金额
last_six_month_new_loan_no 过去六个月客户的新贷款申请数量
last_six_month_defaulted_no 过去六个月客户的违约数量
average_age 平均贷款期限
credit_history 信用记录
enquirie_no 客户查询贷款次数
loan_to_asset_ratio 贷款与资产比例
total_account_loan_no 所有账户申请的活跃贷款数量
main_account_inactive_loan_no 主账户申请的无效贷款数量
sub_account_inactive_loan_no 二级账户申请的无效贷款数量
total_inactive_loan_no 所有账户申请的无效贷款数量
total_overdue_no 所有账户的逾期次数
total_outstanding_loan 所有账户的未结余额的总额
total_sanction_loan 来自所有账户的所有贷款被批准的贷款金额
total_disbursed_loan 为所有账户的所有贷款支付的贷款金额
total_monthly_payment 所有账户的月供金额
outstanding_disburse_ratio 已发放贷款总额/未偿还贷款总额(两者比例)
main_account_tenure 主账户还款期数
sub_account_tenure 二级账户还款期数
disburse_to_sactioned_ratio 已发放贷款/批准贷款(两者比例)
active_to_inactive_act_ratio 有效贷款次数/无效贷款次数(两者比例)
Credit_level 信用评分
employment_type 工作类型
age 年龄
loan_default 1表示客户逾期,0表示客户未逾期
3. 案例实现¶
import joblib
from sklearn.ensemble import RandomForestClassifier
import pandas as pd
from sklearn.model_selection import train_test_split
import joblib
import numpy as np
from imblearn.over_sampling import SMOTE
from collections import Counter
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)
pd.set_option('display.width', 1000)
if __name__ == '__main__':
# 1. 加载数据集
data = pd.read_csv('data/车辆贷款违约预测.csv')
# 2. 数据基本处理
# 删除指定某些列
data = data.drop(['customer_id', 'disbursed_date'], axis=1)
# 有些特征中的数据使用 inf 标记, 需要删除
inf_names = []
for name in data.columns:
if np.any(np.isinf(data[name])):
inf_names.append(name)
for name in inf_names:
# 获得包含 inf 的行索引
inf_ids = data[data[name] == np.inf].index
# 删除索引对应的数据
data = data.drop(inf_ids)
# 3. 特征值和目标值
x = data.iloc[:, :-1].astype(np.float64)
y = data.iloc[:, -1]
# 4. 类别不平衡数据处理
print('各类别数据比例:', Counter(y))
x, y = SMOTE(random_state=42).fit_resample(x, y)
print('各类别数据比例:', Counter(y))
# 5. 数据集分割
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, stratify=y, random_state=22)
# 6. 随机森林训练和存储
# 随机森林训练 0.89
estimator = RandomForestClassifier(n_estimators=500,oob_score=True, random_state=22)
# AdaBoost训练
# estimator = AdaBoostClassifier(n_estimators=500, random_state=22)
print('训练数据形状:', x_train.shape)
estimator.fit(x_train, y_train)
# 保存模型
joblib.dump(estimator, 'model/random_forest.pth')
# 7. 模型预测
from sklearn.metrics import classification_report
accurary = estimator.score(x_test, y_test)
print('OOB:', estimator.oob_score_)
print('ACC:', accurary)
# 打印精度、召回率、f1-score、accuracy
print(classification_report(y_true=y_test, y_pred=estimator.predict(x_test)))