<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          樹+神經(jīng)網(wǎng)絡(luò)算法強強聯(lián)手(Python)

          共 9333字,需瀏覽 19分鐘

           ·

          2022-08-04 00:27

          結(jié)合論文《Revisiting Deep Learning Models for Tabular Data》的觀點,集成樹模型通常擅長于表格數(shù)據(jù)這種異構(gòu)數(shù)據(jù)集,是實打?qū)嵉谋砀駭?shù)據(jù)王者。

          集成樹模型中的LightGBM是增強版的GBDT,支持了分類變量,在工程層面大大提高了訓(xùn)練效率。關(guān)于樹模型的介紹,可見之前文章:一文講透樹模型

          DNN深度神經(jīng)網(wǎng)絡(luò)擅長于同構(gòu)的高維數(shù)據(jù),從高維稀疏的表示中學(xué)習(xí)到低維致密的分布式表示,所以在自然語言、圖像識別等領(lǐng)域基本上是稱霸武林(神經(jīng)網(wǎng)絡(luò)的介紹及實踐可見系列文章:一文搞定深度學(xué)習(xí)建模全流程)。對于異構(gòu)致密的表格數(shù)據(jù),個人實踐來看,DNN模型的非線性能力沒樹模型來得高效。

          所以一個很樸素的想法是,結(jié)合這樹模型+神經(jīng)網(wǎng)絡(luò)模型的優(yōu)勢。比如通過NN學(xué)習(xí)文本的嵌入特征后,輸入樹模型繼續(xù)學(xué)習(xí)(如word2vec+LGB做文本分類,可見文章:NLP建模全流程)?;蛘呤牵瑯淠P蛯W(xué)習(xí)表格數(shù)據(jù)后,輸出樣本的高維個葉子節(jié)點的特征表示,輸入DNN模型。

          接下來,我們使用LightGBM+DNN模型強強聯(lián)手,驗證其在信貸違約的表格數(shù)據(jù)預(yù)測分類效果。

          數(shù)據(jù)處理及樹模型訓(xùn)練

          lightgbm樹模型,自帶缺失、類別變量的處理,還有很強的非線性擬合能力,特征工程上面不用做很多處理,建模非常方便。

          ##完整代碼及數(shù)據(jù)請見 算法進階github:https://github.com/aialgorithm/Blog

          # 劃分?jǐn)?shù)據(jù)集:訓(xùn)練集和測試集
          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)

          # 訓(xùn)練模型
          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可以達(dá)到0.8656

          樹+神經(jīng)網(wǎng)絡(luò)

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

          import numpy as np

          y_pred = lgb.predict(train_bank[num_feas + cate_feas],pred_leaf=True) 

          # 提取葉子節(jié)點
          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')

          # 拼接原特征和樹節(jié)點特征
          df_final2 = pd.concat([train_bank[num_feas],df2],axis=1)
          df_final2.head()

          將拼接好原特征及樹節(jié)點路徑特征輸入神經(jīng)網(wǎng)絡(luò)模型,并使用網(wǎng)格搜索調(diào)優(yōu)神經(jīng)網(wǎng)絡(luò)模型。

          # 劃分?jǐn)?shù)據(jù)集:訓(xùn)練集和測試集
          train_x, test_x, train_y, test_y = train_test_split(df_final2, train_bank.isDefault,test_size=0.3, random_state=0)

          # 神經(jīng)網(wǎng)絡(luò)模型評估
          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) # 固定隨機種子,使每次運行結(jié)果固定



          bestval = 0
          # 創(chuàng)建神經(jīng)模型并暴力搜索較優(yōu)網(wǎng)絡(luò)結(jié)構(gòu)超參: 輸入層;   n層k個神經(jīng)元的relu隱藏層;  輸出層
          for layer_nums in range(2): #隱藏層的層數(shù)
              for k in list(range(1,100,5)):  # 網(wǎng)格神經(jīng)元數(shù)
                  for norm in [0.01,0.05,0.1,0.2,0.4,0.6,0.8]:#正則化懲罰系數(shù)
                      print("************隱藏層vs神經(jīng)元數(shù)vs norm**************",layer_nums,k,norm)
                      model = Sequential()
                      model.add(BatchNormalization())  # 輸入層 批標(biāo)準(zhǔn)化  input_dim=train_x.shape
                      for _ in range(layer_nums):
                          model.add(Dense(k,  
                                          kernel_initializer='random_uniform',   # 均勻初始化
                                          activation='relu',                     # relu激活函數(shù)
                                          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'))  # 輸出層


                      # 編譯模型:優(yōu)化目標(biāo)為回歸預(yù)測損失mse,優(yōu)化算法為adam
                      model.compile(optimizer='adam', loss=keras.losses.binary_crossentropy) 

                      # 訓(xùn)練模型
                      history = model.fit(train_x.replace([np.inf, -np.inf], np.nan).fillna(0), 
                                          train_y, 
                                          epochs=1000,              # 訓(xùn)練迭代次數(shù)
                                          batch_size=1000,           # 每epoch采樣的batch大小
                                          validation_data=(test_x.replace([np.inf, -np.inf], np.nan).fillna(0),test_y),   # 從訓(xùn)練集再拆分驗證集,作為早停的衡量指標(biāo)
                                          callbacks=[EarlyStopping(monitor='val_loss', patience=10)],    #早停法
                                          verbose=False)  # 不輸出過程  
                      print("驗證集最優(yōu)結(jié)果:",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')    # 藍(lán)色線訓(xùn)練集損失
          plt.plot(history.history['val_loss'],c='red'# 紅色線驗證集損失
          plt.show()
          model.summary()   #模型概述信息
          print(bestparas)
              


          在我們這個實驗中,使用樹模型+神經(jīng)網(wǎng)絡(luò)模型在test的auc得到一些不錯的提升,樹模型的AUC 0.8656,而樹模型+神經(jīng)網(wǎng)絡(luò)的AUC 0.8776,提升了1.2%

          其他試驗結(jié)果

          結(jié)合微軟的試驗,樹+神經(jīng)網(wǎng)絡(luò)(DeepGBM),在不同的任務(wù)上也是可以帶來一些的效果提升的。有興趣可以閱讀下文末參考文獻(xiàn)。

          LGB+DNN(或者單層的LR)是一個很不錯的想法,有提升模型的一些效果。但需要注意的是,這也會加重模型的落地及迭代的復(fù)雜度。綜合來看,樹+神經(jīng)網(wǎng)絡(luò)是一個好的故事,但是結(jié)局沒有太驚艷。

          參考論文:https://www.microsoft.com/en-us/research/uploads/prod/2019/08/deepgbm_kdd2019__CR_.pdf https://github.com/motefly/DeepGBM

          - END -


          瀏覽 107
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲最新视频在线免费播放不卡网站 | 欧美操屄视频 | 免费看亚洲色情视频 | 免费黄色欧美 | 夜夜操狠狠操 |