信用卡审核结果特征分析
原始数据
client.csv
client2.csv
加载数据
from __future__ import division, print_function import numpy as np import pandas as pd from sklearn.metrics import roc_curve, auc ###计算roc和auc from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import precision_score, recall_score, f1_score import matplotlib.pyplot as plt import warnings warnings.filterwarnings('ignore') # 忽略警告 plt.rcParams['font.sans-serif'] = ['SimHei'] #解决中文显示 plt.rcParams['axes.unicode_minus'] = False #解决符号无法显示 # 读取数据并合并 data1 = pd.read_csv('client.csv') data11=data1.loc[:,['客户号','性别','年龄','婚姻状态','户籍','教育程度','居住类型','职业类别','工作年限','个人年收入','车辆情况','信贷情况']] data2 = pd.read_csv('client2.csv') data22=data2.loc[:,['客户号','审批结果']] # 根据客户号将两个数据进行合并 data=pd.merge(data11,data22,how='left',on='客户号') data
数据处理
# 将审批结果这一列中的空值记为0,0-通过记为1,并转化为整数类型 data.审批结果[data.审批结果.isnull()==True]=0 data.审批结果[data.审批结果=='0-通过']=1 data['审批结果']=data['审批结果'].astype(int) data['审批结果'].head()
建模
准备数据
# 准备数据 并进行one-hot编码 y=data['审批结果'] a=['性别','婚姻状态','户籍','教育程度','居住类型','职业类别','车辆情况','信贷情况','年龄','个人年收入'] X=pd.get_dummies(data[a]) X
构建模型
# 划分训练集合测试集 X_train,X_test,y_train,y_test = train_test_split (X,y,test_size=0.30,random_state=1) # 创建随机森林模型 rf=RandomForestClassifier(n_estimators=100,oob_score=True, random_state=10) rf.fit(X_train,y_train) #进行模型的训练 #这里使用了默认的参数设置 y_pred=rf.predict(X_test) X_pred=rf.predict(X_train) confmat = pd.crosstab(y_test,y_pred) confmat #打印模型混淆矩阵
从混淆矩阵中,我们看出在预测0(未通过)的用户中,有1174个预测正确,有35个 预测错误;在预测1(通过)的用户中,有1720个预测正确,有71个预测错误
# 召回率、准确率、F1 print ('precision:%.3f' %precision_score(y_true=y_test, y_pred=y_pred)) print ('recall:%.3f' %recall_score(y_true=y_test, y_pred=y_pred)) print ('F1:%.3f' %f1_score(y_true=y_test, y_pred=y_pred))
我们看出模型准确率为0.98,模型非常好
绘制ROC曲线
# 画ROC曲线 Test_fpr,Test_tpr,threshold = roc_curve(y_test, y_pred) ###计算真正率和假正率 Train_fpr,Train_tpr,threshold = roc_curve(y_train, X_pred) ###计算真正率和假正率 Test_roc_auc = auc(Test_fpr,Test_tpr) ###计算auc的值 Train_roc_auc = auc(Train_fpr,Train_tpr) ###计算auc的值 plt.figure(figsize=(10,10)) plt.plot(Test_fpr,Test_tpr, color='darkorange', lw=2, label='ROC curve (area = %0.2f)' % Test_roc_auc) ###假正率为横坐标,真正率为纵坐标做曲线 plt.plot(Train_fpr,Train_tpr, color='red', lw=2, label='ROC curve (area = %0.2f)' % Train_roc_auc) ###假正率为横坐标,真正率为纵坐标做曲线 plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--') plt.xlim([0.0, 1.0]) plt.ylim([0.0, 1.05]) plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plt.title('Mode ROC curve') plt.legend(loc="lower right") plt.show()
ROC曲线也是反映模型的准确率,曲线与斜率为1的直线围成的面积越大,模型准确率越高
特征重要性评分
# 打印特征重要性评分 feat_labels = X_train.columns[0:] importances = rf.feature_importances_ indices = np.argsort(importances)[::-1] for i,j in zip(range(X_train.shape[1]-1),indices): print(i + 1, feat_labels[j], importances[j])
从结果中我们看出个人年收入的重要性评分最大,说明个人年收入对信用卡审核结果重要性最大影响最大,其次是年龄,车辆情况,居住情况等特征
用户信用等级的特征分析
原始数据
client2.csv
costhis.csv
加载数据
from __future__ import division, print_function import numpy as np import pandas as pd from sklearn.metrics import roc_curve, auc ###计算roc和auc from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import precision_score, recall_score, f1_score import matplotlib.pyplot as plt import warnings warnings.filterwarnings('ignore') # 忽略警告 plt.rcParams['font.sans-serif'] = ['SimHei'] #解决中文显示 plt.rcParams['axes.unicode_minus'] = False #解决符号无法显示 # 加载数据并合并 data1 = pd.read_csv('client2.csv') data11=data1.loc[:,['客户号','性别','年龄','婚姻状态','户籍','教育程度','居住类型','职业类别','工作年限','个人收入','车辆情况','信用等级']] data2 = pd.read_csv('costhis.csv') data22=data2.loc[:,['客户号','日均消费金额','日均次数','单笔消费最小金额','单笔消费最大金额']] data=pd.merge(data22,data11,how='left',on='客户号') data
数据处理
# 将信用等级进行编码 data.信用等级[data.信用等级=='A-优质客户']=1 data.信用等级[data.信用等级=='B-良好客户']=2 data.信用等级[data.信用等级=='C-普通客户']=3 data.信用等级[data.信用等级=='D-风险客户']=4 data['信用等级']=data['信用等级'].astype(int) data['信用等级']
建模
数据准备
# 准备数据 进行one-hot编码 y=data['信用等级'] a=['性别','婚姻状态','户籍','教育程度','居住类型','职业类别','车辆情况','年龄','个人收入','日均消费金额','日均次数','单笔消费最小金额','单笔消费最大金额'] X=pd.get_dummies(data[a]) X
构建模型
#划分训练集合测试集 X_train,X_test,y_train,y_test = train_test_split (X,y,test_size=0.30,random_state=1) rf=RandomForestClassifier(n_estimators=100,oob_score=True, random_state=10) rf.fit(X_train,y_train) #进行模型的训练 #这里使用了默认的参数设置 y_pred=rf.predict(X_test) X_pred=rf.predict(X_train) from sklearn.metrics import confusion_matrix confmat = confusion_matrix(y_test, y_pred) # 打印混淆矩阵 confmat
从混淆矩阵中我们看出,在预测1类客户时,有123个预测正确,有4个预测成了2类客户;在预测2类客户时,有315个预测正确,有6个预测成1类,14个预测成3类;在预测3类客户时,有570个预测正确,有28个预测成2类客户,20个预测成4类客户;在预测4类客户时,有672个预测正确,有35个预测成3类客户
print ('模型预测准确率:%.3f'%(rf.score(X_test, y_test))) #打印模型预测精度
模型预测准确率:0.940
我们看出模型预测准确率为0.94,模型较好
画混淆矩阵图
#混淆矩阵 def plot_confusion_matrix(cm, title='Confusion Matrix', cmap=plt.cm.Blues): plt.imshow(cm, interpolation='nearest', cmap=cmap,alpha=0.3) plt.title(title,fontsize = 16) plt.colorbar() xlocations = np.array(range(len(labels))) plt.xticks(xlocations, labels, rotation=90) plt.yticks(xlocations, labels) plt.ylabel('True label',fontsize = 14) plt.xlabel('Predicted label',fontsize = 14) # 画混淆矩阵图 labels = ['1', '2', '3', '4'] tick_marks = np.array(range(len(labels))) + 0.5 np.set_printoptions(precision=2) cm_normalized = confmat.astype('float') / confmat.sum(axis=1)[:, np.newaxis] plt.figure(figsize=(8, 6), dpi=120) ind_array = np.arange(len(labels)) x, y = np.meshgrid(ind_array, ind_array) Sumyb=0 TPreyb=0 for x_val, y_val in zip(x.flatten(), y.flatten()): c = cm_normalized[y_val][x_val] d=confmat[y_val][x_val] Sumyb=Sumyb+d if c > 0.01: plt.text(x_val, y_val, "%0.2f" % (c,), color='red', fontsize=14, va='center', ha='center') if x_val==y_val: TPreyb=TPreyb+d # offset the tick plt.gca().set_xticks(tick_marks, minor=True) plt.gca().set_yticks(tick_marks, minor=True) plt.gca().xaxis.set_ticks_position('none') plt.gca().yaxis.set_ticks_position('none') plt.grid(True, which='minor', linestyle='-') plt.gcf().subplots_adjust(bottom=0.15) plot_confusion_matrix(confmat, title='Normalized confusion matrix') plt.show()
特征重要性评分
#打印特征重要性评分 feat_labels = X_train.columns[0:] importances = rf.feature_importances_ indices = np.argsort(importances)[::-1] for f,j in zip(range(X_train.shape[1]-1),indices): print(f + 1, feat_labels[j], importances[j])
从结果看出年龄,个人收入,日均消费金额,单笔消费最大、小金额等特征重要性较大,即对预测用户信用等级的重要性最大
接下来我们通过直方图进行可视化查看
特征可视化
#直方图 def draw_hist(myList,Title,Xlabel,Ylabel): rects=plt.bar(range(len(myList)), myList) index=[0,1,2,3] YmaxLen=10**(len(str(max(HisData)))-1) ymax=(int(max(HisData)/YmaxLen)+1)* YmaxLen plt.ylim(ymax=ymax, ymin=0) plt.xticks(index, name_list) plt.xlabel(Xlabel) #X轴标签 plt.ylabel(Ylabel) #y轴标签 plt.title(Title) plt.rcParams['font.sans-serif'] = ['SimHei'] #解决中文显示 plt.rcParams['axes.unicode_minus'] = False #解决符号无法显示 for rect in rects: height = rect.get_height() plt.text(rect.get_x() + rect.get_width() / 2, height, str(height), ha='center', va='bottom') plt.show()
先定义一个画直方图的方法,便于后面直接使用
个人收入对信用等级的影响分析
# 个人收入对信用等级的影响分析 HisData=[] for x in range(4): a=sum(data.个人收入[data.信用等级==x+1]) b=len(data.个人收入[data.信用等级==x+1]) HisData.append(int(a/b)) draw_hist(HisData,u'个人收入与信用等级的关系',u'信用等级',u'个人收入') # 直方图展示
日均消费金额对信用等级的影响分析
# 日均消费金额对信用等级的影响分析 name_list = [u'A-优质客户', 'B-良好客户', 'C-普通客户', 'D-风险客户'] HisData=[] for x in range(4): a=sum(data.日均消费金额[data.信用等级==x+1]) b=len(data.日均消费金额[data.信用等级==x+1]) HisData.append(int(a/b)) draw_hist(HisData,u'日均消费额与信用等级的关系',u'信用等级',u'日均消费额') # 直方图展示
单笔消费最大金额对信用等级的影响分析
# 单笔消费最大金额对信用等级的影响分析 HisData=[] for x in range(4): a=sum(data.单笔消费最大金额[data.信用等级==x+1]) b=len(data.单笔消费最大金额[data.信用等级==x+1]) HisData.append(int(a/b)) draw_hist(HisData,u'单笔消费最大金额与信用等级的关系',u'信用等级',u'单笔消费最大金额 ') # 直方图展示