劍指LightGBM和XGboost!斯坦福發表NGBoost演算法

  • 2019 年 11 月 27 日
  • 筆記

轉自AI開發者

Stanford ML Group 最近在他們的論文中發表了一個新演算法,其實現被稱為 NGBoost。該演算法利用自然梯度將不確定性估計引入到梯度增強中。本文試圖了解這個新演算法,並與其他流行的 boosting 演算法 LightGBM 和 XGboost 進行比較,以了解它在實踐中是如何工作的。

註:Stanford ML Group 發表的論文網址為:https://arxiv.org/abs/1910.03225,有興趣的同學可以下載學習~

本文的主要內容包括以下三個部分:

1.什麼是自然梯度增強?

2.經驗驗證——與 LightGBM 和 XGBoost 的比較

3.結論

1. 什麼是自然梯度增強?

正如我在簡介中所寫那樣,NGBoost 是一種新的 boosting 演算法,它使用自然梯度 boosting,是一種用於概率預測的模組化 boosting 演算法。該演算法由 Base learners 、參數概率分布和評分規則組成。我將簡要地解釋一下這些術語是什麼。

  • Base learners

該演算法使用 Base learners。它接受輸入 x,輸出用來形成條件概率。這些 Base learners 使用 scikit-learn 的決策樹作為樹型學習者,使用嶺回歸作為線性學習者。

  • 參數概率分布

參數概率分布是一種條件分布。這是由 Base learners 輸出的加法組合形成的。

  • 評分規則

評分規則採用預測的概率分布和對目標特徵的觀察來對預測結果進行評分,真實的結果分布期望值得到最好的分數。該演算法使用最大似然估計(MLE)或 CRPS(連續排序概率得分)。

我們剛剛介紹了 NGBoost 的基本概念。我建議你閱讀原稿以便進一步理解(用數學符號更容易理解演算法)。

2. 經驗驗證:與 LightGBM 和 XGBoost 的比較

billy lee 在 Unsplash 雜誌上的照片

讓我們實現 NGBoost,看看它的性能如何。論文還對各種數據集進行了實驗。他們比較了 MC-dropout、Deep-Ensembles 和 NGBoost 在回歸問題中的表現,NGBoost 表現出了很強的競爭力。在這篇博文中,我想展示一下這個模型在 Kaggle 上著名的房價預測數據集上的性能。這個數據集包含 81 個特徵,1460 行,目標是預測銷售價格。讓我們看看 NGBoost 如何處理這些情況。

目標特徵的分布

由於測試演算法的性能是本文的目的,我們將跳過整個特徵工程部分,並將使用 Nanashi 的解決方案。

導入包:

# import packages  import pandas as pd    from ngboost.ngboost import NGBoost  from ngboost.learners import default_tree_learner  from ngboost.distns import Normal  from ngboost.scores    import MLE import lightgbm as lgb    import xgboost as xgb    from sklearn.model_selection import train_test_split  from sklearn.metrics import mean_squared_error  from math import sqrt

在這裡,我將使用上面的默認學習者、分布和評分規則,看看結果如何變化。

# read the dataset  df = pd.read_csv('~/train.csv')  # feature engineering  tr, te = Nanashi_solution(df)

現在使用 NGBoost 演算法進行預測。

# NGBoost  ngb = NGBoost(Base=default_tree_learner, Dist=Normal, Score=MLE(),  natural_gradient=True,verbose=False)    ngboost = ngb.fit(np.asarray(tr.drop(['SalePrice'],1)),  np.asarray(tr.SalePrice))    y_pred_ngb = pd.DataFrame(ngb.predict(te.drop(['SalePrice'],1)))

對 LightGBM 和 XGBoost 也做一樣的事情:

# LightGBM  ltr = lgb.Dataset(tr.drop(['SalePrice'],1),label=tr['SalePrice'])    param = {  'bagging_freq': 5,  'bagging_fraction': 0.6,  'bagging_seed': 123,  'boost_from_average':'false',  'boost': 'gbdt',  'feature_fraction': 0.3,  'learning_rate': .01,  'max_depth': 3,  'metric':'rmse',  'min_data_in_leaf': 128,  'min_sum_hessian_in_leaf': 8,  'num_leaves': 128, 'num_threads': 8,  'tree_learner': 'serial',  'objective': 'regression',  'verbosity': -1,  'random_state':123,  'max_bin': 8,  'early_stopping_round':100  }      lgbm = lgb.train(param,ltr,num_boost_round=10000,valid_sets= [(ltr)],verbose_eval=1000)    y_pred_lgb = lgbm.predict(te.drop(['SalePrice'],1))  y_pred_lgb = np.where(y_pred>=.25,1,0)    # XGBoost  params = {  'max_depth': 4, 'eta': 0.01,  'objective':'reg:squarederror',  'eval_metric': ['rmse'],  'booster':'gbtree',  'verbosity':0,  'sample_type':'weighted',  'max_delta_step':4,  'subsample':.5,  'min_child_weight':100,  'early_stopping_round':50  }    dtr, dte = xgb.DMatrix(tr.drop(['SalePrice'],1),label=tr.SalePrice),  xgb.DMatrix(te.drop(['SalePrice'],1),label=te.SalePrice)    num_round = 5000  xgbst = xgb.train(params,dtr,num_round,verbose_eval=500)    y_pred_xgb = xgbst.predict(dte)

現在我們用所有演算法進行了預測。讓我們檢查一下它們的準確性。我們將使用與這次 kaggle 競賽相同的標準,RMSE。

# Check the results  print('RMSE: NGBoost',  round(sqrt(mean_squared_error(X_val.SalePrice,y_pred_ngb)),4))  print('RMSE: LGBM',  round(sqrt(mean_squared_error(X_val.SalePrice,y_pred_lgbm)),4))  print('RMSE: XGBoost',  round(sqrt(mean_squared_error(X_val.SalePrice,y_pred_xgb)),4))

以下是預測結果的總結。

預測結果總結

看來 NGBoost 的性能優於其他著名的 boosting 演算法。公平地說,我覺得如果我調整 BGBoost 的參數,它會更好。

NGBoost 與其他 boosting 演算法最大的區別之一是可以返回每個預測的概率分布。這可以通過使用 pred_dist 函數可視化。此函數能夠顯示概率預測的結果。

# see the probability distributions by visualising  Y_dists = ngb.pred_dist(X_val.drop(['SalePrice'],1))  y_range = np.linspace(min(X_val.SalePrice), max(X_val.SalePrice), 200)  dist_values = Y_dists.pdf(y_range).transpose()    # plot index 0 and 114  idx = 114  plt.plot(y_range,dist_values[idx])  plt.title(f"idx: {idx}")  plt.tight_layout()  plt.show()

概率分布示例

上面的圖表是每個預測的概率分布。X 軸顯示銷售價格的日誌值(目標特徵)。我們可以觀察到,指數 0 的概率分布比指數 114 的更寬。

3. 結論與思考

從實驗結果可以看出,NGBoost 演算法與其他著名的 boosting 演算法具有相同的性能。然而,計算時間比其他兩種演算法要長得多。這可以通過使用子取樣方法來改進。此外,在我的印象中,NGBost 包仍在開發中,例如,沒有提前停止選項,沒有顯示中間結果的選項,選擇 Base leaners 的靈活性(到目前為止,我們只能在決策樹和嶺回歸之間選擇),設置一個隨機狀態種子,等等。我相信這些要點將很快得到落實。

你也可以在我的 GitHub 頁面上找到我在這篇文章中使用的程式碼:https://github.com/kyosek/NGBoost-experiments

總結

  • NGBoost 是一種返回概率分布的 boosting 演算法。
  • 自然梯度增強,一種用於概率預測的模組化增強演算法。這包括 Base leaners、參數概率分布和評分規則。
  • NGBoost 預測與其他流行的 boosting 演算法相比具有很大的競爭力。

參考文獻:

[1] T. Duan, et al., NGBoost: Natural Gradient Boosting for Probabilistic Prediction (2019), ArXiv 1910.03225