1. 程式人生 > 其它 >史上最詳細的XGBoost實戰(下)

史上最詳細的XGBoost實戰(下)

作者:章華燕

編輯:田 旭

XGBoost 引數詳解

在執行XGboost之前,必須設定三種類型成熟:general parameters,booster parameters和task parameters:

  • General parameters 該引數引數控制在提升(boosting)過程中使用哪種booster,常用的booster有樹模型(tree)和線性模型(linear model)
  • Booster parameters 這取決於使用哪種booster
  • Task parameters 控制學習的場景,例如在迴歸問題中會使用不同的引數控制排序

01

General Parameters

  1. booster [default=gbtree] 有兩中模型可以選擇gbtree和gblinear。gbtree使用基於樹的模型進行提升計算,gblinear使用線性模型進行提升計算。預設值為gbtree。
  2. silent [default=0] 取0時表示打印出執行時資訊,取1時表示以緘默方式執行,不列印執行時資訊。預設值為0。
  3. nthread XGBoost執行時的執行緒數。預設值是當前系統可以獲得的最大執行緒數。
  4. num_pbuffer 預測緩衝區大小,通常設定為訓練例項的數目。緩衝用於儲存最後一步提升的預測結果,無需人為設定。
  5. num_feature Boosting過程中用到的特徵維數,設定為特徵個數。XGBoost會自動設定,無需人為設定。

02

Parameters for Tree Booster

  1. eta [default=0.3] 為了防止過擬合,更新過程中用到的收縮步長。在每次提升計算之後,演算法會直接獲得新特徵的權重。 eta通過縮減特徵的權重使提升計算過程更加保守。預設值為0.3 。 取值範圍為:[0,1]
  2. gamma [default=0] minimum loss reduction required to make a further partition on a leaf node of the tree. the larger, the more conservative the algorithm will be. 取值範圍為:[0,∞]
  3. max_depth [default=6] 數的最大深度。預設值為6。 取值範圍為:[1,∞]
  4. min_child_weight [default=1] 孩子節點中最小的樣本權重和。如果一個葉子節點的樣本權重和小於min_child_weight則拆分過程結束。在現行迴歸模型中,這個引數是指建立每個模型所需要的最小樣本數。該成熟越大演算法越conservative。 取值範圍為:[0,∞]
  5. max_delta_step [default=0] 我們允許每個樹的權重被估計的值。如果它的值被設定為0,意味著沒有約束;如果它被設定為一個正值,它能夠使得更新的步驟更加保守。通常這個引數是沒有必要的,但是如果在邏輯迴歸中類極其不平衡這時候他有可能會起到幫助作用。把它範圍設定為1-10之間也許能控制更新。 取值範圍為:[0,∞]
  6. subsample [default=1] 用於訓練模型的子樣本佔整個樣本集合的比例。如果設定為0.5則意味著XGBoost將隨機的從整個樣本集合中隨機的抽取出50%的子樣本建立樹模型,這能夠防止過擬合。 取值範圍為:(0,1]
  7. colsample_bytree [default=1] 在建立樹時對特徵取樣的比例。預設值為1。 取值範圍為:(0,1]

03

Parameter for Linear Booster

  1. lambda [default=0] L2 正則的懲罰係數
  2. alpha [default=0] L1 正則的懲罰係數
  3. lambda_bias 在偏置上的L2正則。預設值為0(在L1上沒有偏置項的正則,因為L1時偏置不重要)。

04

Task Parameters

  1. objective [ default=reg:linear ] 定義學習任務及相應的學習目標,可選的目標函式如下: “reg:linear” —— 線性迴歸。 “reg:logistic”—— 邏輯迴歸。 “binary:logistic”—— 二分類的邏輯迴歸問題,輸出為概率。 “binary:logitraw”—— 二分類的邏輯迴歸問題,輸出的結果為wTx。 “count:poisson”—— 計數問題的poisson迴歸,輸出結果為poisson分佈。在poisson迴歸中,max_delta_step的預設值為0.7。(used to safeguard optimization) “multi:softmax” –讓XGBoost採用softmax目標函式處理多分類問題,同時需要設定引數num_class(類別個數) “multi:softprob” –和softmax一樣,但是輸出的是ndata * nclass的向量,可以將該向量reshape成ndata行nclass列的矩陣。沒行資料表示樣本所屬於每個類別的概率。 “rank:pairwise” –set XGBoost to do ranking task by minimizing the pairwise loss。
  2. base_score [ default=0.5 ] 所有例項的初始化預測分數,全域性偏置;為了足夠的迭代次數,改變這個值將不會有太大的影響。
  3. eval_metric [ default according to objective ] 校驗資料所需要的評價指標,不同的目標函式將會有預設的評價指標(rmse for regression, and error for classification, mean average precision for ranking)。 使用者可以新增多種評價指標,對於Python使用者要以list傳遞引數對給程式,而不是map引數list引數不會覆蓋’eval_metric’。 可供的選擇如下: “rmse”: root mean square error “logloss”: negative log-likelihood “error”: Binary classification error rate. It is calculated as #(wrong cases)/#(all cases). For the predictions, the evaluation will regard the instances with prediction value larger than 0.5 as positive instances, and the others as negative instances. “merror”: Multiclass classification error rate. “mlogloss”: Multiclass logloss. “auc”: Area under the curve for ranking evaluation. “ndcg”:Normalized Discounted Cumulative Gain “map”:Mean average precision “ndcg@n”,”map@n”: n can be assigned as an integer to cut off the top positions in the lists for evaluation. “ndcg-“,”map-“,”ndcg@n-“,”map@n-“: In XGBoost, NDCG andMAP will evaluate the score of a list without any positive samples as 1. By adding “-” in the evaluation metric XGBoostwill evaluate these score as 0 to be consistent under some conditions. training repeatively
  4. seed [ default=0 ] 隨機數的種子。預設值為0。

XGBoost 實戰

XGBoost有兩大類介面:XGBoost原生介面 和 scikit-learn介面 ,並且XGBoost能夠實現 分類 和 迴歸 兩種任務。因此,本章節分四個小塊來介紹!

01

基於XGBoost原生介面的分類

from sklearn.datasets import load_iris
import xgboost as xgb
from xgboost import plot_importance
from matplotlib import pyplot as plt
from sklearn.model_selection import train_test_split

# read in the iris data
iris = load_iris()

X = iris.data
y = iris.target

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1234565)

params = {
    'booster': 'gbtree',
    'objective': 'multi:softmax',
    'num_class': 3,
    'gamma': 0.1,
    'max_depth': 6,
    'lambda': 2,
    'subsample': 0.7,
    'colsample_bytree': 0.7,
    'min_child_weight': 3,
    'silent': 1,
    'eta': 0.1,
    'seed': 1000,
    'nthread': 4,
}

plst = params.items()


dtrain = xgb.DMatrix(X_train, y_train)
num_rounds = 500
model = xgb.train(plst, dtrain, num_rounds)

# 對測試集進行預測
dtest = xgb.DMatrix(X_test)
ans = model.predict(dtest)

# 計算準確率
cnt1 = 0
cnt2 = 0
for i in range(len(y_test)):
    if ans[i] == y_test[i]:
        cnt1 += 1
    else:
        cnt2 += 1

print("Accuracy: %.2f %% " % (100 * cnt1 / (cnt1 + cnt2)))

# 顯示重要特徵
plot_importance(model)
plt.show()

輸出預測正確率以及特徵重要性:

Accuracy: 96.67 %

02

基於XGBoost原生介面的迴歸

import xgboost as xgb
from xgboost import plot_importance
from matplotlib import pyplot as plt
from sklearn.model_selection import train_test_split

# 讀取檔案原始資料
data = []
labels = []
labels2 = []
with open("lppz5.csv", encoding='UTF-8') as fileObject:
    for line in fileObject:
        line_split = line.split(',')
        data.append(line_split[10:])
        labels.append(line_split[8])

X = []
for row in data:
    row = [float(x) for x in row]
    X.append(row)

y = [float(x) for x in labels]

# XGBoost訓練過程
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

params = {
    'booster': 'gbtree',
    'objective': 'reg:gamma',
    'gamma': 0.1,
    'max_depth': 5,
    'lambda': 3,
    'subsample': 0.7,
    'colsample_bytree': 0.7,
    'min_child_weight': 3,
    'silent': 1,
    'eta': 0.1,
    'seed': 1000,
    'nthread': 4,
}

dtrain = xgb.DMatrix(X_train, y_train)
num_rounds = 300
plst = params.items()
model = xgb.train(plst, dtrain, num_rounds)

# 對測試集進行預測
dtest = xgb.DMatrix(X_test)
ans = model.predict(dtest)

# 顯示重要特徵
plot_importance(model)
plt.show()

重要特徵(值越大,說明該特徵越重要)顯示結果:

03

基於Scikit-learn介面的分類

from sklearn.datasets import load_iris
import xgboost as xgb
from xgboost import plot_importance
from matplotlib import pyplot as plt
from sklearn.model_selection import train_test_split

# read in the iris data
iris = load_iris()

X = iris.data
y = iris.target

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

# 訓練模型
model = xgb.XGBClassifier(max_depth=5, learning_rate=0.1, n_estimators=160, silent=True, objective='multi:softmax')
model.fit(X_train, y_train)

# 對測試集進行預測
ans = model.predict(X_test)

# 計算準確率
cnt1 = 0
cnt2 = 0
for i in range(len(y_test)):
    if ans[i] == y_test[i]:
        cnt1 += 1
    else:
        cnt2 += 1

print("Accuracy: %.2f %% " % (100 * cnt1 / (cnt1 + cnt2)))

# 顯示重要特徵
plot_importance(model)
plt.show()

輸出預測正確率以及特徵重要性:

Accuracy: 100.00 %

04

基於XGBoost原生介面的迴歸

import xgboost as xgb
from xgboost import plot_importance
from matplotlib import pyplot as plt
from sklearn.model_selection import train_test_split

# 讀取檔案原始資料
data = []
labels = []
labels2 = []
with open("lppz5.csv", encoding='UTF-8') as fileObject:
    for line in fileObject:
        line_split = line.split(',')
        data.append(line_split[10:])
        labels.append(line_split[8])

X = []
for row in data:
    row = [float(x) for x in row]
    X.append(row)

y = [float(x) for x in labels]

# XGBoost訓練過程
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

model = xgb.XGBRegressor(max_depth=5, learning_rate=0.1, n_estimators=160, silent=True, objective='reg:gamma')
model.fit(X_train, y_train)

# 對測試集進行預測
ans = model.predict(X_test)

# 顯示重要特徵
plot_importance(model)
plt.show()

重要特徵(值越大,說明該特徵越重要)顯示結果: