合并五张表
将筛选后的五个表进行合并,得出25个字段
df_train=user_train.merge(bank_train) df_train=df_train.merge(bill_train) df_train=df_train.merge(browse_train) df_train=df_train.merge(overdue_train) df_train.head()
查看完整表格的基本情况,无缺失值,均是数值类型。
df_train.info()
特征工程
基于业务理解的筛选
银行流水记录特征相关性分析
# 相关性结果数据表 corrmat=bank_train[internal_chars].corr() #热力图 sns.heatmap(corrmat, square=True, linewidths=.5, annot=True);
- '进账单数'与'进账金额'的相关系数很高,相关系数为0.99
- '支出单数', '支出金额'的相关性较高,相关系数分别为0.82,0.85
- '进账金额'与'支出单数', '支出金额'的相关性较高,相关系数分别为0.81,0.85
- '支出单数'与 '支出金额'的相关性很高,相关系数为0.99
- '工资笔数'与'工资收入'相关系数为1
- 可见收入、支出、工资三个指标的金额跟笔数是线性关系,那么后续将构建一个新的特征:笔均=金额/笔数,取工资笔均;而且收入、支出是强相关(0.82),所以只取一个即可,支出笔均。
- 后续将用'进账金额/进账单数','支出金额/支出单数','工资收入/工资笔数'得到'进账笔均','支出笔均','工资笔均'
总表相关性分析
# 相关性结果数据表 corrmat=df_train[internal_chars].corr() # 热力图 sns.heatmap(corrmat, square=False, linewidths=.5, annot=True);
- '本期账单金额'与'本期账单余额'相关系数为0.85
- '上期账单金额'与'上期还款金额'相关系数为0.75
- '本期账单金额'与'上期还款金额'相关系数为0.64
- '信用卡额度'与'上期账单金额'和'上期还款金额'相关系数分别为0.54和0.52
- '本期账单金额'与'上期账单金额'相关系数为0.5
本期的账单余额与最低还款额具有高度共线性,决定只选用最低还款额。
生产衍射变量
上期还款差额 =上期账单金额 - 上期还款金额, 上期还款差额还会直接影响用户的信用额度以及本期的账单金额。
调整金额和循环利息是跟“上期的还款差额”有关的:
- 还款差额>0,需要计算循环利息,调整金额不计
- 还款差额<0,需要计算调整金额,循环利息不计
可以将还款差额进行“特征二值化”来代替这两个特征。
预借现金额度,是指持卡人使用信用卡通过ATM等自助终端提取现金的最高额度,取现额度包含于信用额度之内,一般是信用额度的50%左右,所以可以不用这个特征,选择信用额度即可。
df_train['平均支出']=df_train.apply(lambda x:x.支出金额/x.支出单数, axis=1) df_train['平均工资收入']=df_train.apply(lambda x:x.工资收入/x.工资笔数, axis=1) df_train['上期还款差额']=df_train.apply(lambda x:x.上期账单金额-x.上期还款金额, axis=1) df_select=df_train.loc[:,['用户id', '性别', '教育程度', '婚姻状态', '平均支出', '平均工资收入', '上期还款差额', '信用卡额度', '本期账单余额', '本期账单最低还款额', '消费笔数', '浏览行为数据', '样本标签']].fillna(0) df_select.head()
基于机器学习的筛选
将上期还款差额
二值化
from sklearn.preprocessing import Binarizer X=df_select['上期还款差额'].values.reshape(-1,1) transformer = Binarizer(threshold=0).fit_transform(X) df_select['上期还款差额标签']=transformer
方差过滤法
过滤那些不带有信息的变量,默认参数为0,即过滤方差为0的那些变量,只保留对模型有贡献的那些信息。
from sklearn.feature_selection import VarianceThreshold VTS = VarianceThreshold() # 实例化,参数默认方差为0 x_01=VTS.fit_transform(x)
相关性过滤--互信息法
互信息法是用来捕捉每个特征与标签之间的任意关系(包括线性和非线性关系)的过滤方法。
和F检验相似,它既可以做回归也可以做分类,并且包含两个类mutual_info_classif(互信息分类)和mutual_info_regression(互信息回归)。
这两个类的用法和参数都和F检验一模一样,不过互信息法比F检验更加强大,F检验只能够找出线性关系,而互信息法可以找出任意关系。
from sklearn.feature_selection import mutual_info_classif as MIC result = MIC(x,y)
样本不均衡
通过观察,正负样本比例为 836:4899,属于样本不均衡范畴,可采用上采样的SMOTE算法
对其进行样本不均衡处理。
from imblearn.over_sampling import SMOTE over_samples = SMOTE(random_state=111) over_samples_x, over_samples_y = over_samples.fit_sample(x,y)
模型建立与调参
文章一开始已经提到过了,可选模型较多,这里举例三种模型逻辑回归、决策树、随机森林模型,其余模型的选用,小伙伴们可以自己动手练习练习。
二分类模型——逻辑回归模型
互信息与正则化对模型效果的影响
用学习曲线对参数C进行调整,分别在两个模型中进行调参。
超参数C
: 一般不会超过1, 越大惩罚力度越小,本次选取从 0.05 - 2
范围。
from sklearn.linear_model import LogisticRegression as LR from sklearn.model_selection import cross_val_score as cvs lrl1 = LR(penalty='l1', solver='liblinear', C=i, max_iter=1000, random_state=0) lrl2 = LR(penalty='l2', solver='liblinear', C=i, max_iter=1000, random_state=0)
由图可知,在经过互信息过滤后,逻辑回归模型得分明显提高,且当超参数C=0.6
时,模型效果是最好的。
包装法筛选变量
以逻辑回归为基分类器,结合包装法筛选变量,并运用交叉验证绘制学习曲线,探索最佳变量个数。
同时,运用SMOTE算法进行样本均衡处理,并比较均衡前后模型效果的变化。
from sklearn.feature_selection import RFE LR_1 = LogisticRegression(penalty='l1', solver='liblinear', C=0.6, max_iter=1000, random_state=0) selector1 = RFE(LR_1, n_features_to_select=i, step=1) X_wrapper1 = selector1.fit_transform(x, y) once1=cvs(LR_1, X_wrapper1, y, cv=5, scoring='f1').mean()
由图可见,样本均衡前后模型效果有大幅度增长。且两种正则化方法相差无几。
模型——决策树
因为样本均衡化处理前后,对模型效果提升较为明显,因此在使用决策树模型建立之前,对样本进行均衡化处理。
因为深度参数max_depth
是对决策树模型影响最大的参数之一,因此本案例正对决策树深度绘制学习曲线,探索决策树最佳参数。
plt.plot(L_CVS, 'r') # 交叉验证 plt.plot(L_train, 'g')# 训练集 plt.plot(L_test, 'b') # 测试集
由学习曲线可知,在max_depth=5
时训练集和测试集模型效果均达到了最佳状态,当在max_depth
大于5后,模型在训练集上的分数依然在上升,而测试集上的表现有所下降,这就是模型过拟合现象,因此最终我们选用max_depth=5
。
特征重要性
features_imp = pd.Series(dtc.feature_importances_, index = x.columns).sort_values(ascending=False) features_imp
上期还款差额标签 0.705916 性别 0.101779 平均支出 0.064218 平均工资收入 0.047644 浏览行为数据 0.044333 教育程度 0.015257 婚姻状态 0.012665 本期账单最低还款额 0.004455 消费笔数 0.003734 本期账单余额 0.000000 信用卡额度 0.000000 dtype: float64
决策树可视化
这里提出一点,如果需要深入理解决策树决策过程,可以借助决策树可视化来辅助理解。
import graphviz from sklearn import tree #首先配置 dot_data = tree.export_graphviz(dtc # 要对已经建成的dct这个实例化好的模型进行画图 ,feature_names= x.columns # 更改列名为中文 # ,class_names=[] # 更改标签名字 ,filled=True # 给每一个节点分配颜色,颜色约深表示叶子的纯度越高 ,rounded=True # 节点性状为圆角 ) graph = graphviz.Source(dot_data) graph
树模型——随机森林
from sklearn.ensemble import RandomForestClassifier as RFC from sklearn.model_selection import GridSearchCV rfc = RFC(n_estimators=i+1, n_jobs=-1, random_state=90) score = cvs(rfc,over_samples_x_train, over_samples_y_train, cv=5, scoring='f1').mean()
模型调参
有⼀些参数是没有参照的,一开始很难确定⼀个范围,这种情况下采用先通过学习曲线确定参数大致范围,再通过网格搜索确定最佳参数。
比如确定n_estimators
范围时,通过学习曲线观察n_estimators
在什么取值开始变得平稳,是否⼀直推动模型整体准确率的上升等信息。
对于其他参数也是按照同样的思路,如影响单棵决策树模型的参数max_depth
来说,⼀般根据数据的⼤⼩来进⾏⼀个试探,比如乳腺癌数据很⼩,所以可以采⽤1~10
,或者1~20
这样的试探。
但对于像digit recognition
那样的⼤型数据来说,我们应该尝试30~50层深度(或许还不⾜够),此时更应该画出学习曲线,来观察深度对模型的影响。
确定范围后,就可以通过网格搜索的方式确定最佳参数。其他参数就不一一举例了,大家可以动手尝试一下。
# 调整max_depth param_grid = {'max_depth':np.arange(1, 20, 1)} rfc = RFC(n_estimators=150,random_state=90, n_jobs=-1) GS = GridSearchCV(rfc,param_grid,cv=5, scoring='f1') GS.fit(over_samples_x, over_samples_y) GS.best_params_ GS.best_score_
模型评价
本次案例模型评估使用classification_report
sklearn中的classification_report
函数用于显示主要分类指标的文本报告.在报告中显示每个类的精确度,召回率,F1值等信息。
主要参数:
y_true
:1维数组,或标签指示器数组/稀疏矩阵,目标值。
y_pred
:1维数组,或标签指示器数组/稀疏矩阵,分类器返回的估计值。
labels
:array,shape = [n_labels],报表中包含的标签索引的可选列表。
target_names
:字符串列表,与标签匹配的可选显示名称(相同顺序)。
sample_weight
:类似于shape = [n_samples]的数组,可选项,样本权重。
digits:int
,输出浮点值的位数。
策树验证集评价结果
最后这里举了一个决策树模型效果评价的例子,其余分类型模型评价同样可以使用。当然,模型评价方法不止这一种,大家也可以尝试着从其他角度来做模型评价。
precision recall f1-score support 0 0.70 0.74 0.72 1454 1 0.72 0.68 0.70 1454 accuracy 0.71 2908 macro avg 0.71 0.71 0.71 2908 weighted avg 0.71 0.71 0.71 2908
本文旨在梳理数据挖掘的一般过程,没有涉及到很复杂的算法,每个环节,如数据预处理、特征工程、模型建立于评价,均是常用的方法。本文数据也都给大家准备好了。