Xgboost是Boosting算法的其中一種,Boosting算法的思想是將許多弱分類器集成在一塊兒,造成一個強分類器。由於Xgboost是一種提高樹模型,因此它是將許多樹模型集成在一塊兒,造成一個很強的分類器。而所用到的樹模型則是CART迴歸樹模型。html
Xgboost是在GBDT的基礎上進行改進,使之更強大,適用於更大範圍。node
Xgboost通常和sklearn一塊兒使用,可是因爲sklearn中沒有集成Xgboost,因此才須要單獨下載安裝。python
Xgboost算法能夠給預測模型帶來能力的提高。當咱們對其表現有更多瞭解的時候,咱們會發現他有以下優點:git
實際上,Xgboost是以「正則化提高(regularized boosting)」 技術而聞名。Xgboost在代價函數里加入了正則項,用於控制模型的複雜度。正則項裏包含了樹的葉子節點個數,每一個葉子節點上輸出的score的L2模的平方和。從Bias-variance tradeoff角度來說,正則項下降了模型的variance,使學習出來的模型更加簡單,防止過擬合,這也是Xgboost優於傳統GBDT的一個特徵算法
Xgboost工具支持並行。衆所周知,Boosting算法是順序處理的,也是說Boosting不是一種串行的結構嗎?怎麼並行的?注意Xgboost的並行不是tree粒度的並行。Xgboost也是一次迭代完才能進行下一次迭代的(第t次迭代的代價函數裏包含)。Xgboost的並行式在特徵粒度上的,也就是說每一顆樹的構造都依賴於前一顆樹。c#
咱們知道,決策樹的學習最耗時的一個步驟就是對特徵的值進行排序(由於要肯定最佳分割點),Xgboost在訓練以前,預先對數據進行了排序,而後保存爲block結構,後面的迭代中重複使用這個結構,大大減少計算量。這個block結構也使得並行成爲了可能,在進行節點的分類時,須要計算每一個特徵的增益,大大減小計算量。這個block結構也使得並行成爲了可能,在進行節點的分裂的時候,須要計算每一個特徵的增益,最終選增益最大的那個特徵去作分裂,那麼各個特徵的增益計算就能夠開多線程進行。數組
Xgboost支持用戶自定義目標函數和評估函數,只要目標函數二階可導就行。它對模型增長了一個全新的維度,因此咱們的處理不會受到任何限制。緩存
對於特徵的值有缺失的樣本,Xgboost能夠自動學習出他的分裂方向。Xgboost內置處理缺失值的規則。用戶須要提供一個和其餘樣本不一樣的值,而後把它做爲一個參數穿進去,以此來做爲缺失值的取值。Xgboost在不一樣節點遇到缺失值時採用不一樣的處理方法,而且會學習將來遇到缺失值時的處理方法。多線程
Xgboost先從頂到底創建全部能夠創建的子樹,再從底到頂反向機芯剪枝,比起GBM,這樣不容易陷入局部最優解dom
Xgboost容許在每一輪Boosting迭代中使用交叉驗證。所以能夠方便的得到最優Boosting迭代次數,而GBM使用網格搜索,只能檢測有限個值。
1,點擊此處,下載對應本身Python版本的網址。
2,輸入安裝的程式:
pip install xgboost-0.81-cp37-cp37m-win_amd64.whl
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)
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):控制學習的場景,例如在迴歸問題中會使用不一樣的參數控制排序
缺省值爲gbtree
缺省值爲0
缺省值是當前系統能夠得到的最大線程數
XGBoost會自動設置,不須要手工設置
缺省值爲0.3
缺省值爲6
缺省值爲1
缺省值爲0
(在L1上沒有偏置項的正則,由於L1時偏置不重要)
這個參數是來控制理想的優化目標和每一步結果的度量方法。
缺省值爲0
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
有了參數列表和數據就能夠訓練模型了
num_round = 10 bst = xgb.train( plst, dtrain, num_round, evallist )
# 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))
在訓練完成以後能夠將模型保存下來,也能夠查看模型內部的結構
bst.save_model('test.model')
導出模型和特徵映射(Map)
你能夠導出模型到txt文件並瀏覽模型的含義:
# 導出模型到文件 bst.dump_model('dump.raw.txt') # 導出模型和特徵映射 bst.dump_model('dump.raw.txt','featmap.txt')
經過以下方式能夠加載模型
bst = xgb.Booster({'nthread':4}) # init model bst.load_model("model.bin") # load data
Xgboost有兩大類接口:Xgboost原生接口 和sklearn接口,而且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%
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()
重要特徵(值越大,說明該特徵越重要)顯示結果:
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' )
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%
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()
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)......"
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)
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,下降學習速率,肯定理想參數。
下面詳細的進行這些操做。
爲了肯定Boosting參數,咱們要先給其餘參數一個初始值。我們先按照以下方法取值:
注意,上面這些參數的值知識一個初始的估計值,後繼須要調優。這裏把學習速率就設成默認的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)
咱們先對這兩個參數調優,是由於他們對最終結果有很大的影響。首先,咱們先大範圍地粗略參數,而後再小範圍的微調。
注意:在這一節我會進行高負荷的柵格搜索(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參數取值範圍很大,這裏咱們設置爲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 參數。咱們分兩個階段來進行這個步驟。這兩個步驟都取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)等。
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)
使用梯度提高算法的好處是在提高樹被建立後,能夠相對直接地獲得每一個屬性的重要性得分。通常來講,重要性分數,衡量了特徵在模型中的提高決策樹構建中的價值。一個屬性越多的被用來在模型中構建決策樹,它的重要性就相對越高。
屬性重要性是經過對數據集中的每一個屬性進行計算,並進行排序獲得。在單個決策樹中經過每一個屬性分裂點改進性能度量的量來計算屬性重要性。由節點負責加權和記錄次數,也就是說一個屬性對分裂點改進性能度量越大(越靠近根節點),權值越大;被越多提高樹所選擇,屬性越重要。性能度量能夠是選擇分裂節點的Gini純度,也能夠是其餘度量函數。
最終將一個屬性在全部提高樹中的結果進行加權求和後而後平均,獲得重要性得分。
一個已訓練的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具備最低的重要性。
特徵重要性得分,能夠用於在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%,這多是對這樣一個小數據集的清洗,可是對於更大的數據集和使用交叉驗證做爲模型評估方案多是更有用的策略。
代碼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能夠用於不少函數,好比訓練集測試集的劃分;構建決策樹;構建隨機森林
隨機數種子控制每次劃分訓練集和測試集的模式,其取值不變時劃分獲得的結果如出一轍,其值改變時,劃分獲得的結果不一樣。若不設置此參數,則函數會自動選擇一種隨機模式,獲得的結果也就不一樣。
clf = tree.DecisionTreeClassifier(criterion="entropy",random_state=30,splitter="random")
其取值不變時,用相同的訓練集建樹獲得的結果如出一轍,對測試集的預測結果也是同樣的
其取值改變時,獲得的結果不一樣;
若不設置此參數,則函數會自動選擇一種隨機模式,每次獲得的結果也就不一樣。
clf = RandomForestClassifier(random_state=0)
其取值不變時,用相同的訓練集建樹獲得的結果如出一轍,對測試集的預測結果也是同樣的
其取值改變時,獲得的結果不一樣;
若不設置此參數,則函數會自動選擇一種隨機模式,每次獲得的結果也就不一樣。
在須要設置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