您的位置:首页 >聚焦 >

天天快消息!树+神经网络算法强强联手(Python)

2022-08-04 05:40:05    来源:程序员客栈

结合论文《Revisiting Deep Learning Models for Tabular Data》的观点,集成树模型通常擅长于表格数据这种异构数据集,是实打实的表格数据王者。

集成树模型中的LightGBM是增强版的GBDT,支持了分类变量,在工程层面大大提高了训练效率。关于树模型的介绍,可见之前文章:一文讲透树模型


(资料图片仅供参考)

DNN深度神经网络擅长于同构的高维数据,从高维稀疏的表示中学习到低维致密的分布式表示,所以在自然语言、图像识别等领域基本上是称霸武林(神经网络的介绍及实践可见系列文章:一文搞定深度学习建模全流程)。对于异构致密的表格数据,个人实践来看,DNN模型的非线性能力没树模型来得高效。

所以一个很朴素的想法是,结合这树模型+神经网络模型的优势。比如通过NN学习文本的嵌入特征后,输入树模型继续学习(如word2vec+LGB做文本分类,可见文章:NLP建模全流程)。或者是,树模型学习表格数据后,输出样本的高维个叶子节点的特征表示,输入DNN模型。

接下来,我们使用LightGBM+DNN模型强强联手,验证其在信贷违约的表格数据预测分类效果。

数据处理及树模型训练

lightgbm树模型,自带缺失、类别变量的处理,还有很强的非线性拟合能力,特征工程上面不用做很多处理,建模非常方便。

##完整代码及数据请见算法进阶github:https://github.com/aialgorithm/Blog#划分数据集:训练集和测试集train_x,test_x,train_y,test_y=train_test_split(train_bank[num_feas+cate_feas],train_bank.isDefault,test_size=0.3,random_state=0)#训练模型lgb=lightgbm.LGBMClassifier(n_estimators=5,num_leaves=5,class_weight="balanced",metric="AUC")lgb.fit(train_x,train_y)print("train",model_metrics(lgb,train_x,train_y))print("test",model_metrics(lgb,test_x,test_y))

简单处理建模后test的AUC可以达到0.8656

树+神经网络

接下来我们将提取树模型的叶子节点的路径作为特征,并简单做下特征选择处理

importnumpyasnpy_pred=lgb.predict(train_bank[num_feas+cate_feas],pred_leaf=True)#提取叶子节点train_matrix=np.zeros([len(y_pred),len(y_pred[0])*lgb.get_params()["num_leaves"]],dtype=np.int64)print(train_matrix.shape)foriinrange(len(y_pred)):temp=np.arange(len(y_pred[0]))*lgb.get_params()["num_leaves"]+np.array(y_pred[i])train_matrix[i][temp]+=1#dropzero-featuresdf2=pd.DataFrame(train_matrix)droplist2=[]forkindf2.columns:ifnotdf2[k].any():droplist2.append(k)print(len(droplist2))df2=df2.drop(droplist2,axis=1).add_suffix("_lgb")#拼接原特征和树节点特征df_final2=pd.concat([train_bank[num_feas],df2],axis=1)df_final2.head()

将拼接好原特征及树节点路径特征输入神经网络模型,并使用网格搜索调优神经网络模型。

#划分数据集:训练集和测试集train_x,test_x,train_y,test_y=train_test_split(df_final2,train_bank.isDefault,test_size=0.3,random_state=0)#神经网络模型评估defmodel_metrics2(nnmodel,x,y):yprob=nnmodel.predict(x.replace([np.inf,-np.inf],np.nan).fillna(0))[:,0]fpr,tpr,_=roc_curve(y,yprob,pos_label=1)returnauc(fpr,tpr),max(tpr-fpr)importkerasfromkerasimportregularizersfromkeras.layersimportDense,Dropout,BatchNormalization,GaussianNoisefromkeras.modelsimportSequential,Modelfromkeras.callbacksimportEarlyStoppingfromsklearn.metricsimportmean_squared_errornp.random.seed(1)#固定随机种子,使每次运行结果固定bestval=0#创建神经模型并暴力搜索较优网络结构超参:输入层; n层k个神经元的relu隐藏层;输出层forlayer_numsinrange(2):#隐藏层的层数forkinlist(range(1,100,5)):#网格神经元数fornormin[0.01,0.05,0.1,0.2,0.4,0.6,0.8]:#正则化惩罚系数print("************隐藏层vs神经元数vsnorm**************",layer_nums,k,norm)model=Sequential()model.add(BatchNormalization())#输入层批标准化input_dim=train_x.shapefor_inrange(layer_nums):model.add(Dense(k,kernel_initializer="random_uniform",#均匀初始化activation="relu",#relu激活函数kernel_regularizer=regularizers.l1_l2(l1=norm,l2=norm),#L1及L2正则项use_bias=True))#隐藏层1model.add(Dropout(norm))#dropout正则model.add(Dense(1,use_bias=True,activation="sigmoid"))#输出层#编译模型:优化目标为回归预测损失mse,优化算法为adammodel.compile(optimizer="adam",loss=keras.losses.binary_crossentropy)#训练模型history=model.fit(train_x.replace([np.inf,-np.inf],np.nan).fillna(0),train_y,epochs=1000,#训练迭代次数batch_size=1000,#每epoch采样的batch大小validation_data=(test_x.replace([np.inf,-np.inf],np.nan).fillna(0),test_y),#从训练集再拆分验证集,作为早停的衡量指标callbacks=[EarlyStopping(monitor="val_loss",patience=10)],#早停法verbose=False)#不输出过程print("验证集最优结果:",min(history.history["loss"]),min(history.history["val_loss"]))print("------------train------------\n",model_metrics2(model,train_x,train_y))print("------------test------------\n",model_metrics2(model,test_x,test_y))test_auc=model_metrics2(model,test_x,test_y)[0]iftest_auc>bestval:bestval=test_aucbestparas=["bestval,layer_nums,k,norm",bestval,layer_nums,k,norm]#模型评估:拟合效果plt.plot(history.history["loss"],c="blue")#蓝色线训练集损失plt.plot(history.history["val_loss"],c="red")#红色线验证集损失plt.show()model.summary()#模型概述信息print(bestparas)

在我们这个实验中,使用树模型+神经网络模型在test的auc得到一些不错的提升,树模型的AUC 0.8656,而树模型+神经网络的AUC 0.8776,提升了1.2%

其他试验结果

结合微软的试验,树+神经网络(DeepGBM),在不同的任务上也是可以带来一些的效果提升的。有兴趣可以阅读下文末参考文献。

LGB+DNN(或者单层的LR)是一个很不错的想法,有提升模型的一些效果。但需要注意的是,这也会加重模型的落地及迭代的复杂度。综合来看,树+神经网络是一个好的故事,但是结局没有太惊艳。

参考论文:https://www.microsoft.com/en-us/research/uploads/prod/2019/08/deepgbm_kdd2019__CR_.pdfhttps://github.com/motefly/DeepGBM

- END -

关键词: 神经网络 神经网络模型 强强联手

相关阅读