引言
LightGBM是微軟開發(fā)的boosting集成模型,和XGBoost一樣是對GBDT的優(yōu)化和高效實現(xiàn),原理有一些相似之處,但它很多方面比XGBoost有著更為優(yōu)秀的表現(xiàn)。
本篇內(nèi)容ShowMeAI展開給大家講解LightGBM的工程應(yīng)用方法,對于LightGBM原理知識感興趣的同學,歡迎參考ShowMeAI的另外一篇文章 圖解機器學習 | LightGBM模型詳解。
1.LightGBM安裝
LightGBM作為常見的強大Python機器學習工具庫,安裝也比較簡單。
1.1 Python與IDE環(huán)境設(shè)置
python環(huán)境與IDE設(shè)置可以參考ShowMeAI文章 圖解python | 安裝與環(huán)境設(shè)置 進行設(shè)置。

1.2 工具庫安裝
(1) Linux/Mac等系統(tǒng)
這些系統(tǒng)下的XGBoost安裝,大家只要基于pip就可以輕松完成了,在命令行端輸入命令如下命令即可等待安裝完成。
pip install lightgbm
大家也可以選擇國內(nèi)的pip源,以獲得更好的安裝速度:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple lightgbm
(2) Windows系統(tǒng)
對于windows系統(tǒng)而言,比較高效便捷的安裝方式是:在網(wǎng)址http://www.lfd.uci.edu/~gohlke/pythonlibs/ 中去下載對應(yīng)版本的的LightGBM安裝包,再通過如下命令安裝。
pip install lightgbm?3.3.2?cp310?cp310?win_amd64.whl
2.LightGBM參數(shù)手冊
在ShowMeAI的前一篇內(nèi)容 XGBoost工具庫建模應(yīng)用詳解 中,我們講解到了Xgboost的三類參數(shù)通用參數(shù),學習目標參數(shù),Booster參數(shù)。而LightGBM可調(diào)參數(shù)更加豐富,包含核心參數(shù),學習控制參數(shù),IO參數(shù),目標參數(shù),度量參數(shù),網(wǎng)絡(luò)參數(shù),GPU參數(shù),模型參數(shù),這里我常修改的便是核心參數(shù),學習控制參數(shù),度量參數(shù)等。下面我們對這些模型參數(shù)做展開講解,更多的細節(jié)可以參考LightGBM中文文檔。
2.1 參數(shù)介紹
(1) 核心參數(shù)
config或者config_file:一個字符串,給出了配置文件的路徑。默認為空字符串。-
task:一個字符串,給出了要執(zhí)行的任務(wù)??梢詾椋?/p>-
train或者training:表示是訓練任務(wù)。默認為train。 -
predict或者prediction或者test:表示是預(yù)測任務(wù)。 -
convert_model:表示是模型轉(zhuǎn)換任務(wù)。將模型文件轉(zhuǎn)換成if-else格式。
-
-
application或者objective或者app:一個字符串,表示問題類型??梢詾椋?/p>-
regression或regression_l2或mean_squared_error或mse或l2_root或root_mean_squred_error或rmse:表示回歸任務(wù),但是使用L2損失函數(shù)。默認為regression。 -
regression_l1或者mae或者mean_absolute_error:表示回歸任務(wù),但是使用L1損失函數(shù)。 -
huber:表示回歸任務(wù),但是使用huber損失函數(shù)。 -
fair:表示回歸任務(wù),但是使用fair損失函數(shù)。 -
poisson:表示Poisson回歸任務(wù)。 -
quantile:表示quantile回歸任務(wù)。 -
quantile_l2:表示quantile回歸任務(wù),但是使用了L2損失函數(shù)。 -
mape或者mean_absolute_precentage_error:表示回歸任務(wù),但是使用MAPE損失函數(shù) -
gamma:表示gamma回歸任務(wù)。 -
tweedie:表示tweedie回歸任務(wù)。 -
binary:表示二分類任務(wù),使用對數(shù)損失函數(shù)作為目標函數(shù)。 -
multiclass:表示多分類任務(wù),使用softmax函數(shù)作為目標函數(shù)。必須設(shè)置num_class參數(shù) -
multiclassova或者multiclass_ova或者ova或者ovr:表示多分類任務(wù),使用one-vs-all的二分類目標函數(shù)。必須設(shè)置num_class參數(shù)。 -
xentropy或者cross_entropy:目標函數(shù)為交叉熵(同時具有可選擇的線性權(quán)重)。要求標簽是[0,1]之間的數(shù)值。 -
xentlambda或者cross_entropy_lambda:替代了參數(shù)化的cross_entropy。要求標簽是[0,1]之間的數(shù)值。 -
lambdarank:表示排序任務(wù)。在lambdarank任務(wù)中,標簽應(yīng)該為整數(shù)類型,數(shù)值越大表示相關(guān)性越高。label_gain參數(shù)可以用于設(shè)置整數(shù)標簽的增益(權(quán)重)。
-
-
boosting或者boost或者boosting_type:一個字符串,給出了基學習器模型算法??梢詾椋?/p>-
gbdt:表示傳統(tǒng)的梯度提升決策樹。默認值為gbdt。 -
rf:表示隨機森林。 -
dart:表示帶dropout的gbdt。 -
goss:表示Gradient-based One-Side Sampling 的gbdt。
-
data或者train或者train_data:一個字符串,給出了訓練數(shù)據(jù)所在的文件的文件名。默認為空字符串。LightGBM將使用它來訓練模型。valid或者test或者valid_data或者test_data:一個字符串,表示驗證集所在的文件的文件名。默認為空字符串。LightGBM將輸出該數(shù)據(jù)集的度量。如果有多個驗證集,則用逗號分隔。-
num_iterations或者num_iteration或者num_tree或者num_trees或者num_round或者num_rounds或者num_boost_round一個整數(shù),給出了boosting的迭代次數(shù)。默認為100。- 對于Python/R包,該參數(shù)是被忽略的。對于Python,使用
train()/cv()的輸入?yún)?shù)num_boost_round來代替。 - 在內(nèi)部,LightGBM對于multiclass問題設(shè)置了
num_class*num_iterations棵樹。
- 對于Python/R包,該參數(shù)是被忽略的。對于Python,使用
learning_rate或者shrinkage_rate:個浮點數(shù),給出了學習率。默認為1。在dart中,它還會影響dropped trees的歸一化權(quán)重。num_leaves或者num_leaf:一個整數(shù),給出了一棵樹上的葉子數(shù)。默認為31。-
tree_learner或者tree:一個字符串,給出了tree learner,主要用于并行學習。默認為serial??梢詾椋?/p>-
serial:單臺機器的tree learner -
feature:特征并行的tree learner -
data:數(shù)據(jù)并行的tree learner -
voting:投票并行的tree learner
-
-
num_threads或者num_thread或者nthread:一個整數(shù),給出了LightGBM的線程數(shù)。默認為OpenMP_default。- 為了更快的速度,應(yīng)該將它設(shè)置為真正的CPU內(nèi)核數(shù),而不是線程的數(shù)量(大多數(shù)CPU使用超線程來使每個CPU內(nèi)核生成2個線程)。
- 當數(shù)據(jù)集較小的時候,不要將它設(shè)置的過大。
- 對于并行學習,不應(yīng)該使用全部的CPU核心,因為這會使得網(wǎng)絡(luò)性能不佳。
-
device:一個字符串,指定計算設(shè)備。默認為cpu??梢詾?code>gpu、cpu。- 建議使用較小的
max_bin來獲得更快的計算速度。 - 為了加快學習速度,GPU默認使用32位浮點數(shù)來求和。你可以設(shè)置
gpu_use_dp=True來啟動64位浮點數(shù),但是它會使得訓練速度降低。
- 建議使用較小的
(2) 學習控制參數(shù)
-
max_depth:一個整數(shù),限制了樹模型的最大深度,默認值為-1。如果小于0,則表示沒有限制。 -
min_data_in_leaf或者min_data_per_leaf或者min_data或者min_child_samples:一個整數(shù),表示一個葉子節(jié)點上包含的最少樣本數(shù)量。默認值為20。 -
min_sum_hessian_in_leaf或者min_sum_hessian_per_leaf或者min_sum_hessian或者min_hessian或者min_child_weight:一個浮點數(shù),表示一個葉子節(jié)點上的最小hessian之和。(也就是葉節(jié)點樣本權(quán)重之和的最小值)默認為1e-3。 -
feature_fraction或者sub_feature或者colsample_bytree:一個浮點數(shù),取值范圍為[0.0,1.0],默認值為0。如果小于1.0,則LightGBM會在每次迭代中隨機選擇部分特征。如0.8表示:在每棵樹訓練之前選擇80%的特征來訓練。 -
feature_fraction_seed:一個整數(shù),表示feature_fraction的隨機數(shù)種子,默認為2。 -
bagging_fraction或者sub_row或者subsample:一個浮點數(shù),取值范圍為[0.0,1.0],默認值為0。如果小于1.0,則LightGBM會在每次迭代中隨機選擇部分樣本來訓練(非重復采樣)。如0.8表示:在每棵樹訓練之前選擇80%的樣本(非重復采樣)來訓練。 -
bagging_freq或者subsample_freq:一個整數(shù),表示每bagging_freq次執(zhí)行bagging。如果該參數(shù)為0,表示禁用bagging。 -
bagging_seed或者bagging_fraction_seed:一個整數(shù),表示bagging的隨機數(shù)種子,默認為3。 -
early_stopping_round或者early_stopping_rounds或者early_stopping:一個整數(shù),默認為0。如果一個驗證集的度量在early_stopping_round循環(huán)中沒有提升,則停止訓練。如果為0則表示不開啟早停。 -
lambda_l1或者reg_alpha:一個浮點數(shù),表示L1正則化系數(shù)。默認為0。 -
lambda_l2或者reg_lambda:一個浮點數(shù),表示L2正則化系數(shù)。默認為0。 -
min_split_gain或者min_gain_to_split:一個浮點數(shù),表示執(zhí)行切分的最小增益,默認為0。 -
drop_rate:一個浮點數(shù),取值范圍為[0.0,1.0],表示dropout的比例,默認為1。該參數(shù)僅在dart中使用。 -
skip_drop:一個浮點數(shù),取值范圍為[0.0,1.0],表示跳過dropout的概率,默認為5。該參數(shù)僅在dart中使用。 -
max_drop:一個整數(shù),表示一次迭代中刪除樹的最大數(shù)量,默認為50。如果小于等于0,則表示沒有限制。該參數(shù)僅在dart中使用。 -
uniform_drop:一個布爾值,表示是否想要均勻的刪除樹,默認值為False。該參數(shù)僅在dart中使用。 -
xgboost_dart_mode:一個布爾值,表示是否使用xgboost dart模式,默認值為False。該參數(shù)僅在dart中使用。 -
drop_seed:一個整數(shù),表示dropout的隨機數(shù)種子,默認值為4。該參數(shù)僅在dart中使用。 -
top_rate:一個浮點數(shù),取值范圍為[0.0,1.0],表示在goss中,大梯度數(shù)據(jù)的保留比例,默認值為2。該參數(shù)僅在goss中使用。 -
other_rate:一個浮點數(shù),取值范圍為[0.0,1.0],表示在goss中,小梯度數(shù)據(jù)的保留比例,默認值為1。該參數(shù)僅在goss中使用。 -
min_data_per_group:一個整數(shù),表示每個分類組的最小數(shù)據(jù)量,默認值為100。用于排序任務(wù) -
max_cat_threshold:一個整數(shù),表示category特征的取值集合的最大大小。默認為32。 -
cat_smooth:一個浮點數(shù),用于category特征的概率平滑。默認值為10。它可以降低噪聲在category特征中的影響,尤其是對于數(shù)據(jù)很少的類。 -
cat_l2:一個浮點數(shù),用于category切分中的L2正則化系數(shù)。默認為10。 -
top_k或者topk:一個整數(shù),用于投票并行中。默認為20。將它設(shè)置為更大的值可以獲得更精確的結(jié)果,但是會降低訓練速度。
(3) IO參數(shù)
-
max_bin:一個整數(shù),表示最大的桶的數(shù)量。默認值為255。LightGBM會根據(jù)它來自動壓縮內(nèi)存。如max_bin=255時,則LightGBM將使用uint8來表示特征的每一個值。 -
min_data_in_bin:一個整數(shù),表示每個桶的最小樣本數(shù)。默認為3。該方法可以避免出現(xiàn)一個桶只有一個樣本的情況。 -
data_random_seed:一個整數(shù),表示并行學習數(shù)據(jù)分隔中的隨機數(shù)種子。默認為1它不包括特征并行。 -
output_model或者model_output或者model_out:一個字符串,表示訓練中輸出的模型被保存的文件的文件名。默認txt。 -
input_model或者model_input或者model_in:一個字符串,表示輸入模型的文件的文件名。默認空字符串。對于prediction任務(wù),該模型將用于預(yù)測數(shù)據(jù),對于train任務(wù),訓練將從該模型繼續(xù) -
output_result或者predict_result或者prediction_result:一個字符串,給出了prediction結(jié)果存放的文件名。默認為txt。 -
pre_partition或者is_pre_partition:一個布爾值,指示數(shù)據(jù)是否已經(jīng)被劃分。默認值為False。如果為true,則不同的機器使用不同的partition來訓練。它用于并行學習(不包括特征并行) -
is_sparse或者is_enable_sparse或者enable_sparse:一個布爾值,表示是否開啟稀疏優(yōu)化,默認為True。如果為True則啟用稀疏優(yōu)化。 -
two_round或者two_round_loading或者use_two_round_loading:一個布爾值,指示是否啟動兩次加載。默認值為False,表示只需要進行一次加載。默認情況下,LightGBM會將數(shù)據(jù)文件映射到內(nèi)存,然后從內(nèi)存加載特征,這將提供更快的數(shù)據(jù)加載速度。但是當數(shù)據(jù)文件很大時,內(nèi)存可能會被耗盡。如果數(shù)據(jù)文件太大,則將它設(shè)置為True -
save_binary或者is_save_binary或者is_save_binary_file:一個布爾值,表示是否將數(shù)據(jù)集(包括驗證集)保存到二進制文件中。默認值為False。如果為True,則可以加快數(shù)據(jù)的加載速度。 -
verbosity或者verbose:一個整數(shù),表示是否輸出中間信息。默認值為1。如果小于0,則僅僅輸出critical信息;如果等于0,則還會輸出error,warning信息;如果大于0,則還會輸出info信息。 -
header或者has_header:一個布爾值,表示輸入數(shù)據(jù)是否有頭部。默認為False。 -
label或者label_column:一個字符串,表示標簽列。默認為空字符串。你也可以指定一個整數(shù),如label=0表示第0列是標簽列。你也可以為列名添加前綴,如label=prefix:label_name。 -
weight或者weight_column:一個字符串,表示樣本權(quán)重列。默認為空字符串。你也可以指定一個整數(shù),如weight=0表示第0列是權(quán)重列。注意:它是剔除了標簽列之后的索引。假如標簽列為0,權(quán)重列為1,則這里weight=0。你也可以為列名添加前綴,如weight=prefix:weight_name。 -
query或者query_column或者gourp或者group_column:一個字符串,query/groupID列。默認為空字符串。你也可以指定一個整數(shù),如query=0表示第0列是query列。注意:它是剔除了標簽列之后的索引。假如標簽列為0,query列為1,則這里query=0。你也可以為列名添加前綴,如query=prefix:query_name。 -
ignore_column或者ignore_feature或者blacklist:一個字符串,表示訓練中忽略的一些列,默認為空字符串??梢杂脭?shù)字做索引,如ignore_column=0,1,2表示第0,1,2列將被忽略。注意:它是剔除了標簽列之后的索引。 - 你也可以為列名添加前綴,如
ignore_column=prefix:ign_name1,ign_name2。 -
categorical_feature或者categorical_column或者cat_feature或者cat_column:一個字符串,指定category特征的列。默認為空字符串??梢杂脭?shù)字做索引,如categorical_feature=0,1,2表示第0,1,2列將作為category特征。注意:它是剔除了標簽列之后的索引。你也可以為列名添加前綴,如categorical_feature=prefix:cat_name1,cat_name2在categorycal特征中,負的取值被視作缺失值。 -
predict_raw_score或者raw_score或者is_predict_raw_score:一個布爾值,表示是否預(yù)測原始得分。默認為False。如果為True則僅預(yù)測原始得分。該參數(shù)只用于prediction任務(wù)。 -
predict_leaf_index或者leaf_index或者is_predict_leaf_index:一個布爾值,表示是否預(yù)測每個樣本在每棵樹上的葉節(jié)點編號。默認為False。在預(yù)測時,每個樣本都會被分配到每棵樹的某個葉子節(jié)點上。該參數(shù)就是要輸出這些葉子節(jié)點的編號。該參數(shù)只用于prediction任務(wù)。 -
predict_contrib或者contrib或者is_predict_contrib:一個布爾值,表示是否輸出每個特征對于每個樣本的預(yù)測的貢獻。默認為False。輸出的結(jié)果形狀為[nsamples,nfeatures+1],之所以+1是考慮到bais的貢獻。所有的貢獻加起來就是該樣本的預(yù)測結(jié)果。該參數(shù)只用于prediction任務(wù)。 -
bin_construct_sample_cnt或者subsample_for_bin:一個整數(shù),表示用來構(gòu)建直方圖的樣本的數(shù)量。默認為200000。如果數(shù)據(jù)非常稀疏,則可以設(shè)置為一個更大的值,如果設(shè)置更大的值,則會提供更好的訓練效果,但是會增加數(shù)據(jù)加載時間。 -
num_iteration_predict:一個整數(shù),表示在預(yù)測中使用多少棵子樹。默認為-1。小于等于0表示使用模型的所有子樹。該參數(shù)只用于prediction任務(wù)。 -
pred_early_stop:一個布爾值,表示是否使用早停來加速預(yù)測。默認為False。如果為True,則可能影響精度。 -
pred_early_stop_freq:一個整數(shù),表示檢查早停的頻率。默認為10 -
pred_early_stop_margin:一個浮點數(shù),表示早停的邊際閾值。默認為0 -
use_missing:一個布爾值,表示是否使用缺失值功能。默認為True如果為False則禁用缺失值功能。 -
zero_as_missing:一個布爾值,表示是否將所有的零(包括在libsvm/sparse矩陣中未顯示的值)都視為缺失值。默認為False。如果為False,則將nan視作缺失值。如果為True,則np.nan和零都將視作缺失值。 -
init_score_file:一個字符串,表示訓練時的初始化分數(shù)文件的路徑。默認為空字符串,表示train_data_file+”.init”(如果存在) -
valid_init_score_file:一個字符串,表示驗證時的初始化分數(shù)文件的路徑。默認為空字符串,表示valid_data_file+”.init”(如果存在)。如果有多個(對應(yīng)于多個驗證集),則可以用逗號,來分隔。
(4) 目標參數(shù)
-
sigmoid:一個浮點數(shù),用sigmoid函數(shù)的參數(shù),默認為0。它用于二分類任務(wù)和lambdarank任務(wù)。 -
alpha:一個浮點數(shù),用于Huber損失函數(shù)和Quantileregression,默認值為0。它用于huber回歸任務(wù)和Quantile回歸任務(wù)。 -
fair_c:一個浮點數(shù),用于Fair損失函數(shù),默認值為0。它用于fair回歸任務(wù)。 -
gaussian_eta:一個浮點數(shù),用于控制高斯函數(shù)的寬度,默認值為0。它用于regression_l1回歸任務(wù)和huber回歸任務(wù)。 -
posson_max_delta_step:一個浮點數(shù),用于Poisson regression的參數(shù),默認值為7。它用于poisson回歸任務(wù)。 -
scale_pos_weight:一個浮點數(shù),用于調(diào)整正樣本的權(quán)重,默認值為0它用于二分類任務(wù)。 -
boost_from_average:一個布爾值,指示是否將初始得分調(diào)整為平均值(它可以使得收斂速度更快)。默認為True。它用于回歸任務(wù)。 -
is_unbalance或者unbalanced_set:一個布爾值,指示訓練數(shù)據(jù)是否均衡的。默認為True。它用于二分類任務(wù)。 -
max_position:一個整數(shù),指示將在這個NDCG位置優(yōu)化。默認為20。它用于lambdarank任務(wù)。 -
label_gain:一個浮點數(shù)序列,給出了每個標簽的增益。默認值為0,1,3,7,15,….它用于lambdarank任務(wù)。 -
num_class或者num_classes:一個整數(shù),指示了多分類任務(wù)中的類別數(shù)量。默認為1它用于多分類任務(wù)。 -
reg_sqrt:一個布爾值,默認為False。如果為True,則擬合的結(jié)果為:\sqrt{label}。同時預(yù)測的結(jié)果被自動轉(zhuǎn)換為:{pred}^2。它用于回歸任務(wù)。
(5) 度量參數(shù)
-
metric:一個字符串,指定了度量的指標,默認為:對于回歸問題,使用l2;對于二分類問題,使用binary_logloss;對于lambdarank問題,使用ndcg。如果有多個度量指標,則用逗號,分隔。-
l1或者mean_absolute_error或者mae或者regression_l1:表示絕對值損失。 -
l2或者mean_squared_error或者mse或者regression_l2或者regression:表示平方損失。 -
l2_root或者root_mean_squared_error或者rmse:表示開方損失。 -
quantile:表示Quantile回歸中的損失。 -
mape或者mean_absolute_percentage_error:表示MAPE損失。 -
huber:表示huber損失。 -
fair:表示fair損失。 -
poisson:表示poisson回歸的負對數(shù)似然。 -
gamma:表示gamma回歸的負對數(shù)似然。 -
gamma_deviance:表示gamma回歸的殘差的方差。 -
tweedie:表示Tweedie回歸的負對數(shù)似然。 -
ndcg:表示NDCG。 -
map或者mean_average_precision:表示平均的精度。 -
auc:表示AUC。 -
binary_logloss或者binary:表示二類分類中的對數(shù)損失函數(shù)。 -
binary_error:表示二類分類中的分類錯誤率。 -
multi_logloss或者multiclass或者softmax或者‘multiclassova或者multiclass_ova,或者ova或者ovr`:表示多類分類中的對數(shù)損失函數(shù)。 -
multi_error:表示多分類中的分類錯誤率。 -
xentropy或者cross_entropy:表示交叉熵。 -
xentlambda或者cross_entropy_lambda:表示intensity加權(quán)的交叉熵。 -
kldiv或者kullback_leibler:表示KL散度。
-
-
metric_freq或者output_freq:一個正式,表示每隔多少次輸出一次度量結(jié)果。默認為1。 -
train_metric或者training_metric或者is_training_metric:一個布爾值,默認為False。如果為True,則在訓練時就輸出度量結(jié)果。 -
ndcg_at或者ndcg_eval_at或者eval_at:一個整數(shù)列表,指定了NDCG評估點的位置。默認為1、2、3、4、5。
2.2 參數(shù)影響與調(diào)參建議
以下為總結(jié)的核心參數(shù)對模型的影響,及與之對應(yīng)的調(diào)參建議。
(1) 對樹生長控制

-
num_leaves:葉節(jié)點的數(shù)目。它是控制樹模型復雜度的主要參數(shù)。- 如果是
level-wise,則該參數(shù)為,其中depth為樹的深度。但是當葉子數(shù)量相同時,leaf-wise的樹要遠遠深過level-wise樹,非常容易導致過擬合。因此應(yīng)該讓num_leaves小于
。在leaf-wise樹中,并不存在depth的概念。因為不存在一個從leaves到depth的合理映射。
- 如果是
-
min_data_in_leaf:每個葉節(jié)點的最少樣本數(shù)量。- 它是處理
leaf-wise樹的過擬合的重要參數(shù)。將它設(shè)為較大的值,可以避免生成一個過深的樹。但是也可能導致欠擬合。
- 它是處理
-
max_depth:樹的最大深度。該參數(shù)可以顯式的限制樹的深度。
(2) 更快的訓練速度

- 通過設(shè)置
bagging_fraction和bagging_freq參數(shù)來使用bagging方法。 - 通過設(shè)置
feature_fraction參數(shù)來使用特征的子抽樣。 - 使用較小的
max_bin。 - 使用
save_binary在未來的學習過程對數(shù)據(jù)加載進行加速。
(3) 更好的模型效果

- 使用較大的
max_bin(學習速度可能變慢)。 - 使用較小的
learning_rate和較大的num_iterations。 - 使用較大的
num_leaves(可能導致過擬合)。 - 使用更大的訓練數(shù)據(jù)。
- 嘗試
dart。
(4) 緩解過擬合問題

- 使用較小的
max_bin。 - 使用較小的
num_leaves。 - 使用
min_data_in_leaf和min_sum_hessian_in_leaf。 - 通過設(shè)置
bagging_fraction和bagging_freq來使用bagging。 - 通過設(shè)置
feature_fraction來使用特征子抽樣。 - 使用更大的訓練數(shù)據(jù)。
- 使用
lambda_l1、lambda_l2和min_gain_to_split來使用正則。 - 嘗試
max_depth來避免生成過深的樹。
3.LightGBM內(nèi)置建模方式
3.1 內(nèi)置建模方式
LightGBM內(nèi)置了建模方式,有如下的數(shù)據(jù)格式與核心訓練方法:
- 基于
lightgbm.Dataset格式的數(shù)據(jù)。 - 基于
lightgbm.train接口訓練。
下面是官方的一個簡單示例,演示了讀取libsvm格式數(shù)據(jù)(成Dataset格式)并指定參數(shù)建模的過程。
# coding: utf-8
import json
import lightgbm as lgb
import pandas as pd
from sklearn.metrics import mean_squared_error
# 加載數(shù)據(jù)集合
print('加載數(shù)據(jù)...')
df_train = pd.read_csv('./data/regression.train.txt', header=None, sep='\t')
df_test = pd.read_csv('./data/regression.test.txt', header=None, sep='\t')
# 設(shè)定訓練集和測試集
y_train = df_train[0].values
y_test = df_test[0].values
X_train = df_train.drop(0, axis=1).values
X_test = df_test.drop(0, axis=1).values
# 構(gòu)建lgb中的Dataset格式
lgb_train = lgb.Dataset(X_train, y_train)
lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train)
# 敲定好一組參數(shù)
params = {
'task': 'train',
'boosting_type': 'gbdt',
'objective': 'regression',
'metric': {'l2', 'auc'},
'num_leaves': 31,
'learning_rate': 0.05,
'feature_fraction': 0.9,
'bagging_fraction': 0.8,
'bagging_freq': 5,
'verbose': 0
}
print('開始訓練...')
# 訓練
gbm = lgb.train(params,
lgb_train,
num_boost_round=20,
valid_sets=lgb_eval,
early_stopping_rounds=5)
# 保存模型
print('保存模型...')
# 保存模型到文件中
gbm.save_model('model.txt')
print('開始預(yù)測...')
# 預(yù)測
y_pred = gbm.predict(X_test, num_iteration=gbm.best_iteration)
# 評估
print('預(yù)估結(jié)果的rmse為:')
print(mean_squared_error(y_test, y_pred) ** 0.5)

加載數(shù)據(jù)...
開始訓練...
[1] valid_0's l2: 0.24288 valid_0's auc: 0.764496
Training until validation scores don't improve for 5 rounds.
[2] valid_0's l2: 0.239307 valid_0's auc: 0.766173
[3] valid_0's l2: 0.235559 valid_0's auc: 0.785547
[4] valid_0's l2: 0.230771 valid_0's auc: 0.797786
[5] valid_0's l2: 0.226297 valid_0's auc: 0.805155
[6] valid_0's l2: 0.223692 valid_0's auc: 0.800979
[7] valid_0's l2: 0.220941 valid_0's auc: 0.806566
[8] valid_0's l2: 0.217982 valid_0's auc: 0.808566
[9] valid_0's l2: 0.215351 valid_0's auc: 0.809041
[10] valid_0's l2: 0.213064 valid_0's auc: 0.805953
[11] valid_0's l2: 0.211053 valid_0's auc: 0.804631
[12] valid_0's l2: 0.209336 valid_0's auc: 0.802922
[13] valid_0's l2: 0.207492 valid_0's auc: 0.802011
[14] valid_0's l2: 0.206016 valid_0's auc: 0.80193
Early stopping, best iteration is:
[9] valid_0's l2: 0.215351 valid_0's auc: 0.809041
保存模型...
開始預(yù)測...
預(yù)估結(jié)果的rmse為:
0.4640593794679212
3.2 設(shè)置樣本權(quán)重
LightGBM的建模非常靈活,它可以支持我們對于每個樣本設(shè)置不同的權(quán)重學習,設(shè)置的方式也非常簡單,我們需要提供給模型一組權(quán)重數(shù)組數(shù)據(jù),長度和樣本數(shù)一致。
如下是一個典型的例子,其中binary.train和binary.test讀取后加載為lightgbm.Dataset格式的輸入,而在lightgbm.Dataset的構(gòu)建參數(shù)中可以設(shè)置樣本權(quán)重(這個例子中是numpy array的形態(tài))。再基于lightgbm.train接口使用內(nèi)置建模方式訓練。
# coding: utf-8
import json
import lightgbm as lgb
import pandas as pd
import numpy as np
from sklearn.metrics import mean_squared_error
import warnings
warnings.filterwarnings("ignore")
# 加載數(shù)據(jù)集
print('加載數(shù)據(jù)...')
df_train = pd.read_csv('./data/binary.train', header=None, sep='\t')
df_test = pd.read_csv('./data/binary.test', header=None, sep='\t')
W_train = pd.read_csv('./data/binary.train.weight', header=None)[0]
W_test = pd.read_csv('./data/binary.test.weight', header=None)[0]
y_train = df_train[0].values
y_test = df_test[0].values
X_train = df_train.drop(0, axis=1).values
X_test = df_test.drop(0, axis=1).values
num_train, num_feature = X_train.shape
# 加載數(shù)據(jù)的同時加載權(quán)重
lgb_train = lgb.Dataset(X_train, y_train,
weight=W_train, free_raw_data=False)
lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train,
weight=W_test, free_raw_data=False)
# 設(shè)定參數(shù)
params = {
'boosting_type': 'gbdt',
'objective': 'binary',
'metric': 'binary_logloss',
'num_leaves': 31,
'learning_rate': 0.05,
'feature_fraction': 0.9,
'bagging_fraction': 0.8,
'bagging_freq': 5,
'verbose': 0
}
# 產(chǎn)出特征名稱
feature_name = ['feature_' + str(col) for col in range(num_feature)]
print('開始訓練...')
gbm = lgb.train(params,
lgb_train,
num_boost_round=10,
valid_sets=lgb_train, # 評估訓練集
feature_name=feature_name,
categorical_feature=[21])
加載數(shù)據(jù)...
開始訓練...
[1] training's binary_logloss: 0.68205
[2] training's binary_logloss: 0.673618
[3] training's binary_logloss: 0.665891
[4] training's binary_logloss: 0.656874
[5] training's binary_logloss: 0.648523
[6] training's binary_logloss: 0.641874
[7] training's binary_logloss: 0.636029
[8] training's binary_logloss: 0.629427
[9] training's binary_logloss: 0.623354
[10] training's binary_logloss: 0.617593
3.3 模型存儲與加載
上述建模過程得到的模型對象,可以通過save_model成員函數(shù)進行保存。保存好的模型可以通過lgb.Booster加載回內(nèi)存,并對測試集進行預(yù)測。
具體示例代碼如下:
# 查看特征名稱
print('完成10輪訓練...')
print('第7個特征為:')
print(repr(lgb_train.feature_name[6]))
# 存儲模型
gbm.save_model('./model/lgb_model.txt')
# 特征名稱
print('特征名稱:')
print(gbm.feature_name())
# 特征重要度
print('特征重要度:')
print(list(gbm.feature_importance()))
# 加載模型
print('加載模型用于預(yù)測')
bst = lgb.Booster(model_file='./model/lgb_model.txt')
# 預(yù)測
y_pred = bst.predict(X_test)
# 在測試集評估效果
print('在測試集上的rmse為:')
print(mean_squared_error(y_test, y_pred) ** 0.5)

完成10輪訓練...
第7個特征為:
'feature_6'
特征名稱:
['feature_0', 'feature_1', 'feature_2', 'feature_3', 'feature_4', 'feature_5', 'feature_6', 'feature_7', 'feature_8', 'feature_9', 'feature_10', 'feature_11', 'feature_12', 'feature_13', 'feature_14', 'feature_15', 'feature_16', 'feature_17', 'feature_18', 'feature_19', 'feature_20', 'feature_21', 'feature_22', 'feature_23', 'feature_24', 'feature_25', 'feature_26', 'feature_27']
特征重要度:
[8, 5, 1, 19, 7, 33, 2, 0, 2, 10, 5, 2, 0, 9, 3, 3, 0, 2, 2, 5, 1, 0, 36, 3, 33, 45, 29, 35]
加載模型用于預(yù)測
在測試集上的rmse為:
0.4629245607636925
3.4 繼續(xù)訓練
LightGBM為boosting模型,每一輪訓練會增加新的基學習器,LightGBM還支持基于現(xiàn)有模型和參數(shù)繼續(xù)訓練,無需每次從頭訓練。
如下是典型的示例,我們加載已經(jīng)訓練10輪(即10顆樹集成)的lgb模型,在此基礎(chǔ)上繼續(xù)訓練(在參數(shù)層面做了一些改變,調(diào)整了學習率,增加了一些bagging等緩解過擬合的處理方法)
# 繼續(xù)訓練
# 從./model/model.txt中加載模型初始化
gbm = lgb.train(params,
lgb_train,
num_boost_round=10,
init_model='./model/lgb_model.txt',
valid_sets=lgb_eval)
print('以舊模型為初始化,完成第 10-20 輪訓練...')
# 在訓練的過程中調(diào)整超參數(shù)
# 比如這里調(diào)整的是學習率
gbm = lgb.train(params,
lgb_train,
num_boost_round=10,
init_model=gbm,
learning_rates=lambda iter: 0.05 * (0.99 ** iter),
valid_sets=lgb_eval)
print('逐步調(diào)整學習率完成第 20-30 輪訓練...')
# 調(diào)整其他超參數(shù)
gbm = lgb.train(params,
lgb_train,
num_boost_round=10,
init_model=gbm,
valid_sets=lgb_eval,
callbacks=[lgb.reset_parameter(bagging_fraction=[0.7] * 5 + [0.6] * 5)])
print('逐步調(diào)整bagging比率完成第 30-40 輪訓練...')

[11] valid_0's binary_logloss: 0.616177
[12] valid_0's binary_logloss: 0.611792
[13] valid_0's binary_logloss: 0.607043
[14] valid_0's binary_logloss: 0.602314
[15] valid_0's binary_logloss: 0.598433
[16] valid_0's binary_logloss: 0.595238
[17] valid_0's binary_logloss: 0.592047
[18] valid_0's binary_logloss: 0.588673
[19] valid_0's binary_logloss: 0.586084
[20] valid_0's binary_logloss: 0.584033
以舊模型為初始化,完成第 10-20 輪訓練...
[21] valid_0's binary_logloss: 0.616177
[22] valid_0's binary_logloss: 0.611834
[23] valid_0's binary_logloss: 0.607177
[24] valid_0's binary_logloss: 0.602577
[25] valid_0's binary_logloss: 0.59831
[26] valid_0's binary_logloss: 0.595259
[27] valid_0's binary_logloss: 0.592201
[28] valid_0's binary_logloss: 0.589017
[29] valid_0's binary_logloss: 0.586597
[30] valid_0's binary_logloss: 0.584454
逐步調(diào)整學習率完成第 20-30 輪訓練...
[31] valid_0's binary_logloss: 0.616053
[32] valid_0's binary_logloss: 0.612291
[33] valid_0's binary_logloss: 0.60856
[34] valid_0's binary_logloss: 0.605387
[35] valid_0's binary_logloss: 0.601744
[36] valid_0's binary_logloss: 0.598556
[37] valid_0's binary_logloss: 0.595585
[38] valid_0's binary_logloss: 0.593228
[39] valid_0's binary_logloss: 0.59018
[40] valid_0's binary_logloss: 0.588391
逐步調(diào)整bagging比率完成第 30-40 輪訓練...
3.5 自定義損失函數(shù)
LightGBM支持在訓練過程中,自定義損失函數(shù)和評估準則,其中損失函數(shù)的定義需要返回損失函數(shù)一階和二階導數(shù)的計算方法,評估準則部分需要對數(shù)據(jù)的label和預(yù)估值進行計算。其中損失函數(shù)用于訓練過程中的樹結(jié)構(gòu)學習,而評估準則很多時候是用在驗證集上進行效果評估。
# 自定義損失函數(shù)需要提供損失函數(shù)的一階和二階導數(shù)形式
def loglikelood(preds, train_data):
labels = train_data.get_label()
preds = 1. / (1. + np.exp(-preds))
grad = preds - labels
hess = preds * (1. - preds)
return grad, hess
# 自定義評估函數(shù)
def binary_error(preds, train_data):
labels = train_data.get_label()
return 'error', np.mean(labels != (preds > 0.5)), False
gbm = lgb.train(params,
lgb_train,
num_boost_round=10,
init_model=gbm,
fobj=loglikelood,
feval=binary_error,
valid_sets=lgb_eval)
print('用自定義的損失函數(shù)與評估標準完成第40-50輪...')

[41] valid_0's binary_logloss: 0.614429 valid_0's error: 0.268
[42] valid_0's binary_logloss: 0.610689 valid_0's error: 0.26
[43] valid_0's binary_logloss: 0.606267 valid_0's error: 0.264
[44] valid_0's binary_logloss: 0.601949 valid_0's error: 0.258
[45] valid_0's binary_logloss: 0.597271 valid_0's error: 0.266
[46] valid_0's binary_logloss: 0.593971 valid_0's error: 0.276
[47] valid_0's binary_logloss: 0.591427 valid_0's error: 0.278
[48] valid_0's binary_logloss: 0.588301 valid_0's error: 0.284
[49] valid_0's binary_logloss: 0.586562 valid_0's error: 0.288
[50] valid_0's binary_logloss: 0.584056 valid_0's error: 0.288
用自定義的損失函數(shù)與評估標準完成第40-50輪...
4.LightGBM預(yù)估器形態(tài)接口
4.1 SKLearn形態(tài)預(yù)估器接口
和XGBoost一樣,LightGBM也支持用SKLearn中統(tǒng)一的預(yù)估器形態(tài)接口進行建模,如下為典型的參考案例,對于讀取為Dataframe格式的訓練集和測試集,可以直接使用LightGBM初始化LGBMRegressor進行fit擬合訓練。使用方法與接口,和SKLearn中其他預(yù)估器一致。
# coding: utf-8
import lightgbm as lgb
import pandas as pd
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import GridSearchCV
# 加載數(shù)據(jù)
print('加載數(shù)據(jù)...')
df_train = pd.read_csv('./data/regression.train.txt', header=None, sep='\t')
df_test = pd.read_csv('./data/regression.test.txt', header=None, sep='\t')
# 取出特征和標簽
y_train = df_train[0].values
y_test = df_test[0].values
X_train = df_train.drop(0, axis=1).values
X_test = df_test.drop(0, axis=1).values
print('開始訓練...')
# 初始化LGBMRegressor
gbm = lgb.LGBMRegressor(objective='regression',
num_leaves=31,
learning_rate=0.05,
n_estimators=20)
# 使用fit函數(shù)擬合
gbm.fit(X_train, y_train,
eval_set=[(X_test, y_test)],
eval_metric='l1',
early_stopping_rounds=5)
# 預(yù)測
print('開始預(yù)測...')
y_pred = gbm.predict(X_test, num_iteration=gbm.best_iteration_)
# 評估預(yù)測結(jié)果
print('預(yù)測結(jié)果的rmse是:')
print(mean_squared_error(y_test, y_pred) ** 0.5)

加載數(shù)據(jù)...
開始訓練...
[1] valid_0's l1: 0.491735
Training until validation scores don't improve for 5 rounds.
[2] valid_0's l1: 0.486563
[3] valid_0's l1: 0.481489
[4] valid_0's l1: 0.476848
[5] valid_0's l1: 0.47305
[6] valid_0's l1: 0.469049
[7] valid_0's l1: 0.465556
[8] valid_0's l1: 0.462208
[9] valid_0's l1: 0.458676
[10] valid_0's l1: 0.454998
[11] valid_0's l1: 0.452047
[12] valid_0's l1: 0.449158
[13] valid_0's l1: 0.44608
[14] valid_0's l1: 0.443554
[15] valid_0's l1: 0.440643
[16] valid_0's l1: 0.437687
[17] valid_0's l1: 0.435454
[18] valid_0's l1: 0.433288
[19] valid_0's l1: 0.431297
[20] valid_0's l1: 0.428946
Did not meet early stopping. Best iteration is:
[20] valid_0's l1: 0.428946
開始預(yù)測...
預(yù)測結(jié)果的rmse是:
0.4441153344254208
4.2 網(wǎng)格搜索調(diào)參
上面提到LightGBM的預(yù)估器接口,整體使用方法和SKLearn中其他預(yù)估器一致,所以我們也可以使用SKLearn中的超參數(shù)調(diào)優(yōu)方法來進行模型調(diào)優(yōu)。
如下是一個典型的網(wǎng)格搜索交法調(diào)優(yōu)超參數(shù)的代碼示例,我們會給出候選參數(shù)列表字典,通過GridSearchCV進行交叉驗證實驗評估,選出LightGBM在候選參數(shù)中最優(yōu)的超參數(shù)。
# 配合scikit-learn的網(wǎng)格搜索交叉驗證選擇最優(yōu)超參數(shù)
estimator = lgb.LGBMRegressor(num_leaves=31)
param_grid = {
'learning_rate': [0.01, 0.1, 1],
'n_estimators': [20, 40]
}
gbm = GridSearchCV(estimator, param_grid)
gbm.fit(X_train, y_train)
print('用網(wǎng)格搜索找到的最優(yōu)超參數(shù)為:')
print(gbm.best_params_)

用網(wǎng)格搜索找到的最優(yōu)超參數(shù)為:
{'learning_rate': 0.1, 'n_estimators': 40}
4.3 繪圖解釋
LightGBM支持對模型訓練進行可視化呈現(xiàn)與解釋,包括對于訓練過程中的損失函數(shù)取值與評估準則結(jié)果的可視化、訓練完成后特征重要度的排序與可視化、基學習器(比如決策樹)的可視化。
以下為參考代碼:
# coding: utf-8
import lightgbm as lgb
import pandas as pd
try:
import matplotlib.pyplot as plt
except ImportError:
raise ImportError('You need to install matplotlib for plotting.')
# 加載數(shù)據(jù)集
print('加載數(shù)據(jù)...')
df_train = pd.read_csv('./data/regression.train.txt', header=None, sep='\t')
df_test = pd.read_csv('./data/regression.test.txt', header=None, sep='\t')
# 取出特征和標簽
y_train = df_train[0].values
y_test = df_test[0].values
X_train = df_train.drop(0, axis=1).values
X_test = df_test.drop(0, axis=1).values
# 構(gòu)建lgb中的Dataset數(shù)據(jù)格式
lgb_train = lgb.Dataset(X_train, y_train)
lgb_test = lgb.Dataset(X_test, y_test, reference=lgb_train)
# 設(shè)定參數(shù)
params = {
'num_leaves': 5,
'metric': ('l1', 'l2'),
'verbose': 0
}
evals_result = {} # to record eval results for plotting
print('開始訓練...')
# 訓練
gbm = lgb.train(params,
lgb_train,
num_boost_round=100,
valid_sets=[lgb_train, lgb_test],
feature_name=['f' + str(i + 1) for i in range(28)],
categorical_feature=[21],
evals_result=evals_result,
verbose_eval=10)
print('在訓練過程中繪圖...')
ax = lgb.plot_metric(evals_result, metric='l1')
plt.show()
print('畫出特征重要度...')
ax = lgb.plot_importance(gbm, max_num_features=10)
plt.show()
print('畫出第84顆樹...')
ax = lgb.plot_tree(gbm, tree_index=83, figsize=(20, 8), show_info=['split_gain'])
plt.show()
#print('用graphviz畫出第84顆樹...')
#graph = lgb.create_tree_digraph(gbm, tree_index=83, name='Tree84')
#graph.render(view=True)

加載數(shù)據(jù)...
開始訓練...
[10] training's l2: 0.217995 training's l1: 0.457448 valid_1's l2: 0.21641 valid_1's l1: 0.456464
[20] training's l2: 0.205099 training's l1: 0.436869 valid_1's l2: 0.201616 valid_1's l1: 0.434057
[30] training's l2: 0.197421 training's l1: 0.421302 valid_1's l2: 0.192514 valid_1's l1: 0.417019
[40] training's l2: 0.192856 training's l1: 0.411107 valid_1's l2: 0.187258 valid_1's l1: 0.406303
[50] training's l2: 0.189593 training's l1: 0.403695 valid_1's l2: 0.183688 valid_1's l1: 0.398997
[60] training's l2: 0.187043 training's l1: 0.398704 valid_1's l2: 0.181009 valid_1's l1: 0.393977
[70] training's l2: 0.184982 training's l1: 0.394876 valid_1's l2: 0.178803 valid_1's l1: 0.389805
[80] training's l2: 0.1828 training's l1: 0.391147 valid_1's l2: 0.176799 valid_1's l1: 0.386476
[90] training's l2: 0.180817 training's l1: 0.388101 valid_1's l2: 0.175775 valid_1's l1: 0.384404
[100] training's l2: 0.179171 training's l1: 0.385174 valid_1's l2: 0.175321 valid_1's l1: 0.382929


參考資料
作者:韓信子@ShowMeAI
教程地址:http://www.showmeai.tech/tutorials/41
本文地址:http://www.showmeai.tech/article-detail/205
聲明:版權(quán)所有,轉(zhuǎn)載請聯(lián)系平臺與作者并注明出處
收藏ShowMeAI查看更多精彩內(nèi)容