🤵♂️ 个人主页:@艾派森的个人主页
✍🏻作者简介:Python学习者
🐋 希望大家多多支持,我们一起进步!😄
如果文章对你有帮助的话,
欢迎评论 💬点赞👍🏻 收藏 📂加关注+
喜欢大数据分析项目的小伙伴,希望可以多多支持该系列的其他文章
大数据分析案例-基于随机森林算法预测人类预期寿命 |
大数据分析案例-基于随机森林算法的商品评价情感分析 |
大数据分析案例-用RFM模型对客户价值分析(聚类) |
大数据分析案例-对电信客户流失分析预警预测 |
大数据分析案例-基于随机森林模型对北京房价进行预测 |
大数据分析案例-基于RFM模型对电商客户价值分析 |
大数据分析案例-基于逻辑回归算法构建垃圾邮件分类器模型 |
大数据分析案例-基于决策树算法构建员工离职预测模型 |
大数据分析案例-基于KNN算法对茅台股票进行预测 |
大数据分析案例-基于多元线性回归算法构建广告投放收益模型 |
大数据分案例-基于随机森林算法构建返乡人群预测模型 |
大数据分析案例-基于决策树算法构建金融反欺诈分类模型 |
1.项目背景
伴随着我国经济的高速发展,我国信用卡的发卡规模逐年递增,使用者的数量逐年上升,信用违约的案例不断增多,违约规模进一步扩大,这将给银行带来风险。研究显示,截至2018年末,信用卡逾期半年未偿的信贷总额为788.61亿元,同比增长了18.92%。因此,在保持银行信用卡业务增长的同时,有效的利用信用卡用户数据,提前识别出潜在的风险个体,对风险进行预判,控制违约的增长,给风险管理控制者提供进一步决策的依据,是银行关注的重点。
信用卡违约预测问题是指根据银行在授信过程中收集到的信用卡用户信息数据和用户在使用中不断产生的消费账单信息,挖掘出重要特征,预测出哪些持卡人可能会逾期还款或者不还款,是提前识别出潜在风险个体的一种有效措施。
对信用卡违约问题进行预测可以识别潜在的破产用户,并针对不同的信用卡用户制定适当的政策。对于提前还款的用户,提高其信用额度或给予相应的信用积分奖励,而对逾期未还款的用户,降低其信用度等级和相应的信用额度。通过相应的政策可以预防逾期还款或者不还款的情况发生,加强违约风险的管理,降低风险并预估损失,从而使银行信用卡业务预期收益最大化,对信用卡核心竞争力的提高以及违约风险管理体系的完善具有重要意义。
2.项目简介
2.1项目说明
本项目旨在使用机器学习等算法构建信用卡违约预测模型,主要应用在金融相关领域,根据用户以往的行为数据来预测是否会违约,有利于商业银行防范和化解信用卡风险,完善信用卡违约风险管理工作。
2.2数据说明
本案例使用的是来自UCI网站上的信用卡客户数据,包含了2005年4月到2005年9月客户的人口统计特征、信用数据、历史还款、账单等信息。目的是对客户下个月是否违约做出预测。原始数据格式是csv
,一共有24个列。具体字段信息如下:
变量名称 | 含义 |
LIMIT_BAL | 可透支金额 |
SEX | 性别:男1,女2 |
EDUCATION | 教育程度:研究生1,本科2,高中3,其他0 |
MARRIAGE | 婚姻状况:已婚1,单身2,其他0 |
AGE | 年龄 |
PAY_0 | 2005年9月还款情况 |
PAY_2 | 2005年8月还款情况 |
PAY_3 | 2005年7月还款情况 |
PAY_4 | 2005年6月还款情况 |
PAY_5 | 2005年5月还款情况 |
PAY_6 | 2005年4月还款情况 |
BILL_AMT1 | 2005年9月账单金额 |
BILL_AMT2 | 2005年8月账单金额 |
BILL_AMT3 | 2005年7月账单金额 |
BILL_AMT4 | 2005年6月账单金额 |
BILL_AMT5 | 2005年5月账单金额 |
BILL_AMT6 | 2005年4月账单金额 |
PAY_AMT1 | 2005年9月还款金额 |
PAY_AMT2 | 2005年8月还款金额 |
PAY_AMT3 | 2005年7月还款金额 |
PAY_AMT4 | 2005年6月还款金额 |
PAY_AMT5 | 2005年5月还款金额 |
PAY_AMT6 | 2005年4月还款金额 |
payment_flag | 下个月是否违约:违约1,守约0 |
2.3技术工具
Python版本:3.9
代码编辑器:jupyter notebook
3.算法原理
决策树( Decision Tree) 又称为判定树,是数据挖掘技术中的一种重要的分类与回归方法,它是一种以树结构(包括二叉树和多叉树)形式来表达的预测分析模型。其每个非叶节点表示一个特征属性上的测试,每个分支代表这个特征属性在某个值域上的输出,而每个叶节点存放一个类别。一般,一棵决策树包含一个根节点,若干个内部结点和若干个叶结点。叶结点对应于决策结果,其他每个结点对应于一个属性测试。每个结点包含的样本集合根据属性测试的结果划分到子结点中,根结点包含样本全集,从根结点到每个叶结点的路径对应了一个判定的测试序列。决策树学习的目的是产生一棵泛化能力强,即处理未见示例强的决策树。使用决策树进行决策的过程就是从根节点开始,测试待分类项中相应的特征属性,并按照其值选择输出分支,直到到达叶子节点,将叶子节点存放的类别作为决策结果。
决策树的构建
特征选择:选取有较强分类能力的特征。
决策树生成:典型的算法有 ID3 和 C4.5, 它们生成决策树过程相似, ID3 是采用信息增益作为特征选择度量, 而 C4.5 采用信息增益比率。
决策树剪枝:剪枝原因是决策树生成算法生成的树对训练数据的预测很准确, 但是对于未知数据分类很差, 这就产生了过拟合的现象。涉及算法有CART算法。
决策树的划分选择
熵:物理意义是体系混乱程度的度量。
信息熵:表示事物不确定性的度量标准,可以根据数学中的概率计算,出现的概率就大,出现的机会就多,不确定性就小(信息熵小)。
决策树的剪枝
剪枝:顾名思义就是给决策树 "去掉" 一些判断分支,同时在剩下的树结构下仍然能得到不错的结果。之所以进行剪枝,是为了防止或减少 "过拟合现象" 的发生,是决策树具有更好的泛化能力。
具体做法:去掉过于细分的叶节点,使其回退到父节点,甚至更高的节点,然后将父节点或更高的叶节点改为新的叶节点。
剪枝的两种方法:
预剪枝:在决策树构造时就进行剪枝。在决策树构造过程中,对节点进行评估,如果对其划分并不能再验证集中提高准确性,那么该节点就不要继续王下划分。这时就会把当前节点作为叶节点。
后剪枝:在生成决策树之后再剪枝。通常会从决策树的叶节点开始,逐层向上对每个节点进行评估。如果剪掉该节点,带来的验证集中准确性差别不大或有明显提升,则可以对它进行剪枝,用叶子节点来代填该节点。
注意:决策树的生成只考虑局部最优,相对地,决策树的剪枝则考虑全局最优。
4.项目实施步骤
4.1理解数据
首先使用pandas读取信用卡违约数据,并查看前五行
查看数据大小发现原始数据共有20983行,24列
查看数据基本信息
从结果中我们可以看出各个变量的数否有缺失值以及数据类型。
查看数据描述性统计
从描述性统计结果中,我们可以得到各个变量的总数、均值、方差、最大最小值、四分位数等信息。
4.2数据清洗
在这里我们主要是对原始数据中的缺失数据和重复数据进行删除处理
4.3探索性数据分析
首先导入用到的第三方库
4.3.1违约比例
从图中,我们可以发现该数据违约的比例远远小于守约的比例,数据严重不平衡,后期需要进行处理。
4.3.2可透支金额的分布
从图中我们发现可透支金额主要集中在0~200000。
4.3.3性别对于可透支金额的影响
从图中可以发现在守约的用户群体中,男性群体的可透支金额略微高于女性;而在违约群体中,女性的可透支金额略微高于男性。
4.3.4受教育程度对于可透支金额的影响
从图中可以看出无论是违约还是守约群体,可透支金额大小:研究生>本科生>高中,可以发现学历越高,可透支金额越大,说明学历对于可透支金额的影响较大。
4.3.5婚姻状况对于可透支金额的影响
从图中可看出,无论是违约还是守约群体,都有共同的趋势:1>2>0,即已婚>单身>其他,说明婚姻状态对于可透支金额有显著影响。
4.3.6年龄与可透支金额的关系
从散点图看出,年龄与可透支金额似乎没有相关关系。
4.3.7各变量之间的相关系数
4.4特征工程
前面我们通过可视化发现数据存在不平衡的情况,所以在这里我们进行过采样进行处理
进过处理后,我们发现违约和守约数据已经平衡了。
接着我们对原始数据集进行拆分处理,其中测试集比例为0.2
4.5模型构建
构建决策树模型并打印其准确率
构建逻辑回归模型并打印其准确率
构建xgboost模型并打印其准确率
4.6模型评估
前面我们构建了三个模型,其中决策树模型的准确率最高,所以我们使用决策树模型作为最后的模型,这里我们使用混淆矩阵、分类报告、ROC曲线作为模型评估结果。
4.7模型预测
这里我们使用决策树模型进行预测,并查看真实值和预测值结果,发现十个预测结果中有两个预测错误,模型效果还不错,但还有待提高。
5.实验总结
本次实验通过探索性分析以及使用决策树构建信用卡违约模型,得出以下结论:
1.可透支金额主要集中在0~200000之间。
2.性别对于可透支金额的影响较小。
3.受教育程度和婚姻状况对可透支金额的影响较大。
4.决策树模型的准确率为0.88,模型效果还有待提高。
心得与体会:
通过这次Python项目实战,我学到了许多新的知识,这是一个让我把书本上的理论知识运用于实践中的好机会。原先,学的时候感叹学的资料太难懂,此刻想来,有些其实并不难,关键在于理解。
在这次实战中还锻炼了我其他方面的潜力,提高了我的综合素质。首先,它锻炼了我做项目的潜力,提高了独立思考问题、自我动手操作的潜力,在工作的过程中,复习了以前学习过的知识,并掌握了一些应用知识的技巧等
在此次实战中,我还学会了下面几点工作学习心态:
1)继续学习,不断提升理论涵养。在信息时代,学习是不断地汲取新信息,获得事业进步的动力。作为一名青年学子更就应把学习作为持续工作用心性的重要途径。走上工作岗位后,我会用心响应单位号召,结合工作实际,不断学习理论、业务知识和社会知识,用先进的理论武装头脑,用精良的业务知识提升潜力,以广博的社会知识拓展视野。
2)努力实践,自觉进行主角转化。只有将理论付诸于实践才能实现理论自身的价值,也只有将理论付诸于实践才能使理论得以检验。同样,一个人的价值也是透过实践活动来实现的,也只有透过实践才能锻炼人的品质,彰显人的意志。
3)提高工作用心性和主动性。实习,是开端也是结束。展此刻自我面前的是一片任自我驰骋的沃土,也分明感受到了沉甸甸的职责。在今后的工作和生活中,我将继续学习,深入实践,不断提升自我,努力创造业绩,继续创造更多的价值。
这次Python实战不仅仅使我学到了知识,丰富了经验。也帮忙我缩小了实践和理论的差距。在未来的工作中我会把学到的理论知识和实践经验不断的应用到实际工作中,为实现理想而努力。
源代码
import pandas as pd
import warnings
warnings.filterwarnings('ignore')
data = pd.read_csv('data.csv')
data.head()
##### 数据探索
data.shape # 查看数据大小
data.info() # 查看数据基本信息
data.describe().T # 查看描述性统计
##### 数据清洗
data.dropna(inplace=True) # 删除缺失值
data.drop_duplicates(inplace=True) # 删除重复值
数据可视化
import matplotlib.pylab as plt
import seaborn as sns
sns.set(font="SimHei")
plt.rcParams['font.sans-serif'] = ['SimHei'] #解决中文显示
plt.rcParams['axes.unicode_minus'] = False #解决符号无法显示
# 查看数据中是否违约的比例数量
sns.countplot(data=data,x='payment_flag')
plt.show()
# 分析可透支金额的分布
sns.distplot(data['LIMIT_BAL'],kde=True)
plt.show()
# 分析性别对于可透支金额的影响
sns.boxplot(data=data,x='payment_flag',y='LIMIT_BAL',hue='SEX')
plt.show()
# 分析受教育程度对于可透支金额的影响
sns.boxplot(data=data,x='payment_flag',y='LIMIT_BAL',hue='EDUCATION')
plt.show()
# 分析婚姻状况对于可透支金额的影响
sns.boxplot(data=data,x='payment_flag',y='LIMIT_BAL',hue='MARRIAGE')
plt.show()
# 分析年龄与可透支金额的关系
plt.scatter(x=data['AGE'],y=data['LIMIT_BAL'])
plt.show()
# 分析各个特征之间的相关系数
fig = plt.figure(figsize=(16,16))
sns.heatmap(data.corr(),vmax=1,annot=True,linewidths=0.5,cbar=False,cmap='YlGnBu',annot_kws={'fontsize':12})
plt.xticks(fontsize=14)
plt.yticks(fontsize=14)
plt.title('各个因素之间的相关系数',fontsize=20)
plt.show()
特征工程
# 对数据集进行过采样处理
new_df = pd.DataFrame() # 构建一个新的df来存储data['payment_flag']==1的数据
# 用循环生成一个data['payment_flag']==1的df,相当于将扩充data['payment_flag']==1的数据量
for i in range(len(data[data['payment_flag']==0])-len(data[data['payment_flag']==1])):
a = data[data['payment_flag']==1].sample(1) # 随机选择一个data['payment_flag']==1的数据
new_df = new_df.append(a)
new_data = pd.concat([data,new_df]) # 合并数据集
new_data['payment_flag'].value_counts()
from sklearn.model_selection import train_test_split
# 准备数据
X = new_data.drop('payment_flag',axis=1)
y = new_data['payment_flag']
# 划分数据集
x_train,x_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=42)
print('训练集大小:',x_train.shape[0])
print('测试集大小:',x_test.shape[0])
构建模型
# 构建决策树模型
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
tree = DecisionTreeClassifier()
tree.fit(x_train,y_train)
y_pred1 = tree.predict(x_test)
print('决策树模型准确率:',accuracy_score(y_test,y_pred1))
# 构建逻辑回归模型
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
lg = LogisticRegression()
lg.fit(x_train,y_train)
y_pred2 = lg.predict(x_test)
print('逻辑回归模型准确率:',accuracy_score(y_test,y_pred2))
# 构建xgboost模型
from xgboost import XGBClassifier
from sklearn.metrics import accuracy_score
xgb = XGBClassifier()
xgb.fit(x_train,y_train)
y_pred3 = xgb.predict(x_test)
print('xgboost模型准确率:',accuracy_score(y_test,y_pred3))
模型评估
# 因为决策树模型准确率最高,故选用决策树模型作为最终的模型
from sklearn.metrics import confusion_matrix,classification_report,auc,roc_curve
# 模型评估
y_pred = tree.predict(x_test)
print('模型混淆矩阵:','\n',confusion_matrix(y_test,y_pred1))
fig = plt.figure(figsize=(10,8))
sns.heatmap(confusion_matrix(y_test,y_pred1),annot=True,linewidths=0.5,annot_kws={'fontsize':18},fmt='d')
plt.xlabel('Predicted Class',fontdict={'fontsize':16})
plt.ylabel('True Class',fontdict={'fontsize':16})
plt.xticks(fontsize=16)
plt.yticks(fontsize=16)
plt.title('Decision Tree',fontsize=20)
plt.show()
print('模型分类报告:','\n',classification_report(y_test,y_pred1))
# 画出ROC曲线
y_prob = tree.predict_proba(x_test)[:,1]
false_positive_rate, true_positive_rate, thresholds = roc_curve(y_test, y_prob)
roc = auc(false_positive_rate, true_positive_rate)
plt.figure(figsize=(10,10))
plt.title('ROC')
plt.plot(false_positive_rate,true_positive_rate, color='red',label = 'AUC = %0.2f' % roc)
plt.legend(loc = 'lower right')
plt.plot([0, 1], [0, 1],linestyle='--')
plt.axis('tight')
plt.ylabel('True Positive Rate')
plt.xlabel('False Positive Rate')
plt.show()
模型预测
# 使用决策树模型进行预测,发现十个当作有两个预测错误
result = pd.DataFrame()
result['真实值'] = y_test
result['预测值'] = y_pred1
result.head(10)