版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Python数据分析与实践12025/11/27第13章金融风险数据分析项目实践本章学习目标:了解数据分析项目的基本步骤学会观察数据和预处理数据探索和可视化选择和训练模型模型调参和评估32025/11/2713.1实践项目简介
金融借贷是指金融机构或个人向借款人提供资金或物品的行为,借款人需在未来偿还借款本金和利息。金融借贷是现代经济的重要组成部分,在个人消费、企业生产经营、政府投资等方面发挥着重要作用。
本章基于一家叫做LendingClub的网络信贷公司的用户借贷金融数据,分析借款人信用风险的相关影响因素。LendingClub是全球最大的P2P借贷平台,总部位于美国加利福尼亚州旧金山。本案例提供的借款人借贷数据共计887379条记录,包含借款人个人信息、贷款目的、贷款总额、贷款利率、月供、贷款状态等共74个特征。后续我们将对这些特征进行筛选和预处理。
42025/11/2713.2打开与查看数据
本章的数据文件名称为loan.csv,文件格式为CSV,编码格式为UTF-8。
首先需要为本案例创建一个工作区目录,例如loan_lc,用于存放python代码和数据,另外请在目标python环境中下载如下python模块:NumPy、Pandas、Matplotlib以及Scikit-Learn。
本章以JupyterNotebook作为Python开发环境,读者也可选择其他开发环境,不影响代码运行。
将下载下来的原始数据loan.csv复制到项目工作区目录loan_lc文件夹下,使用pandas加载数据:
importpandasaspd
LOAN_DATA_PATH="loan.csv"loan_data=pd.read_csv(LOAN_DATA_PATH)52025/11/27使用DataFrame的head()方法查看数据示例:13.2打开与查看数据
loan_data.head(
)
由于head方法只能显示数据集的前10、后10列属性(如上图所示),而原始数据集有74个属性,因此该方法并不能很好地展示数据特征和详情62025/11/27我们可使用info()方法查看数据字段详情,该方法将列出数据集中所有字段的名称、非空数据量和数据类型。13.2打开与查看数据loan_(
)
由于该数据集共有887379条数据,因此如果某个字段的“Non-NullCount”值为887379,则表示该字段没有空值,否则说明该字段的某些记录存在空值,用887379减去“Non-NullCount”值即为该字段空值的数量。在所有74个字段中,有34个字段没有空值,占比不到一半,而其余40个字段或多或少存在空值,之后需要进一步处理。
72025/11/2713.3数据探索与可视化
首先对数据各个属性特征进行描述性统计分析,通过使用各种统计指标和图形来呈现数据的特征和模式,从而对数据进行初步理解和分析
。通过value_counts()方法查看感兴趣的属性,尤其是分类变量(Nominal)属性,从而了解该属性有哪些可选值以及不同属性取值在记录数量上的分布。通过如下代码查看数据集中loan_status(贷款状态)有哪些取值:
loan_data['loan_status'].value_counts()82025/11/2713.3数据探索与可视化
对于数值型属性,我们使用describe()方法获取其基础统计描述信息,如均值、标准差、中位数、最大最小值等。以贷款利率为例:
loan_data['int_rate'].describe()可以看到该公司提供的借贷产品其利率在5.32%~29%之间,均值和中位数相近大约为13%,可知数据中影响均值的极值并不多,由Q1、Q3可知大多数人所申请到的贷款利率应在10%~16%之间浮动。
92025/11/27另一个值得关注的信息是贷款额度,即某申请人在该次借款申请中所获得的贷款总金额:可见该公司所提供的最大贷款额度不超过3.5万美元,大部分申请人获批了1万多元的信用贷款。由于均值比中位数高了1700,可见更多的人申请到了相对大额贷款,拉高了平均值。读者可使用describe()方法自行查看其他数值型属性的描述统计特征。
13.3数据探索与可视化
loan_data['funded_amnt'].describe()102025/11/27分别画出申请贷款额度(loan_amnt)和批准贷款额度(funded_amnt)的直方图,直方图能够较好地展示数据的分布,查看分布特征:13.3数据探索与可视化
importmatplotlib.pyplotaspltloan_data[["loan_amnt","funded_amnt"]].hist(bins=50,figsize=(15,5))plt.show()两张直方图在分布上几乎一致,意味着借款人只要被贷款公司审核通过,基本都能按申请额度足额获得资助金额。另外,10000、12000、15000、20000、35000左右的金额是最常被借款人申请的额度。
112025/11/27接下来再按年度特征来考察公司发放的贷款总额。原数据中issue_d字段表示贷款发放的时间,精确到月份,格式为“mmm-yyyy”例如2015年10月开始发放的贷款,记为“Oct-2015”,我们只需要其中的年份部分,因此可以先将该日期字符转换为日期类型,再提取其中的年份信息:
13.3数据探索与可视化
loan_data['year']=pd.to_datetime(loan_data['issue_d']).dt.year这样我们在原始数据中新增了一个字段“year”,表示该贷款的年份。下列代码使用柱状图查看2007~2015年各个年份的贷款总记录数:
loan_counts_by_year=loan_data.groupby("year").size()loan_counts_by_year=loan_counts_by_year.sort_index()plt.bar(loan_counts_by_year.index,loan_counts_by_year.values)plt.xlabel("年份")plt.ylabel("贷款总记录数")plt.xticks(year_counts.index,year_counts.index)plt.show()122025/11/2713.3数据探索与可视化
代码中groupby()方法可以对方法参数的指定字段进行统计,得到一个DataFrameGroupBy对象,再调用该对象的size()方法,可以统计各个年份的记录数量,返回一个Series对象,该对象的index为年份,value为某年份的记录数量。最后使用matplotlib库pyplot对象的bar()方法创建柱状图。如图15.2所示,从2007年开始,贷款总数每一年都以翻倍的速度递增,从2007年的不到1000笔,到2015年已经增至超过40万笔。
图15.2各年贷款记录总数对比132025/11/27通过图表查看贷款金额:
13.3数据探索与可视化
average_loan_amnt=loan_data.groupby("year")["loan_amnt"].mean()average_funded_amnt=loan_data.groupby("year")["funded_amnt"].mean()average_loan_amnt=average_loan_amnt.sort_index()average_funded_amnt=average_funded_amnt.sort_index()plt.bar(average_loan_amnt.index,average_loan_amnt.values,width=0.4,label="平均申请贷款金额")plt.bar(average_funded_amnt.index+0.4,average_funded_amnt.values,width=0.4,label="平均发放贷款金额")plt.xlabel("年份")plt.ylabel("贷款金额")plt.xticks(average_loan_amnt.index+0.2,
average_loan_amnt.index)plt.legend()plt.show()图15.3各年份平均申请贷款金额与平均发放贷款金额对比142025/11/2713.4数据准备
原数据中有不少日期类型的属性,需要首先予以处理。这里将其转化为年份或月份表示的整型(其中issue_d在可视化一节中已经处理过)。对于日期属性中存在的空缺值,使用最大频率值予以填充:
loan_data['last_pymnt_d']=pd.to_datetime(loan_data['last_pymnt_d'].fillna('2016-01-01')).apply(lambdax:int(x.strftime('%m')))loan_data['last_credit_pull_d']=pd.to_datetime(loan_data['last_credit_pull_d'].fillna("2016-01-01")).apply(lambdax:int(x.strftime('%m')))loan_data['earliest_cr_line']=pd.to_datetime(loan_data['earliest_cr_line'].fillna('2001-08-01')).apply(lambdax:int(x.strftime('%m')))152025/11/27对于分类变量属性,如果只有两个可选值,那么可以采用标签编码,如果有两个以上的可选值,则应采用独热编码(one-hot)。13.4数据准备fromsklearnimportpreprocessingforcolinloan_data:ifloan_data[col].dtype=='object'andlen(list(loan_data[col].unique()))<=2:le=preprocessing.LabelEncoder()loan_data[col]=le.fit_transform(loan_data[col])经过独热编码后,整个数据集的特征属性数量会大大增加。如有必要,可使用主成分分析法(PCA)做降维操作。工作年限(emp_length)特征对判断后续分析有较大帮助,数据中其缺失值占比约5%,这里对该特征进行一些处理。
首先考虑到不填写工作年限的人大多未工作,因此可以认为该字段的值为0,使用0值对缺失值进行填补:
loan_data['emp_length'].fillna(value=0,inplace=True)162025/11/27
其次,当前emp_length字段的取值为字符串:
13.4数据准备emp_length
10+years291569
2years78870
<1year70605
3years70026
1year57095
5years55704
4years52529
7years44594
8years43955
6years42950
9years34657
Name:count,dtype:int64使用正则表达式将文字“years”去除,只保留数字,同时将小于1年的年限与1年进行合并,即工作1年及以内的设为“1”,未工作过的设为“0”:
172025/11/27loan_data['emp_length'].replace(to_replace='[^0-9]+',value='',inplace=True,regex=True)loan_data['emp_length'].value_counts().sort_values(ascending=False).plot(kind='bar',figsize=(8,5))13.4数据准备图15.4不同工作年限的记录总数图15.4将各个工作年限的记录数画成柱状图展示,可以看到,工作10年以上的记录数量远高于其他年限,这是因为该属性为“10年以上”,包括11年、12年等多个年份,因此数据量理应远高于其他单一年份。
182025/11/2713.4数据准备最终剩下816722条记录,这些记录中已经不存在缺失值。将借款状态分为两大类:“正常借贷”与“不良借贷”,如下是要分类的目标变量:
bad_loan=['ChargedOff','Late(31-120days)','InGracePeriod','Late(16-30days)','Default','Doesnotmeetthecreditpolicy.Status:ChargedOff']target_list=[1ifiinbad_loanelse0foriinloan_data['loan_status']]
loan_data['TARGET']=target_list其他具有缺失值的记录考虑直接删除:
loan_data.dropna(inplace=True)其中“不良借贷”包括如15.1.1节所述的6种风险状态,将其设为1,其余正常状态为“正常借贷”,将其设为0,从而构建一个新的字段,命名为“TARGET”。创建TARGET属性后,loan_status属性可以直接予以删除。
192025/11/2713.5预测建模
分别使用人工神经网络(ANN)、XGBoost和随机森林三种机器学习算法对借贷状态进行分类,尝试预测其信用风险,具体来讲预测在确定的某种特征下,其TARGET属性为0(正常借贷)还是为1(不良借贷)。
为更好地评估算法,将全部数据拆分为训练集和测试集,训练集用于模型训练,测试集用户模型检验。训练集与测试集的比例为4:1。
fromsklearn.model_selectionimporttrain_test_splitX_train,X_test,y_train,y_test=
train_test_split
(loan_data.drop
(‘TARGET’,axis=1),
loan_data['TARGET'],test_size=0.2)对特征进行归一化处理,采用“最小最大缩放”法将各个特征值缩放至0~1的区间范围:
fromsklearn.preprocessingimportMinMaxScalerscaler=MinMaxScaler()scaler.fit(X_train)X=scaler.transform(X_train)
y=y_train.values
13.5.1基于人工神经网络的借贷分类模型
人工神经网络(ArtificialNeuralNetwork,简称ANN)是受生物神经网络结构启发而设计的一种计算模型,用于模拟人脑的神经网络结构和功能,以解决复杂的模式识别和数据处理问题。ANN由大量的人工神经元(或称为节点)组成,这些神经元按照不同的层次和连接方式构成网络。每个神经元接收来自其他神经元的输入,通过一系列加权和非线性变换后产生输出,然后传递给下一层神经元或者作为整个网络的输出。人工神经网络通常由三种层次的神经元组成:输入层(InputLayer):接受外部输入数据,并将数据传递给网络的隐藏层。隐藏层(HiddenLayer):位于输入层和输出层之间,负责对输入数据进行加权和变换,提取出数据中的特征。输出层(OutputLayer):将隐藏层传递过来的特征经过进一步的加权和变换后产生网络的输出结果。212025/11/27这里采用scikit-learn库提供的多层感知器(MultilayerPerceptron,MLP)进行模型训练。多层感知器是一种较为简单和基础的前馈型神经网络模型,由一个或多个隐藏层(中间层)组成,每个隐藏层包含多个神经元(节点),以及一个输入层和一个输出层。目前常见的卷积神经网络(CNN)和循环神经网络(RNN)都是MLP的改进和衍生模型。
13.5.1基于人工神经网络的借贷分类模型
fromsklearn.neural_networkimportMLPClassifierfromsklearn.model_selectionimportcross_val_scoreimportnumpyasnpfromsklearn.metricsimportclassification_reportcls=MLPClassifier(random_state=1,max_iter=300).fit(X,y)print(classification_report(y,cls.predict(X)))scores=cross_val_score(cls,X,y,scoring="accuracy",cv=10)print("平均准确率:\t{0:.4f}".format(np.mean(scores)))
print("准确率标准差:\t\t{0:.4f}".format(np.std(scores)))13.5.1基于人工神经网络的借贷分类模型
MLPClassifier具有多个可调参数,可以通过交叉验证等方法进行调参。下面是一些常用的调参方法和参数:隐藏层大小(hidden_layer_sizes):指定隐藏层的大小,可以是一个整数表示隐藏层中的节点数量,也可以是一个元组表示每个隐藏层中节点的数量。通常需要根据问题的复杂度和数据集的特征进行调整。激活函数(activation):指定隐藏层和输出层的激活函数,常用的包括"relu"、"logistic"、"tanh"等。默认是"relu"。优化器(solver):指定用于优化权重的算法,常用的包括"adam"、"lbfgs"、"sgd"等。默认是"adam"。学习率(learning_rate):控制权重更新的步长,可以是常数、自适应学习率或衰减学习率。具体取决于所选的优化器。正则化参数(alpha):控制模型的正则化程度,防止过拟合。批量大小(batch_size):指定用于权重更新的样本批量大小。最大迭代次数(max_iter):指定训练过程中的最大迭代次数。早停(early_stopping):控制是否使用早停技术来提前停止训练,防止过拟合。2025/11/27#定义参数网格param_grid={'hidden_layer_sizes':[(10,),(50,),(100,)],'activation':['relu','tanh'],‘solver’:[‘adam’,‘sgd‘],}#使用GridSearchCV进行参数搜索grid_search=GridSearchCV(cls,param_grid,cv=3)grid_search.fit(X,y)#输出最佳参数和最佳得分print("BestParameters:",grid_search.best_params_)
print("BestScore:",grid_search.best_score_)
13.5.1基于人工神经网络的借贷分类模型
下面代码以GridSearchCV对该模型进行一个简单的调参:上述代码对三个参数进行了网格调试:hidden_layer_sizes、activation、solver。网格调试是Scikit-learn库中的一个模型评估工具,用于系统地搜索最佳模型参数的组合。GridSearchCV通过在参数网格中组合不同的参数值,然后使用交叉验证来评估每种参数组合的性能,最终找到最佳的参数组合。2025/11/27242025/11/27XGBoost(eXtremeGradientBoosting)是一种基于梯度提升树(GradientBoostingTree)的机器学习算法,其核心在于集成学习中的提升方法。由于scikit-learn库中没有包含XGBoost模型,读者需要在线下载XGBoost库,如果使用conda包管理里,可以通过如下命令进行下载安装:13.5.2基于XGBoost的借贷分类模型
condainstallpy-xgboost安装完毕后即可在代码中使用import方式导入xgboost包fromsklearn.model_selectionimportcross_val_scoreimportxgboostasxgbimportnumpyasnpfromsklearn.metricsimportclassification_reportcls=xgb.XGBClassifier().fit(X,y)
print(classification_report(y,cls.predict(X)))
scores=cross_val_score(cls,X,y,scoring="accuracy",cv=10)print("平均准确率:\t{0:.4f}".format(np.mean(scores)))
print("准确率标准差:\t\t{0:.4f}".format(np.std(scores)))
13.5.2基于XGBoost的借贷分类模型
XGBoost同样具有若干可调参数用于提高模型的性能和泛化能力。以下是一些常用的XGBoost调参方法和参数:树的数量(n_estimators):指定要构建的决策树的数量。增加树的数量通常可以提高模型的性能,但也会增加训练时间和内存消耗。树的最大深度(max_depth):指定决策树的最大深度。增加深度可以增加模型的复杂度,但也可能导致过拟合。学习率(learning_rate):控制每个树的贡献,降低学习率可以使模型更加稳定,但需要增加树的数量来保持模型的性能。列采样比例(colsample_bytree):指定每棵树用于训练的特征的比例。这可以帮助减少过拟合,提高模型的泛化能力。行采样比例(subsample):指定每棵树用于训练的样本的比例。与列采样类似,行采样也可以帮助减少过拟合。正则化参数(reg_alpha、reg_lambda):控制模型的正则化程度,帮助防止过拟合。早停策略(early_stopping_rounds):指定在验证集上连续多少轮迭代中没有改善时停止训练,以防止过拟合。特征重要性评估(importance_type):指定计算特征重要性的方法,包括"gain"、"weight"、"cover"等。2025/11/2713.5.2基于XGBoost的借贷分类模型
#定义参数网格param_grid={'n_estimators':[100,200,300],'max_depth':[3,5,7],'learning_rate':[0.1,0.01,0.001],}
#使用GridSearchCV进行参数搜索grid_search=GridSearchCV(cls,param_grid,cv=3)grid_search.fit(X,y)
#输出最佳参数和最佳得分print("BestParameters:",grid_search.best_params_)print("BestScore:",grid_search.best_score_)读者可以尝试使用前一节介绍的网格调试GridSearchCV去寻找最佳参数,一个简单的调参示例如下:
2025/11/2713.5.3基于随机森林的借贷分类模型
随机森林模型常用的超参数如下:树的数量(n_estimators):指定随机森林中树的数量。通常增加树的数量可以提高模型的性能,但也会增加训练时间。树的最大深度(max_depth):指定树的最大深度,控制树的复杂度。较大的深度可能会导致过拟合,较小的深度可能会导致欠拟合。节点最少样本数(min_samples_split):指定拆分内部节点所需的最小样本数。控制了树的生长,可以防止过拟合。叶子节点最少样本数(min_samples_leaf):指定叶子节点所需的最小样本数。控制了叶子节点的数量,可以防止过拟合。特征选择策略(max_features):指定用于拆分节点的特征数或比例。可以是整数、浮点数或字符串。常用的选项包括"auto"(sqrt(n_features))、"sqrt"(sqrt(n_features))、"log2"(log
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年常德烟机校招专属考试题库及参考答案
- 2021中信金融业务面试踩坑避坑指南+真题及答案
- 2024黑职院综评面试备考指南 含高频考题及标准答案
- 2026年六下 利率 测试题及答案
- 2026年中国名著情商测试题及答案
- 2025年CFA二级《投资组合管理》新考纲专属模拟题无冗余考点
- 2024济宁中考英语真题及答案附新题型专项解析
- 2023智联招聘职业胜任力测试题及高分适配答案
- 员工聘用协议书
- 室内游乐场所复工申请书
- 商务礼仪之服装搭配
- 电梯机房钻孔协议书范本
- 腰椎疑难病例讨论
- 少儿航空科普教育
- 法院司法礼仪培训课件
- T/CEPPEA 5028-2023陆上风力发电机组预应力预制混凝土塔筒施工与质量验收规范
- 语音主播签约合同协议
- 不良资产处置试题及答案
- 智慧树知到《大学生心理健康》(吉林大学)见面课、章节测试、期末考试答案
- 聚羧酸减水剂工艺流程
- 离心泵检修培训
评论
0/150
提交评论