数据清洗与机器学习贷款偿还预测建模
随着金融领域对风险管理要求的不断提高,预测贷款偿还情况成为了信贷评估的核心任务。通过机器学习模型来预测贷款是否会被按时偿还,能够为金融机构提供更为准确的决策支持,降低信贷风险。本文将基于一个典型的贷款数据集,展示数据清洗、特征选择和模型训练的完整流程。
本文将探讨如何通过数据预处理和特征工程来提升贷款偿还预测的准确性,并利用逻辑回归与随机森林分类器等模型进行训练与评估,为贷款违约预测和金融风控提供方法论支持。
文章目录
- 案例概述
- 数据详解
- 案例分析
- 总结
案例概述
本案例数据地址 Loan Amount Data。
模块名称 | 内容简介 | 所需技能 | 数据类型 | 应用场景 |
---|---|---|---|---|
案例概述 | 该案例通过数据预处理和机器学习模型建立来预测贷款的偿还情况。初步阶段包括数据清洗、特征选择和编码,之后使用逻辑回归和随机森林分类器进行模型训练和评估。 | Python编程,Pandas数据处理,机器学习基础 | CSV文件,数值型数据,分类数据 | 金融风险评估,信用评分 |
案例目标 | 清洗贷款数据,选择有效特征,并通过机器学习模型预测贷款的偿还状态。 | 数据清洗,特征选择,模型训练,交叉验证 | 数值型数据,分类标签 | 信贷分析,贷款违约预测 |
评价指标 | 使用混淆矩阵评估模型性能,包括真正率(TPR)和假正率(FPR)。 | 机器学习模型评估,混淆矩阵 | 数值型数据 | 模型性能评估,分类问题分析 |
业务意义 | 通过预测贷款的偿还状态,可以帮助金融机构减少风险,优化贷款审批流程。 | 数据分析,金融风险管理 | 数值型数据,分类数据 | 金融风控,贷款审批,信用评估 |
在该案例中对贷款数据进行清洗,去除无用的字段和高度重复的特征。这一步骤的目标是确保数据集的有效性,保留对模型训练有帮助的特征。通过对类别数据的编码和数值化,将数据转换为机器学习模型可以使用的格式。选择逻辑回归和随机森林模型进行训练,并使用交叉验证来评估模型的性能。通过混淆矩阵计算出模型的真正率(TPR)和假正率(FPR),为金融机构提供有力的决策依据,从而帮助评估贷款违约的风险,并进一步优化贷款审批流程。
数据详解
该数据集提供了贷款信息的详细分布情况。数据包括多个字段,例如贷款金额、融资金额、投资金额、贷款期限、利率、还款金额、贷款级别、借款人工作信息等。这些字段可以反映借款人的贷款状况、偿还能力以及贷款的风险。贷款金额和融资金额的分布较为均匀,且数据中涉及的贷款金额范围从500元到35000元不等。贷款利率和贷款期限信息也较为详细,提供了不同贷款条件下的分布情况。此外,借款人信息(如就业职位和工作年限)也在数据集中有所体现,帮助分析借款人背景对贷款条件的潜在影响。
字段名称 | 类型/范围 | 描述信息 |
---|---|---|
loan_amnt | 500.00 - 35000.00 | 贷款金额,范围从500元到35000元,表示借款人所申请的贷款数额。 |
funded_amnt | 500.00 - 35000.00 | 融资金额,表示实际为借款人提供的贷款金额,通常与贷款金额相近。 |
funded_amnt_inv | 0.00 - 35000.00 | 投资金额,显示了投资者实际投资的金额。 |
term | 36 months, 60 months | 贷款期限,主要分为36个月和60个月两种,反映了贷款的偿还时间。 |
int_rate | 10.99% - 11.49% | 贷款利率,提供了不同贷款利率的数据,说明贷款利率的分布。 |
installment | 15.67 - 1310.71 | 每期偿还金额,表示借款人每月需要偿还的金额,数据范围从15.67元到1310.71元。 |
grade | A, B, C, D, E, F, G | 贷款评级,分为A到G等级,反映了借款人的信用状况。 |
sub_grade | A1 - G5 | 贷款子级别,详细划分了每个贷款的子级别,用于更精细的信用评估。 |
emp_title | 各种工作职位 | 借款人职称,表示借款人的职位,反映其收入水平及稳定性。 |
emp_length | < 1 year, 10+ years | 工作年限,记录了借款人的工作年限,通常用于评估借款人的稳定性。 |
本数据集详细展示了贷款相关的各类信息,包括贷款金额、融资金额、贷款期限、利率以及借款人的信用等级等。数据中各个字段的取值范围和分布揭示了贷款产品的特性与借款人之间的关系。例如,贷款金额、融资金额和投资金额都有明确的数额区间,帮助分析不同贷款产品的受欢迎程度和分布情况。贷款期限的选择则展示了借款人在不同偿还周期上的偏好。利率字段提供了各个贷款利率的具体信息,利率的不同也可能反映借款人的信用风险。进一步的分析可以结合借款人的工作背景与贷款的各项特征,揭示借款人背景与贷款成功之间的潜在联系。
案例分析
数据清洗与预处理
在开始任何数据分析之前,确保数据清洗是非常重要的。代码的第一部分处理了数据集中的无效字段和重复数据。首先,读取了包含贷款数据的CSV文件,并删除了那些缺少大量数据的列。这是通过设置thresh=half_count
来实现的,即保留至少有一半非缺失值的列。然后去除了desc
和url
等对后续分析无关的列。最后,将处理过的数据保存为新的CSV文件。
import pandas as pd
loans_2007 = pd.read_csv('LoanStats3a.csv', skiprows=1)
half_count = len(loans_2007) / 2
loans_2007 = loans_2007.dropna(thresh=half_count, axis=1)
loans_2007 = loans_2007.drop(['desc', 'url'], axis=1)
loans_2007.to_csv('loans_2007.csv', index=False)
清理无关字段与高度重复特征
进一步的数据清理阶段去除了与贷款信息无关的字段,包括id
、member_id
、grade
等。这些字段对预测模型没有帮助,因此从数据集中删除了它们。通过查看loan_status
字段的分布,保留了两个最重要的贷款状态类别:“Fully Paid”和“Charged Off”。同时,将loan_status
字段中的值映射为1(已还款)和0(已违约)以便于后续的建模。
loans_2007 = loans_2007.drop(["id", "member_id", "funded_amnt", "funded_amnt_inv", "grade", "sub_grade", "emp_title", "issue_d"], axis=1)
loans_2007 = loans_2007.drop(["zip_code", "out_prncp", "out_prncp_inv", "total_pymnt", "total_pymnt_inv", "total_rec_prncp"], axis=1)
loans_2007 = loans_2007.drop(["total_rec_int", "total_rec_late_fee", "recoveries", "collection_recovery_fee", "last_pymnt_d", "last_pymnt_amnt"], axis=1)
print(loans_2007.iloc[0])
print(loans_2007.shape[1])print(loans_2007['loan_status'].value_counts())loans_2007 = loans_2007[(loans_2007['loan_status'] == "Fully Paid") | (loans_2007['loan_status'] == "Charged Off")]status_replace = {"loan_status": {"Fully Paid": 1,"Charged Off": 0,}
}
loans_2007 = loans_2007.replace(status_replace)
去除唯一值列
在这一部分,代码进一步清理了那些只包含唯一值的列,因为这些列对分析没有实际意义。例如,loan_status
本身就被映射成了1和0,其它字段如member_id
可能含有相同值,删除这些列减少了数据集的复杂性。
orig_columns = loans_2007.columns
drop_columns = []
for col in orig_columns:col_series = loans_2007[col].dropna().unique()if len(col_series) == 1:drop_columns.append(col)
loans_2007 = loans_2007.drop(drop_columns, axis=1)
print(drop_columns)
print(loans_2007.shape)
loans_2007.to_csv('filtered_loans_2007.csv', index=False)
处理缺失值与数据类型
数据预处理的下一步是处理缺失值。代码通过删除包含缺失值的行,确保数据的完整性,并输出了每一列的缺失值数量。之后,针对特定的列,如pub_rec_bankruptcies
,进行删除处理,以确保模型不会受到不必要的干扰。
loans = pd.read_csv('filtered_loans_2007.csv')
null_counts = loans.isnull().sum()
print(null_counts)loans = loans.drop("pub_rec_bankruptcies", axis=1)
loans = loans.dropna(axis=0)
print(loans.dtypes.value_counts())
类别变量的映射与处理
处理了数据集中的类别变量。通过查看字段home_ownership
、verification_status
等的取值,代码将这些类别变量转换为数值型变量,方便机器学习模型的处理。例如,emp_length
字段的不同就业年限被映射为整数值。对于int_rate
和revol_util
等字段,剥去了百分号并转换为浮动类型。
mapping_dict = {"emp_length": {"10+ years": 10,"9 years": 9,"8 years": 8,"7 years": 7,"6 years": 6,"5 years": 5,"4 years": 4,"3 years": 3,"2 years": 2,"1 year": 1,"< 1 year": 0,"n/a": 0}
}
loans = loans.drop(["last_credit_pull_d", "earliest_cr_line", "addr_state", "title"], axis=1)
loans["int_rate"] = loans["int_rate"].str.rstrip("%").astype("float")
loans["revol_util"] = loans["revol_util"].str.rstrip("%").astype("float")
loans = loans.replace(mapping_dict)
创建虚拟变量与处理类别特征
代码对类别特征进行了独热编码,将home_ownership
、verification_status
等列转换为虚拟变量。通过将这些虚拟变量拼接回数据集,保证了数据集的结构可以被机器学习模型有效处理。
cat_columns = ["home_ownership", "verification_status", "emp_length", "purpose", "term"]
dummy_df = pd.get_dummies(loans[cat_columns])
loans = pd.concat([loans, dummy_df], axis=1)
loans = loans.drop(cat_columns, axis=1)
loans = loans.drop("pymnt_plan", axis=1)
保存清洗后的数据
经过一系列的清理和转换后,最终的处理结果被保存为cleaned_loans2007.csv
文件,这为后续的建模步骤做了充分的准备。
loans.to_csv('cleaned_loans2007.csv', index=False)
机器学习建模
通过使用逻辑回归模型,代码对处理后的数据进行了训练和预测。通过调用LogisticRegression
,使用了交叉验证(cross_val_predict
)来评估模型的效果。在这里,代码计算了假阳性、真阳性、假阴性和真阴性,并根据这些结果计算了模型的真正率(True Positive Rate, TPR)和假正率(False Positive Rate, FPR)。
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_predict
lr = LogisticRegression(solver='liblinear',class_weight="balanced")
predictions = cross_val_predict(lr, features, target, cv=5)
predictions = pd.Series(predictions)# False positives.
fp_filter = (predictions == 1) & (loans["loan_status"] == 0)
fp = len(predictions[fp_filter])# True positives.
tp_filter = (predictions == 1) & (loans["loan_status"] == 1)
tp = len(predictions[tp_filter])# False negatives.
fn_filter = (predictions == 0) & (loans["loan_status"] == 1)
fn = len(predictions[fn_filter])# True negatives
tn_filter = (predictions == 0) & (loans["loan_status"] == 0)
tn = len(predictions[tn_filter])# Rates
tpr = tp / float((tp + fn))
fpr = fp / float((fp + tn))print(tpr)
print(fpr)
print(predictions[:20])
通过使用多种方法(包括逻辑回归和随机森林),模型计算了不同的预测结果,并对不同的机器学习算法进行了性能评估。通过交叉验证和调整类权重,模型的性能得到了进一步的优化。
总结
通过对贷款数据集的详细分析与处理,成功构建了预测贷款偿还状态的机器学习模型。该过程涵盖了数据清洗、特征选择、类别变量处理及模型训练等多个步骤。通过逻辑回归和随机森林等方法对模型进行了训练,并通过交叉验证与混淆矩阵评估其性能。结果显示,清洗后的数据及适当选择的特征显著提升了模型的预测能力。
未来的工作可以在此基础上进一步引入更复杂的算法,如集成学习和深度学习模型,以提升预测精度。数据增强技术和更精细的特征工程也是潜在的优化方向,能够帮助模型更好地适应各种贷款偿还模式和金融风险管理需求。