Python機器學習筆記:XgBoost算法

前言

1,Xgboost簡介

  Xgboost是Boosting算法的其中一種,Boosting算法的思想是將許多弱分類器集成在一塊兒,造成一個強分類器。由於Xgboost是一種提高樹模型,因此它是將許多樹模型集成在一塊兒,造成一個很強的分類器。而所用到的樹模型則是CART迴歸樹模型。html

  Xgboost是在GBDT的基礎上進行改進,使之更強大,適用於更大範圍。node

  Xgboost通常和sklearn一塊兒使用,可是因爲sklearn中沒有集成Xgboost,因此才須要單獨下載安裝。python

2,Xgboost的優勢

  Xgboost算法能夠給預測模型帶來能力的提高。當咱們對其表現有更多瞭解的時候,咱們會發現他有以下優點:git

2.1  正則化

  實際上,Xgboost是以「正則化提高(regularized boosting)」 技術而聞名。Xgboost在代價函數里加入了正則項,用於控制模型的複雜度。正則項裏包含了樹的葉子節點個數,每一個葉子節點上輸出的score的L2模的平方和。從Bias-variance tradeoff角度來說,正則項下降了模型的variance,使學習出來的模型更加簡單,防止過擬合,這也是Xgboost優於傳統GBDT的一個特徵算法

2.2  並行處理

  Xgboost工具支持並行。衆所周知,Boosting算法是順序處理的,也是說Boosting不是一種串行的結構嗎?怎麼並行的?注意Xgboost的並行不是tree粒度的並行。Xgboost也是一次迭代完才能進行下一次迭代的(第t次迭代的代價函數裏包含)。Xgboost的並行式在特徵粒度上的,也就是說每一顆樹的構造都依賴於前一顆樹。c#

  咱們知道,決策樹的學習最耗時的一個步驟就是對特徵的值進行排序(由於要肯定最佳分割點),Xgboost在訓練以前,預先對數據進行了排序,而後保存爲block結構,後面的迭代中重複使用這個結構,大大減少計算量。這個block結構也使得並行成爲了可能,在進行節點的分類時,須要計算每一個特徵的增益,大大減小計算量。這個block結構也使得並行成爲了可能,在進行節點的分裂的時候,須要計算每一個特徵的增益,最終選增益最大的那個特徵去作分裂,那麼各個特徵的增益計算就能夠開多線程進行。數組

2.3  靈活性

  Xgboost支持用戶自定義目標函數和評估函數,只要目標函數二階可導就行。它對模型增長了一個全新的維度,因此咱們的處理不會受到任何限制。緩存

2.4  缺失值處理

  對於特徵的值有缺失的樣本,Xgboost能夠自動學習出他的分裂方向。Xgboost內置處理缺失值的規則。用戶須要提供一個和其餘樣本不一樣的值,而後把它做爲一個參數穿進去,以此來做爲缺失值的取值。Xgboost在不一樣節點遇到缺失值時採用不一樣的處理方法,而且會學習將來遇到缺失值時的處理方法。多線程

2.5  剪枝

  Xgboost先從頂到底創建全部能夠創建的子樹,再從底到頂反向機芯剪枝,比起GBM,這樣不容易陷入局部最優解dom

2.6  內置交叉驗證

  Xgboost容許在每一輪Boosting迭代中使用交叉驗證。所以能夠方便的得到最優Boosting迭代次數,而GBM使用網格搜索,只能檢測有限個值。

 

3,Xgboost的離線安裝

1,點擊此處,下載對應本身Python版本的網址。

2,輸入安裝的程式:

pip install xgboost-0.81-cp37-cp37m-win_amd64.whl

 

Xgboost模型詳解

1,Xgboost能加載的各類數據格式解析

  Xgboost能夠加載多種數據格式的訓練數據:

libsvm 格式的文本數據;

Numpy 的二維數組;

XGBoost 的二進制的緩存文件。加載的數據存儲在對象 DMatrix 中。

   下面一一列舉:

  記載libsvm格式的數據

dtrain1 = xgb.DMatrix('train.svm.txt')

  記載二進制的緩存文件

dtrain2  = xgb.DMatrix('train.svm.buffer')

  加載numpy的數組

data = np.random.rand(5,10)                 # 5行10列數據集
label = np.random.randint(2,size=5)       # 二分類目標值
dtrain = xgb.DMatrix(data,label=label)    # 組成訓練集

  將scipy.sparse格式的數據轉化爲Dmatrix格式

csr = scipy.sparse.csr_matrix((dat,(row,col)))
dtrain = xgb.DMatrix( csr )

  將Dmatrix格式的數據保存成Xgboost的二進制格式,在下次加載時能夠提升加載速度,使用方法以下:

dtrain = xgb.DMatrix('train.svm.txt')
dtrain.save_binary("train.buffer")

  可使用以下方式處理DMatrix中的缺失值

dtrain = xgb.DMatrix( data, label=label, missing = -999.0)

  當須要給樣本設置權重時,能夠用以下方式:

w = np.random.rand(5,1)
dtrain = xgb.DMatrix( data, label=label, missing = -999.0, weight=w)

2,Xgboost的模型參數

  Xgboost使用key-value字典的方式存儲參數

# xgboost模型
params = {
    'booster':'gbtree',
    'objective':'multi:softmax',   # 多分類問題
    'num_class':10,  # 類別數,與multi softmax並用
    'gamma':0.1,    # 用於控制是否後剪枝的參數,越大越保守,通常0.1 0.2的樣子
    'max_depth':12,  # 構建樹的深度,越大越容易過擬合
    'lambda':2,  # 控制模型複雜度的權重值的L2 正則化項參數,參數越大,模型越不容易過擬合
    'subsample':0.7, # 隨機採樣訓練樣本
    'colsample_bytree':3,# 這個參數默認爲1,是每一個葉子裏面h的和至少是多少
    # 對於正負樣本不均衡時的0-1分類而言,假設h在0.01附近,min_child_weight爲1
    #意味着葉子節點中最少須要包含100個樣本。這個參數很是影響結果,
    # 控制葉子節點中二階導的和的最小值,該參數值越小,越容易過擬合
    'silent':0,  # 設置成1 則沒有運行信息輸入,最好是設置成0
    'eta':0.007,  # 如同窗習率
    'seed':1000,
    'nthread':7,  #CPU線程數
    #'eval_metric':'auc'
}

  

  在運行Xgboost以前,必須設置三種類型成熟:general parameters,booster parameters和task parameters:

  通用參數(General Parameters):該參數控制在提高(boosting)過程當中使用哪一種booster,經常使用的booster有樹模型(tree)和線性模型(linear model)

  Booster參數(Booster Parameters):這取決於使用哪一種booster

  學習目標參數(Task Parameters):控制學習的場景,例如在迴歸問題中會使用不一樣的參數控制排序

2.1, 通用參數

    • booster [default=gbtree] 
      • 有兩種模型能夠選擇gbtree和gblinear。gbtree使用基於樹的模型進行提高計算,gblinear使用線性模型進行提高計算。缺省值爲gbtree
    • silent [default=0] 
      • 取0時表示打印出運行時信息,取1時表示以緘默方式運行,不打印運行時的信息。缺省值爲0
      • 建議取0,過程當中的輸出數據有助於理解模型以及調參。另外實際上我設置其爲1也一般沒法緘默運行。。
    • nthread [default to maximum number of threads available if not set] 
      • XGBoost運行時的線程數。缺省值是當前系統能夠得到的最大線程數
      • 若是你但願以最大速度運行,建議不設置這個參數,模型將自動得到最大線程
    • num_pbuffer [set automatically by xgboost, no need to be set by user] 
      • size of prediction buffer, normally set to number of training instances. The buffers are used to save the prediction results of last boosting step.
    • num_feature [set automatically by xgboost, no need to be set by user] 
      • boosting過程當中用到的特徵維數,設置爲特徵個數。XGBoost會自動設置,不須要手工設置

2.2,tree booster參數

    • eta [default=0.3] 
      • 爲了防止過擬合,更新過程當中用到的收縮步長。在每次提高計算以後,算法會直接得到新特徵的權重。 eta經過縮減特徵的權重使提高計算過程更加保守。缺省值爲0.3
      • 取值範圍爲:[0,1]
      • 一般最後設置eta爲0.01~0.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.
      • range: [0,∞]
      • 模型在默認狀況下,對於一個節點的劃分只有在其loss function 獲得結果大於0的狀況下才進行,而gamma 給定了所需的最低loss function的值
      • gamma值使得算法更conservation,且其值依賴於loss function ,在模型中應該進行調參。
    • max_depth [default=6] 
      • 樹的最大深度。缺省值爲6
      • 取值範圍爲:[1,∞]
      • 指樹的最大深度
      • 樹的深度越大,則對數據的擬合程度越高(過擬合程度也越高)。即該參數也是控制過擬合
      • 建議經過交叉驗證(xgb.cv ) 進行調參
      • 一般取值:3-10
    • min_child_weight [default=1] 
      • 孩子節點中最小的樣本權重和。若是一個葉子節點的樣本權重和小於min_child_weight則拆分過程結束。在現行迴歸模型中,這個參數是指創建每一個模型所須要的最小樣本數。該成熟越大算法越conservative。即調大這個參數可以控制過擬合。
      • 取值範圍爲: [0,∞]
    • max_delta_step [default=0] 
      • Maximum delta step we allow each tree’s weight estimation to be. If the value is set to 0, it means there is no constraint. If it is set to a positive value, it can help making the update step more conservative. Usually this parameter is not needed, but it might help in logistic regression when class is extremely imbalanced. Set it to value of 1-10 might help control the update
      • 取值範圍爲:[0,∞]
      • 若是取值爲0,那麼意味着無限制。若是取爲正數,則其使得xgboost更新過程更加保守。
      • 一般不須要設置這個值,但在使用logistics 迴歸時,若類別極度不平衡,則調整該參數可能有效果
    • subsample [default=1] 
      • 用於訓練模型的子樣本佔整個樣本集合的比例。若是設置爲0.5則意味着XGBoost將隨機的從整個樣本集合中抽取出50%的子樣本創建樹模型,這可以防止過擬合。
      • 取值範圍爲:(0,1]
    • colsample_bytree [default=1] 
      • 在創建樹時對特徵隨機採樣的比例。缺省值爲1
      • 取值範圍:(0,1]
    • colsample_bylevel[default=1]
      • 決定每次節點劃分時子樣例的比例
      • 一般不使用,由於subsample和colsample_bytree已經能夠起到相同的做用了
    • scale_pos_weight[default=0]
      • A value greater than 0 can be used in case of high class imbalance as it helps in faster convergence.
      • 大於0的取值能夠處理類別不平衡的狀況。幫助模型更快收斂

2.3,Linear Booster參數

    • lambda [default=0] 
      • L2 正則的懲罰係數
      • 用於處理XGBoost的正則化部分。一般不使用,但能夠用來下降過擬合
    • alpha [default=0] 
      • L1 正則的懲罰係數
      • 當數據維度極高時可使用,使得算法運行更快。
    • lambda_bias 
      • 在偏置上的L2正則。缺省值爲0(在L1上沒有偏置項的正則,由於L1時偏置不重要)

 

2.4,學習目標參數

  這個參數是來控制理想的優化目標和每一步結果的度量方法。

    • 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 ] 
      • the initial prediction score of all instances, global bias
    • eval_metric [ default according to objective ] 
      • 校驗數據所須要的評價指標,不一樣的目標函數將會有缺省的評價指標(rmse for regression, and error for classification, mean average precision for ranking)
      • 用戶能夠添加多種評價指標,對於Python用戶要以list傳遞參數對給程序,而不是map參數list參數不會覆蓋’eval_metric’
      • The choices are listed below:
      • 「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. It is calculated as #(wrong cases)/#(all cases).
      • 「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 and MAP will evaluate the score of a list without any positive samples as 1. By adding 「-」 in the evaluation metric XGBoost will evaluate these score as 0 to be consistent under some conditions. 
        training repeatively
    • seed [ default=0 ] 
      • 隨機數的種子。缺省值爲0
      • 能夠用於產生可重複的結果(每次取同樣的seed便可獲得相同的隨機劃分)

3,Xgboost基本方法和默認參數

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)

  

  parms:這是一個字典,裏面包含着訓練中的參數關鍵字和對應的值,形式是parms = {'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

4,模型訓練

  有了參數列表和數據就能夠訓練模型了

num_round = 10
bst = xgb.train( plst, dtrain, num_round, evallist )

5,模型預測

# X_test類型能夠是二維List,也能夠是numpy的數組
dtest = DMatrix(X_test)
ans = model.predict(dtest)

  完整代碼以下:

xgb_model.get_booster().save_model('xgb.model')
tar = xgb.Booster(model_file='xgb.model')
x_test = xgb.DMatrix(x_test)
pre=tar.predict(x_test)
act=y_test
print(mean_squared_error(act, pre))

  

6,保存模型

  在訓練完成以後能夠將模型保存下來,也能夠查看模型內部的結構

bst.save_model('test.model')

  導出模型和特徵映射(Map)

  你能夠導出模型到txt文件並瀏覽模型的含義:

# 導出模型到文件
bst.dump_model('dump.raw.txt')
# 導出模型和特徵映射
bst.dump_model('dump.raw.txt','featmap.txt')

7,加載模型

  經過以下方式能夠加載模型

bst = xgb.Booster({'nthread':4}) # init model
bst.load_model("model.bin")      # load data

 

Xgboost實戰

  Xgboost有兩大類接口:Xgboost原生接口 和sklearn接口,而且Xgboost可以實現分類迴歸兩種任務。下面對這四種狀況作以解析。

 1,基於Xgboost原生接口的分類

from sklearn.datasets import load_iris
import xgboost as xgb
from xgboost import plot_importance
import matplotlib.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=123457)

# 算法參數
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,
    'slient':1,
    'eta':0.1,
    'seed':1000,
    'nthread':4,
}

plst = params.items()

# 生成數據集格式
dtrain = xgb.DMatrix(X_train,y_train)
num_rounds = 500
# xgboost模型訓練
model = xgb.train(plst,dtrain,num_rounds)

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

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

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

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

accuarcy:93.33%

  

 

 

2,基於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,
    'slient':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()

  

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

 3,Xgboost使用sklearn接口的分類(推薦)

XGBClassifier

from xgboost.sklearn import XGBClassifier

clf = XGBClassifier(
    silent=0,  # 設置成1則沒有運行信息輸出,最好是設置爲0,是否在運行升級時打印消息
    # nthread = 4  # CPU 線程數 默認最大
    learning_rate=0.3 , # 如同窗習率
    min_child_weight = 1,
    # 這個參數默認爲1,是每一個葉子裏面h的和至少是多少,對正負樣本不均衡時的0-1分類而言
    # 假設h在0.01附近,min_child_weight爲1 意味着葉子節點中最少須要包含100個樣本
    # 這個參數很是影響結果,控制葉子節點中二階導的和的最小值,該參數值越小,越容易過擬合
    max_depth=6, # 構建樹的深度,越大越容易過擬合
    gamma = 0,# 樹的葉子節點上作進一步分區所需的最小損失減小,越大越保守,通常0.1 0.2這樣子
    subsample=1, # 隨機採樣訓練樣本,訓練實例的子採樣比
    max_delta_step=0,  # 最大增量步長,咱們容許每一個樹的權重估計
    colsample_bytree=1, # 生成樹時進行的列採樣
    reg_lambda=1, #控制模型複雜度的權重值的L2正則化項參數,參數越大,模型越不容易過擬合
    # reg_alpha=0, # L1正則項參數
    # scale_pos_weight =1 # 若是取值大於0的話,在類別樣本不平衡的狀況下有助於快速收斂,平衡正負權重
    # objective = 'multi:softmax', # 多分類問題,指定學習任務和響應的學習目標
    # num_class = 10,  # 類別數,多分類與multisoftmax並用
    n_estimators=100,  # 樹的個數
    seed = 1000,  # 隨機種子
    # eval_metric ='auc'
)

  

基於Sckit-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=12343)

# 訓練模型
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('accuracy:%2.f%%'%(accuracy*100))

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

  

  輸出結果:

accuracy:93%

4,基於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()

  

 5,整理代碼1(原生XGB)

from sklearn.model_selection import train_test_split
from sklearn import metrics
from  sklearn.datasets  import  make_hastie_10_2
import xgboost as xgb
#記錄程序運行時間
import time 
start_time = time.time()
X, y = make_hastie_10_2(random_state=0)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=0)##test_size測試集合所佔比例
#xgb矩陣賦值
xgb_train = xgb.DMatrix(X_train, label=y_train)
xgb_test = xgb.DMatrix(X_test,label=y_test)
##參數
params={
'booster':'gbtree',
'silent':1 ,#設置成1則沒有運行信息輸出,最好是設置爲0.
#'nthread':7,# cpu 線程數 默認最大
'eta': 0.007, # 如同窗習率
'min_child_weight':3, 
# 這個參數默認是 1,是每一個葉子裏面 h 的和至少是多少,對正負樣本不均衡時的 0-1 分類而言
#,假設 h 在 0.01 附近,min_child_weight 爲 1 意味着葉子節點中最少須要包含 100 個樣本。
#這個參數很是影響結果,控制葉子節點中二階導的和的最小值,該參數值越小,越容易 overfitting。
'max_depth':6, # 構建樹的深度,越大越容易過擬合
'gamma':0.1,  # 樹的葉子節點上做進一步分區所需的最小損失減小,越大越保守,通常0.一、0.2這樣子。
'subsample':0.7, # 隨機採樣訓練樣本
'colsample_bytree':0.7, # 生成樹時進行的列採樣 
'lambda':2,  # 控制模型複雜度的權重值的L2正則化項參數,參數越大,模型越不容易過擬合。
#'alpha':0, # L1 正則項參數
#'scale_pos_weight':1, #若是取值大於0的話,在類別樣本不平衡的狀況下有助於快速收斂。
#'objective': 'multi:softmax', #多分類的問題
#'num_class':10, # 類別數,多分類與 multisoftmax 並用
'seed':1000, #隨機種子
#'eval_metric': 'auc'
}
plst = list(params.items())
num_rounds = 100 # 迭代次數
watchlist = [(xgb_train, 'train'),(xgb_test, 'val')]
 
#訓練模型並保存
# early_stopping_rounds 當設置的迭代次數較大時,early_stopping_rounds 可在必定的迭代次數內準確率沒有提高就中止訓練
model = xgb.train(plst, xgb_train, num_rounds, watchlist,early_stopping_rounds=100,pred_margin=1)
#model.save_model('./model/xgb.model') # 用於存儲訓練出的模型
print "best best_ntree_limit",model.best_ntree_limit 
y_pred = model.predict(xgb_test,ntree_limit=model.best_ntree_limit)
print ('error=%f' % (  sum(1 for i in range(len(y_pred)) if int(y_pred[i]>0.5)!=y_test[i]) /float(len(y_pred))))  
#輸出運行時長
cost_time = time.time()-start_time
print "xgboost success!",'\n',"cost time:",cost_time,"(s)......"

  

6,整理代碼2(XGB使用sklearn)

from sklearn.model_selection import train_test_split
from sklearn import metrics
from  sklearn.datasets  import  make_hastie_10_2
from xgboost.sklearn import XGBClassifier
X, y = make_hastie_10_2(random_state=0)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=0)##test_size測試集合所佔比例
clf = XGBClassifier(
silent=0 ,#設置成1則沒有運行信息輸出,最好是設置爲0.是否在運行升級時打印消息。
#nthread=4,# cpu 線程數 默認最大
learning_rate= 0.3, # 如同窗習率
min_child_weight=1, 
# 這個參數默認是 1,是每一個葉子裏面 h 的和至少是多少,對正負樣本不均衡時的 0-1 分類而言
#,假設 h 在 0.01 附近,min_child_weight 爲 1 意味着葉子節點中最少須要包含 100 個樣本。
#這個參數很是影響結果,控制葉子節點中二階導的和的最小值,該參數值越小,越容易 overfitting。
max_depth=6, # 構建樹的深度,越大越容易過擬合
gamma=0,  # 樹的葉子節點上做進一步分區所需的最小損失減小,越大越保守,通常0.一、0.2這樣子。
subsample=1, # 隨機採樣訓練樣本 訓練實例的子採樣比
max_delta_step=0,#最大增量步長,咱們容許每一個樹的權重估計。
colsample_bytree=1, # 生成樹時進行的列採樣 
reg_lambda=1,  # 控制模型複雜度的權重值的L2正則化項參數,參數越大,模型越不容易過擬合。
#reg_alpha=0, # L1 正則項參數
#scale_pos_weight=1, #若是取值大於0的話,在類別樣本不平衡的狀況下有助於快速收斂。平衡正負權重
#objective= 'multi:softmax', #多分類的問題 指定學習任務和相應的學習目標
#num_class=10, # 類別數,多分類與 multisoftmax 並用
n_estimators=100, #樹的個數
seed=1000 #隨機種子
#eval_metric= 'auc'
)
clf.fit(X_train,y_train,eval_metric='auc')
#設置驗證集合 verbose=False不打印過程
clf.fit(X_train, y_train,eval_set=[(X_train, y_train), (X_val, y_val)],eval_metric='auc',verbose=False)
#獲取驗證集合結果
evals_result = clf.evals_result()
y_true, y_pred = y_test, clf.predict(X_test)
print"Accuracy : %.4g" % metrics.accuracy_score(y_true, y_pred)
#迴歸
#m_regress = xgb.XGBRegressor(n_estimators=1000,seed=0)

  

Xgboost參數調優的通常方法

調參步驟:

  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函數來肯定最佳的決策樹數量。

from xgboost import XGBClassifier
xgb1 = XGBClassifier(
 learning_rate =0.1,
 n_estimators=1000,
 max_depth=5,
 min_child_weight=1,
 gamma=0,
 subsample=0.8,
 colsample_bytree=0.8,
 objective= 'binary:logistic',
 nthread=4,
 scale_pos_weight=1,
 seed=27)

  

第二步:max_depth和min_weight參數調優

  咱們先對這兩個參數調優,是由於他們對最終結果有很大的影響。首先,咱們先大範圍地粗略參數,而後再小範圍的微調。

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

  網格搜索scoring = 'roc_auc' 只支持二分類,多分類須要修改scoring(默認支持多分類)

param_test1 = {
 'max_depth':range(3,10,2),
 'min_child_weight':range(1,6,2)
}
#param_test2 = {
 'max_depth':[4,5,6],
 'min_child_weight':[4,5,6]
}
from sklearn import svm, grid_search, datasets
from sklearn import grid_search
gsearch1 = grid_search.GridSearchCV(
estimator = XGBClassifier(
learning_rate =0.1,
n_estimators=140, max_depth=5,
min_child_weight=1,
gamma=0,
subsample=0.8,
colsample_bytree=0.8,
objective= 'binary:logistic',
nthread=4,
scale_pos_weight=1,
seed=27),
param_grid = param_test1,
scoring='roc_auc',
n_jobs=4,
iid=False,
cv=5)
gsearch1.fit(train[predictors],train[target])
gsearch1.grid_scores_, gsearch1.best_params_,gsearch1.best_score_
#網格搜索scoring='roc_auc'只支持二分類,多分類須要修改scoring(默認支持多分類)

  

第三步:gamma參數調優

  在已經調整好其餘參數的基礎上,咱們能夠進行gamma參數的調優了。Gamma參數取值範圍很大,這裏咱們設置爲5,其實你也能夠取更精確的gamma值。

param_test3 = {
 'gamma':[i/10.0 for i in range(0,5)]
}

gsearch3 = GridSearchCV(estimator = XGBClassifier( learning_rate =0.1,
 n_estimators=140, max_depth=4,min_child_weight=6, gamma=0, 
subsample=0.8, colsample_bytree=0.8,objective= 'binary:logistic', 
nthread=4, scale_pos_weight=1,seed=27),  param_grid = param_test3, scoring='roc_auc',n_jobs=4,iid=False, cv=5)

gsearch3.fit(train[predictors],train[target])

gsearch3.grid_scores_, gsearch3.best_params_, gsearch3.best_score_

  

param_test3 = {
 'gamma':[i/10.0 for i in range(0,5)]
}
gsearch3 = GridSearchCV(
estimator = XGBClassifier( 
learning_rate =0.1, 
n_estimators=140, 
max_depth=4, 
min_child_weight=6, 
gamma=0, 
subsample=0.8, 
colsample_bytree=0.8, 
objective= 'binary:logistic', 
nthread=4, 
scale_pos_weight=1,
seed=27), 
param_grid = param_test3, 
scoring='roc_auc',
n_jobs=4,
iid=False, 
cv=5)
gsearch3.fit(train[predictors],train[target])
gsearch3.grid_scores_, gsearch3.best_params_, gsearch3.best_score_

  

第四步:調整subsample 和 colsample_bytree參數

  嘗試不一樣的subsample 和 colsample_bytree 參數。咱們分兩個階段來進行這個步驟。這兩個步驟都取0.6,0.7,0.8,0.9做爲起始值。

#取0.6,0.7,0.8,0.9做爲起始值
param_test4 = {
 'subsample':[i/10.0 for i in range(6,10)],
 'colsample_bytree':[i/10.0 for i in range(6,10)]
}
 
gsearch4 = GridSearchCV(
estimator = XGBClassifier(
learning_rate =0.1,
n_estimators=177,
max_depth=3,
min_child_weight=4,
gamma=0.1,
subsample=0.8,
colsample_bytree=0.8,
objective= 'binary:logistic',
nthread=4,
scale_pos_weight=1,
seed=27),
param_grid = param_test4,
scoring='roc_auc',
n_jobs=4,
iid=False,
cv=5)
gsearch4.fit(train[predictors],train[target])
gsearch4.grid_scores_, gsearch4.best_params_, gsearch4.best_score_

  

第五步:正則化參數調優

  因爲gamma函數提供了一種更加有效的下降過擬合的方法,大部分人不多會用到這個參數,可是咱們能夠嘗試用一下這個參數。

param_test6 = {
 'reg_alpha':[1e-5, 1e-2, 0.1, 1, 100]
}
gsearch6 = GridSearchCV(
estimator = XGBClassifier(
learning_rate =0.1,
n_estimators=177,
max_depth=4,
min_child_weight=6,
gamma=0.1,
subsample=0.8,
colsample_bytree=0.8,
objective= 'binary:logistic',
nthread=4,
scale_pos_weight=1,
seed=27),
param_grid = param_test6,
scoring='roc_auc',
n_jobs=4,
iid=False,
cv=5)
gsearch6.fit(train[predictors],train[target])
gsearch6.grid_scores_, gsearch6.best_params_, gsearch6.best_score_

  

第六步:下降學習速率

  最後,咱們使用較低的學習速率,以及使用更多的決策樹,咱們能夠用Xgboost中CV函數來進行這一步工做。

xgb4 = XGBClassifier(
 learning_rate =0.01,
 n_estimators=5000,
 max_depth=4,
 min_child_weight=6,
 gamma=0,
 subsample=0.8,
 colsample_bytree=0.8,
 reg_alpha=0.005,
 objective= 'binary:logistic',
 nthread=4,
 scale_pos_weight=1,
 seed=27)
modelfit(xgb4, train, predictors)

  

   總結一下,要想模型的表現有大幅的提高,調整每一個參數帶來的影響也必須清楚,僅僅靠着參數的調整和模型的小幅優化,想要讓模型的表現有個大幅度提高是不可能的。要想模型的表現有質的飛躍,須要依靠其餘的手段。諸如,特徵工程(feature egineering) ,模型組合(ensemble of model),以及堆疊(stacking)等。

 第七步:Python示例

import xgboost as xgb
import pandas as pd
#獲取數據
from sklearn import cross_validation
from sklearn.datasets import load_iris
iris = load_iris()
#切分數據集
X_train, X_test, y_train, y_test = cross_validation.train_test_split(iris.data, iris.target, test_size=0.33, random_state=42)
#設置參數
m_class = xgb.XGBClassifier(
 learning_rate =0.1,
 n_estimators=1000,
 max_depth=5,
 gamma=0,
 subsample=0.8,
 colsample_bytree=0.8,
 objective= 'binary:logistic',
 nthread=4,
 seed=27)
#訓練
m_class.fit(X_train, y_train)
test_21 = m_class.predict(X_test)
print "Accuracy : %.2f" % metrics.accuracy_score(y_test, test_21)
#預測機率
#test_2 = m_class.predict_proba(X_test)
#查看AUC評價標準
from sklearn import metrics
print "Accuracy : %.2f" % metrics.accuracy_score(y_test, test_21)
##必須二分類才能計算
##print "AUC Score (Train): %f" % metrics.roc_auc_score(y_test, test_2)
#查看重要程度
feat_imp = pd.Series(m_class.booster().get_fscore()).sort_values(ascending=False)
feat_imp.plot(kind='bar', title='Feature Importances')
import matplotlib.pyplot as plt
plt.show()
#迴歸
#m_regress = xgb.XGBRegressor(n_estimators=1000,seed=0)
#m_regress.fit(X_train, y_train)
#test_1 = m_regress.predict(X_test)

  

XGBoost輸出特徵重要性以及篩選特徵

1,梯度提高算法是如何計算特徵重要性的?

  使用梯度提高算法的好處是在提高樹被建立後,能夠相對直接地獲得每一個屬性的重要性得分。通常來講,重要性分數,衡量了特徵在模型中的提高決策樹構建中的價值。一個屬性越多的被用來在模型中構建決策樹,它的重要性就相對越高。

  屬性重要性是經過對數據集中的每一個屬性進行計算,並進行排序獲得。在單個決策樹中經過每一個屬性分裂點改進性能度量的量來計算屬性重要性。由節點負責加權和記錄次數,也就是說一個屬性對分裂點改進性能度量越大(越靠近根節點),權值越大;被越多提高樹所選擇,屬性越重要。性能度量能夠是選擇分裂節點的Gini純度,也能夠是其餘度量函數。

  最終將一個屬性在全部提高樹中的結果進行加權求和後而後平均,獲得重要性得分。

2,繪製特徵重要性

  一個已訓練的Xgboost模型可以自動計算特徵重要性,這些重要性得分能夠經過成員變量feature_importances_獲得。能夠經過以下命令打印:

print(model.feature_importances_)

  咱們能夠直接在條形圖上繪製這些分數,以便得到數據集中每一個特徵的相對重要性的直觀顯示,例如:

# plot
pyplot.bar(range(len(model.feature_importances_)), model.feature_importances_)
pyplot.show()

  咱們能夠經過在the Pima Indians onset of diabetes 數據集上訓練XGBoost模型來演示,並從計算的特徵重要性中繪製條形圖。

# plot feature importance manually
from numpy import loadtxt
from xgboost import XGBClassifier
from matplotlib import pyplot
from sklearn.datasets import load_iris
# load data
dataset = load_iris()
# split data into X and y
X = dataset.data
y = dataset.target
# fit model no training data
model = XGBClassifier()
model.fit(X, y)
# feature importance
print(model.feature_importances_)
# plot
pyplot.bar(range(len(model.feature_importances_)), model.feature_importances_)
pyplot.show()

  運行這個實例,首先輸出特徵重要性分數:

[0.17941953 0.11345647 0.41556728 0.29155672]

  相對重要性條形圖:

  這種繪製的缺點在於,只顯示了特徵重要性而沒有排序,能夠在繪製以前對特徵重要性得分進行排序。

  經過內建的繪製函數進行特徵重要性得分排序後的繪製,這個函數就是plot_importance(),示例以下:

# plot feature importance manually
from numpy import loadtxt
from xgboost import XGBClassifier
from matplotlib import pyplot
from sklearn.datasets import load_iris
from xgboost import plot_importance

# load data
dataset = load_iris()
# split data into X and y
X = dataset.data
y = dataset.target
# fit model no training data
model = XGBClassifier()
model.fit(X, y)
# feature importance
print(model.feature_importances_)
# plot feature importance

plot_importance(model)
pyplot.show()

  示例獲得條形圖:

  根據其在輸入數組的索引,特徵被自動命名爲f0~f3,在問題描述中手動的將這些索引映射到名稱,咱們能夠看到,f2具備最高的重要性,f1具備最低的重要性。

3,根據Xgboost特徵重要性得分進行特徵選擇

  特徵重要性得分,能夠用於在scikit-learn中進行特徵選擇。經過SelectFromModel類實現,該類採用模型並將數據集轉換爲具備選定特徵的子集。這個類能夠採起預先訓練的模型,例如在整個數據集上訓練的模型。而後,它能夠閾值來決定選擇哪些特徵。當在SelectFromModel實例上調用transform()方法時,該閾值被用於在訓練集和測試集上一致性選擇相同特徵。

  在下面的示例中,咱們首先在訓練集上訓練xgboost模型,而後在測試上評估。使用從訓練數據集計算的特徵重要性,而後,將模型封裝在一個SelectFromModel實例中。咱們使用這個來選擇訓練集上的特徵,用所選擇的特徵子集訓練模型,而後在相同的特徵方案下對測試集進行評估。

# select features using threshold
selection = SelectFromModel(model, threshold=thresh, prefit=True)
select_X_train = selection.transform(X_train)
# train model
selection_model = XGBClassifier()
selection_model.fit(select_X_train, y_train)
# eval model
select_X_test = selection.transform(X_test)
y_pred = selection_model.predict(select_X_test)

  咱們能夠經過測試多個閾值,來從特徵重要性中選擇特徵。具體而言,每一個輸入變量的特徵重要性,本質上容許咱們經過重要性來測試每一個特徵子集。

完整代碼以下:

# plot feature importance manually
import numpy as np
from xgboost import XGBClassifier
from matplotlib import pyplot
from sklearn.datasets import load_iris
from xgboost import plot_importance
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.feature_selection import SelectFromModel

# load data
dataset = load_iris()
# split data into X and y
X = dataset.data
y = dataset.target

# split data into train and test sets
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.33,random_state=7)

# fit model no training data
model = XGBClassifier()
model.fit(X_train, y_train)
# feature importance
print(model.feature_importances_)

# make predictions for test data and evaluate
y_pred = model.predict(X_test)
predictions = [round(value) for value in y_pred]
accuracy = accuracy_score(y_test,predictions)
print("Accuracy:%.2f%%"%(accuracy*100.0))

#fit model using each importance as a threshold
thresholds = np.sort(model.feature_importances_)
for thresh in thresholds:
    # select features using threshold
    selection = SelectFromModel(model,threshold=thresh,prefit=True )
    select_X_train = selection.transform(X_train)
    # train model
    selection_model = XGBClassifier()
    selection_model.fit(select_X_train, y_train)
    # eval model
    select_X_test = selection.transform(X_test)
    y_pred = selection_model.predict(select_X_test)
    predictions = [round(value) for value in y_pred]
    accuracy = accuracy_score(y_test,predictions)
    print("Thresh=%.3f, n=%d, Accuracy: %.2f%%" % (thresh, select_X_train.shape[1], accuracy * 100.0))

  運行示例,獲得輸出:

[0.20993228 0.09029345 0.54176074 0.15801354]
Accuracy:92.00%
Thresh=0.090, n=4, Accuracy: 92.00%
Thresh=0.158, n=3, Accuracy: 92.00%
Thresh=0.210, n=2, Accuracy: 86.00%
Thresh=0.542, n=1, Accuracy: 90.00%

  咱們能夠看到,模型的性能一般隨着所選擇的特徵的數量減小,在這一問題上,能夠對測試集準確率和模型複雜度作一個權衡,例如選擇三個特徵,接受準確率爲92%,這多是對這樣一個小數據集的清洗,可是對於更大的數據集和使用交叉驗證做爲模型評估方案多是更有用的策略。

4,網格搜索

代碼1:

from sklearn.model_selection import GridSearchCV
tuned_parameters= [{'n_estimators':[100,200,500],
                  'max_depth':[3,5,7], ##range(3,10,2)
                  'learning_rate':[0.5, 1.0],
                  'subsample':[0.75,0.8,0.85,0.9]
                  }]
tuned_parameters= [{'n_estimators':[100,200,500,1000]
                  }]
clf = GridSearchCV(XGBClassifier(silent=0,nthread=4,learning_rate= 0.5,min_child_weight=1, max_depth=3,gamma=0,subsample=1,colsample_bytree=1,reg_lambda=1,seed=1000), param_grid=tuned_parameters,scoring='roc_auc',n_jobs=4,iid=False,cv=5)  
clf.fit(X_train, y_train)
##clf.grid_scores_, clf.best_params_, clf.best_score_
print(clf.best_params_)
y_true, y_pred = y_test, clf.predict(X_test)
print"Accuracy : %.4g" % metrics.accuracy_score(y_true, y_pred) 
y_proba=clf.predict_proba(X_test)[:,1]
print "AUC Score (Train): %f" % metrics.roc_auc_score(y_true, y_proba)               

  

代碼2:

from sklearn.model_selection import GridSearchCV
parameters= [{'learning_rate':[0.01,0.1,0.3],'n_estimators':[1000,1200,1500,2000,2500]}]
clf = GridSearchCV(XGBClassifier(
             max_depth=3,
             min_child_weight=1,
             gamma=0.5,
             subsample=0.6,
             colsample_bytree=0.6,
             objective= 'binary:logistic', #邏輯迴歸損失函數
             scale_pos_weight=1,
             reg_alpha=0,
             reg_lambda=1,
             seed=27
            ), 
            param_grid=parameters,scoring='roc_auc')  
clf.fit(X_train, y_train)
print(clf.best_params_)  
y_pre= clf.predict(X_test)
y_pro= clf.predict_proba(X_test)[:,1] 
print "AUC Score : %f" % metrics.roc_auc_score(y_test, y_pro) 
print"Accuracy : %.4g" % metrics.accuracy_score(y_test, y_pre) 

  

輸出特徵重要性:

import pandas as pd
import matplotlib.pylab as plt
feat_imp = pd.Series(clf.booster().get_fscore()).sort_values(ascending=False)
feat_imp.plot(kind='bar', title='Feature Importances')
plt.ylabel('Feature Importance Score')
plt.show()

  

補充:關於隨機種子——random_state

  random_state是一個隨機種子,是在任意帶有隨機性的類或者函數裏做爲參數來控制隨機模式。random_state取某一個值的時候,也就肯定了一種規則。

  random_state能夠用於不少函數,好比訓練集測試集的劃分;構建決策樹;構建隨機森林

1,劃分訓練集和測試集的類train_test_split

  隨機數種子控制每次劃分訓練集和測試集的模式,其取值不變時劃分獲得的結果如出一轍,其值改變時,劃分獲得的結果不一樣。若不設置此參數,則函數會自動選擇一種隨機模式,獲得的結果也就不一樣。

2,構建決策樹的函數

clf = tree.DecisionTreeClassifier(criterion="entropy",random_state=30,splitter="random")

  其取值不變時,用相同的訓練集建樹獲得的結果如出一轍,對測試集的預測結果也是同樣的

  其取值改變時,獲得的結果不一樣;

  若不設置此參數,則函數會自動選擇一種隨機模式,每次獲得的結果也就不一樣。

3,構建隨機森林

clf = RandomForestClassifier(random_state=0)

  其取值不變時,用相同的訓練集建樹獲得的結果如出一轍,對測試集的預測結果也是同樣的

  其取值改變時,獲得的結果不一樣;

  若不設置此參數,則函數會自動選擇一種隨機模式,每次獲得的結果也就不一樣。

4,總結

  在須要設置random_state的地方給其賦值,當屢次運行此段代碼獲得徹底同樣的結果,別人運行代碼也能夠復現你的過程。若不設置此參數則會隨機選擇一個種子,執行結果也會所以不一樣。雖然能夠對random_state進行調參,可是調參後再訓練集上表現好的模型未必在陌生訓練集上表現好,因此通常會隨便選擇一個random_state的值做爲參數。

  對於那些本質上是隨機的過程,咱們有必要控制隨機的狀態,這樣才能重複的展示相同的結果。若是對隨機狀態不加控制,那麼實驗的結果就沒法固定,而是隨機的顯示。

 

參考文獻:

https://blog.csdn.net/waitingzby/article/details/81610495

https://blog.csdn.net/u011089523/article/details/72812019

 https://blog.csdn.net/luanpeng825485697/article/details/79907149

https://xgboost.readthedocs.io/en/latest/parameter.html#general-parameters

相關文章
相關標籤/搜索