Python實現Xgboost模型

1.下載xgboost包文件:https://www.lfd.uci.edu/~gohlke/pythonlibs/#xgboost

2.安裝xgboost包:命令管理器輸入 pip install G:\GoogleDownload\xgboost-0.82-cp36-cp36m-win_amd64.whl

3.xgboost優點:

優點:(1)正則化:XGBoost在代價函數里加入了正則項,用於控制模型的複雜度。正則項裏包含了樹的葉子節點個數、每個葉子節點上輸出的score的L2模的平方和。從Bias-variance tradeoff角度來講,正則項降低了模型的variance,使學習出來的模型更加簡單,防止過擬合,這也是xgboost優於傳統GBDT的一個特性。

(2)並行處理:XGBoost工具支持並行。Boosting不是一種串行的結構嗎?怎麼並行的?注意XGBoost的並行不是tree粒度的並行,XGBoost也是一次迭代完才能進行下一次迭代的(第t次迭代的代價函數裏包含了前面t-1次迭代的預測值)。XGBoost的並行是在特徵粒度上的。我們知道,決策樹的學習最耗時的一個步驟就是對特徵的值進行排序(因爲要確定最佳分割點),XGBoost在訓練之前,預先對數據進行了排序,然後保存爲block結構,後面的迭代中重複地使用這個結構,大大減小計算量。這個block結構也使得並行成爲了可能,在進行節點的分裂時,需要計算每個特徵的增益,最終選增益最大的那個特徵去做分裂,那麼各個特徵的增益計算就可以開多線程進行。

(3)靈活性:XGBoost支持用戶自定義目標函數和評估函數,只要目標函數二階可導就行。

(4)缺失值處理:對於特徵的值有缺失的樣本,xgboost可以自動學習出它的分裂方向

(5)剪枝:XGBoost 先從頂到底建立所有可以建立的子樹,再從底到頂反向進行剪枝。比起GBM,這樣不容易陷入局部最優解。

(6)內置交叉驗證:XGBoost允許在每一輪boosting迭代中使用交叉驗證。因此,可以方便地獲得最優boosting迭代次數。而GBM使用網格搜索,只能檢測有限個值。

4.XGBoost參數詳解

在運行XGboost之前,必須設置三種類型參數:general parameters,booster parameters和task parameters:

4.1通用參數(general parameters):該參數參數控制在提升(boosting)過程中使用哪種booster,常用的booster有樹模型(tree)和線性模型(linear model)

booster [default=gbtree]:有兩中模型可以選擇gbtree和gblinear。gbtree使用基於樹的模型進行提升計算,gblinear使用線性模型進行提升計算。缺省值爲gbtree

silent [default=0]:取0時表示打印出運行時信息,取1時表示以緘默方式運行,不打印運行時信息。缺省值爲0

nthread:XGBoost運行時的線程數。缺省值是當前系統可以獲得的最大線程數

num_pbuffer:預測緩衝區大小,通常設置爲訓練實例的數目。緩衝用於保存最後一步提升的預測結果,無需人爲設置。

num_feature:Boosting過程中用到的特徵維數,設置爲特徵個數。XGBoost會自動設置,無需人爲設置。

4.2 Booster參數(booster parameters):這取決於使用哪種booster。

(1)tree booster參數(booster=gbtree)

eta [default=0.3] :爲了防止過擬合,更新過程中用到的收縮步長。在每次提升計算之後,算法會直接獲得新特徵的權重。 eta通過縮減特徵的權重使提升計算過程更加保守。缺省值爲0.3 ,取值範圍爲:[0,1]。典型值爲0.01~0.2。

gamma [default=0] :在節點分裂時,只有分裂後損失函數的值下降了,纔會分裂這個節點。Gamma指定了節點分裂所需的最小損失函數下降值。 這個參數的值越大,算法越保守。

這個參數的值和損失函數息息相關,所以是需要調整的。 取值範圍爲:[0,∞]

max_depth [default=6] :數的最大深度。缺省值爲6 。取值範圍爲:[1,∞]。需要使用CV函數來進行調優。典型值:3-10

min_child_weight [default=1] :孩子節點中最小的樣本權重和。如果一個葉子節點的樣本權重和小於min_child_weight則拆分過程結束。在現行迴歸模型中,這個參數是指建立每個模型所需要的最小樣本數。這個參數用於避免過擬合。當它的值較大時,可以避免模型學習到局部的特殊樣本。 但是如果這個值過高,會導致欠擬合。這個參數需要使用CV來調整。取值範圍爲:[0,∞]

max_delta_step [default=0] :我們允許每個樹的權重被估計的值。如果它的值被設置爲0,意味着沒有約束;如果它被設置爲一個正值,它能夠使得更新的步驟更加保守。通常這個參數是沒有必要的,但是如果在邏輯迴歸中類極其不平衡這時候他有可能會起到幫助作用。把它範圍設置爲1-10之間也許能控制更新。 取值範圍爲:[0,∞]

subsample [default=1] :用於訓練模型的子樣本佔整個樣本集合的比例。如果設置爲0.5則意味着XGBoost將隨機的從整個樣本集合中隨機的抽取出50%的子樣本建立樹模型,這能夠防止過擬合。 取值範圍爲:(0,1]

colsample_bytree [default=1] :在建立樹時對特徵採樣的比例。缺省值爲1 。取值範圍爲:(0,1]

(2)Linear Booster參數(booster=gblinear)

lambda [default=0] :L2 正則的懲罰係數

alpha [default=0] :L1 正則的懲罰係數

lambda_bias :在偏置上的L2正則。缺省值爲0(在L1上沒有偏置項的正則,因爲L1時偏置不重要)

4.3 學習目標參數(task parameters):控制學習的場景,例如在迴歸問題中會使用不同的參數控制排序。

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)

base_score [ default=0.5 ]:所有實例的初始化預測分數,全局偏置;當有足夠的迭代次數時,改變這個值將不會有太大影響。

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(均方根誤差);mae(平均絕對誤差);logloss(負對數似然函數值);error(二分類錯誤率(閾值爲0.5) );merror(多分類錯誤率);mlogloss (多分類logloss損失函數);auc(曲線下面積)

seed [ default=0 ]:隨機數的種子。缺省值爲0

4.4 xgboost.train()函數參數

xgboost.train(params,
              dtrain,
              num_boost_round=10,
              evals=(),
              obj=None,
              feval=None,
              maximize=False,
              early_stopping_rounds=None,
              evals_result=None,
              verbose_eval=True,
              learning_rates=None,
              xgb_model=None) 

params :這是一個字典,裏面包含着訓練中的參數關鍵字和對應的值,形式是params = {‘booster’:’gbtree’, ’eta’:0.1}

dtrain :訓練的數據

num_boost_round :這是指提升迭代的個數

evals :這是一個列表,用於對訓練過程中進行評估列表中的元素。形式是evals = [(dtrain,’train’), (dval,’val’)]或者是evals = [ (dtrain,’train’)], 對於第一種情況,它使得我們可以在訓練過程中觀察驗證集的效果。

obj:自定義目的函數

feval:自定義評估函數

maximize: 是否對評估函數進行最大化

early_stopping_rounds: 早期停止次數 ,假設爲100,驗證集的誤差迭代到一定程度在100次內不能再繼續降低,就停止迭代。這要求evals 裏至少有一個元素,如果有多個,按最後一個去執行。返回的是最後的迭代次數(不是最好的)。如果early_stopping_rounds 存在,則模型會生成三個屬性,bst.best_score, bst.best_iteration, 和bst.best_ntree_limit

evals_result :字典,存儲在watchlist 中的元素的評估結果。

verbose_eval(可以輸入布爾型或數值型):也要求evals 裏至少有 一個元素。如果爲True, 則對evals中元素的評估結果會輸出在結果中;如果輸入數字,假設爲5,則每隔5個迭代輸出一次。

learning_rates :每一次提升的學習率的列表,

xgb_model:在訓練之前用於加載的xgb model。

5.Xgboost實戰:

XGBoost有兩大類接口:XGBoost原生接口和scikit-learn接口 ,並且XGBoost能夠實現分類迴歸兩種任務



# 基於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
from sklearn.metrics import accuracy_score   # 準確率


iris = load_iris()  # 加載樣本數據集
x_data, y_data = iris.data, iris.target
x_train, x_test, y_train, y_test = train_test_split(x_data, y_data,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)  # 生成數據集格式
model = xgb.train(params,
                  dtrain,  # 訓練的數據
                  num_boost_round=500  # 提升迭代的個數
                  ) # xgboost模型訓練


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

# 計算準確率
accuracy = accuracy_score(y_test,y_pred)
print("accuarcy: %.2f%%" % (accuracy*100.0))

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


# ================基於XGBoost原生接口的迴歸=============

import xgboost as xgb
from xgboost import plot_importance
from matplotlib import pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_boston
from sklearn.metrics import mean_squared_error

# 加載數據集
boston = load_boston()
X,y = boston.data,boston.target

# 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)
model = xgb.train(params, dtrain, num_boost_round=500)

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

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



# ==============基於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
from sklearn.metrics import accuracy_score

# 加載樣本數據集
iris = load_iris()
X,y = iris.data,iris.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1234565) # 數據集分割

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

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

# 計算準確率
accuracy = accuracy_score(y_test,y_pred)
print("accuarcy: %.2f%%" % (accuracy*100.0))

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


# ================基於Scikit-learn接口的迴歸================
import xgboost as xgb
from xgboost import plot_importance
from matplotlib import pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_boston

boston = load_boston()
X,y = boston.data,boston.target

# 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()



6.參數調優的一般方法

我們會使用和GBM中相似的方法。需要進行如下步驟:

1. 選擇較高的學習速率(learning rate)。一般情況下,學習速率的值爲0.1。但是,對於不同的問題,理想的學習速率有時候會在0.05到0.3之間波動。選擇對應於此學習速率的理想決策樹數量。XGBoost有一個很有用的函數“cv”,這個函數可以在每一次迭代中使用交叉驗證,並返回理想的決策樹數量。

2. 對於給定的學習速率和決策樹數量,進行決策樹特定參數調優(max_depth, min_child_weight, gamma, subsample, colsample_bytree)。在確定一棵樹的過程中,我們可以選擇不同的參數,待會兒我會舉例說明。

3. xgboost的正則化參數的調優。(lambda, alpha)。這些參數可以降低模型的複雜度,從而提高模型的表現。

4. 降低學習速率,確定理想參數。

咱們一起詳細地一步步進行這些操作。

第一步:確定學習速率和tree_based 參數調優的估計器數目。

爲了確定boosting 參數,我們要先給其它參數一個初始值。咱們先按如下方法取值:

1、max_depth = 5 :這個參數的取值最好在3-10之間。我選的起始值爲5,但是你也可以選擇其它的值。起始值在4-6之間都是不錯的選擇。

2、min_child_weight = 1:在這裏選了一個比較小的值,因爲這是一個極不平衡的分類問題。因此,某些葉子節點下的值會比較小。

3、gamma = 0: 起始值也可以選其它比較小的值,在0.1到0.2之間就可以。這個參數後繼也是要調整的。

4、subsample,colsample_bytree = 0.8: 這個是最常見的初始值了。典型值的範圍在0.5-0.9之間。

5、scale_pos_weight = 1: 這個值是因爲類別十分不平衡。

注意哦,上面這些參數的值只是一個初始的估計值,後繼需要調優。這裏把學習速率就設成默認的0.1。然後用xgboost中的cv函數來確定最佳的決策樹數量。

第二步: max_depth 和 min_weight 參數調優

我們先對這兩個參數調優,是因爲它們對最終結果有很大的影響。首先,我們先大範圍地粗調參數,然後再小範圍地微調。

注意:在這一節我會進行高負荷的柵格搜索(grid search),這個過程大約需要15-30分鐘甚至更久,具體取決於你係統的性能。你也可以根據自己系統的性能選擇不同的值。

第三步:gamma參數調優

第四步:調整subsample 和 colsample_bytree 參數

第五步:正則化參數調優。

第6步:降低學習速率

最後,我們使用較低的學習速率,以及使用更多的決策樹。我們可以用XGBoost中的CV函數來進行這一步工作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章