DNN深度神經網絡擅長于同構的高維數據,從高維稀疏的表示中學習到低維致密的分布式表示,所以在自然語言、圖像識別等領域基本上是稱霸武林(神經網絡的介紹及實踐)。對于異構致密的表格數據,個人實踐來看,DNN模型的非線性能力沒樹模型來得高效。

所以一個很樸素的想法是,結合這樹模型+神經網絡模型的優勢。比如通過NN學習文本的嵌入特征后,輸入樹模型繼續學習(如word2vec+LGB做文本分類)。或者是,樹模型學習表格數據后,輸出樣本的高維個葉子節點的特征表示,輸入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

樹+神經網絡

接下來我們將提取樹模型的葉子節點的路徑作為特征,并簡單做下特征選擇處理

import numpy as np

y_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)

for i in range(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

# drop zero-features
df2 = pd.DataFrame(train_matrix)
droplist2 = []
for k in df2.columns:
if not df2[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)

# 神經網絡模型評估
def model_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)
return auc(fpr, tpr),max(tpr-fpr)

import keras
from keras import regularizers
from keras.layers import Dense,Dropout,BatchNormalization,GaussianNoise
from keras.models import Sequential, Model
from keras.callbacks import EarlyStopping
from sklearn.metrics import mean_squared_error

np.random.seed(1) # 固定隨機種子,使每次運行結果固定

bestval = 0
# 創建神經模型并暴力搜索較優網絡結構超參: 輸入層; n層k個神經元的relu隱藏層; 輸出層
for layer_nums in range(2): #隱藏層的層數
for k in list(range(1,100,5)): # 網格神經元數
for norm in [0.01,0.05,0.1,0.2,0.4,0.6,0.8]:#正則化懲罰系數
print("************隱藏層vs神經元數vs norm**************",layer_nums,k,norm)
model = Sequential()
model.add(BatchNormalization()) # 輸入層 批標準化 input_dim=train_x.shape
for _ in range(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)) # 隱藏層1
model.add(Dropout(norm)) # dropout正則
model.add(Dense(1,use_bias=True,activation='sigmoid')) # 輸出層

# 編譯模型:優化目標為回歸預測損失mse,優化算法為adam
model.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]
if test_auc > bestval:
bestval = test_auc
bestparas = ['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_.pdf https://github.com/motefly/DeepGBM

文章轉自微信公眾號@算法進階

上一篇:

手部分開發一個深度學習框架(Python)

下一篇:

漫談圖神經網絡模型(GNN):從圖到圖卷積
#你可能也喜歡這些API文章!

我們有何不同?

API服務商零注冊

多API并行試用

數據驅動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內容創意新穎性、情感共鳴力、商業轉化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費