在Python中使用XGBoost
本文原是xgboost的官方文檔教程,但是鑒于其中部分內容敘述不清,部分內容也確實存在一定的問題,所以本人重寫了該部分。數據請前往Github此處下載
前置代碼
引用類庫,添加需要的函數
import numpy as np from sklearn.model_selection import train_test_split import xgboost as xgb import pandas as pd import matplotlib %matplotlib inline def GetNewDataByPandas():wine = pd.read_csv("/Data/UCI/wine/wine.csv")wine['alcohol**2'] = pow(wine["alcohol"], 2)wine['volatileAcidity*alcohol'] = wine["alcohol"] * wine['volatile acidity']y = np.array(wine.quality)X = np.array(wine.drop("quality", axis=1))# X = np.array(wine)columns = np.array(wine.columns)return X, y, columns直接從csv加載亦可
file_path = "/home/fonttian/Data/UCI/wine/wine.csv" data = np.genfromtxt(file_path, delimiter=',') dtrain_2 = xgb.DMatrix(data[1:1119, 0:11], data[1:1119, 11]) dtest_2 = xgb.DMatrix(data[1119:1599, 0:11], data[1119:1599, 11])加載數據
讀取數據并分割
# Read wine quality data from file X, y, wineNames = GetNewDataByPandas() # X, y, wineNames = GetDataByPandas() # split data to [0.8,0.2,01] x_train, x_predict, y_train, y_predict = train_test_split(X, y, test_size=0.10, random_state=100)# take fixed holdout set 30% of data rows x_train, x_test, y_train, y_test = train_test_split(x_train, y_train, test_size=0.2, random_state=100)展示數據
wineNames array(['fixed acidity', 'volatile acidity', 'citric acid','residual sugar', 'chlorides', 'free sulfur dioxide','total sulfur dioxide', 'density', 'pH', 'sulphates', 'alcohol','quality', 'alcohol**2', 'volatileAcidity*alcohol'], dtype=object) print(len(x_train),len(y_train)) print(len(x_test)) print(len(x_predict)) 1151 1151 288 160加載到DMatrix
設定參數
Booster參數
param = {'max_depth': 7, 'eta': 1, 'silent': 1, 'objective': 'reg:linear'} param['nthread'] = 4 param['seed'] = 100 param['eval_metric'] = 'auc'還可以指定多個ecal指標
param['eval_metric'] = ['auc', 'ams@0'] # 此處我們進行回歸運算,只設置rmse param['eval_metric'] = ['rmse'] param['eval_metric'] ['rmse']指定設置為監視性能的驗證
evallist = [(dtest, 'eval'), (dtrain, 'train')]訓練
訓練模型
在之前的代碼中,我將數據分割為 6:3:1,其分別為,訓練數據,性能監視用數據,和最后的預測數據。這個比例只是為了示例用,并不具有代表性。
在數據集不足的情況下,除預測數據外,也可以不分割訓練集與驗證集,使用交叉驗證方法,不適用性能監視數據(驗證集)有時也是可行的。請自行思考,進行選擇。
num_round = 10 bst_without_evallist = xgb.train(param, dtrain, num_round) num_round = 10 bst_with_evallist = xgb.train(param, dtrain, num_round, evallist) [0] eval-rmse:0.793859 train-rmse:0.68806 [1] eval-rmse:0.796485 train-rmse:0.474253 [2] eval-rmse:0.796662 train-rmse:0.450195 [3] eval-rmse:0.778571 train-rmse:0.400886 [4] eval-rmse:0.789566 train-rmse:0.340342 [5] eval-rmse:0.798235 train-rmse:0.27816 [6] eval-rmse:0.804898 train-rmse:0.244093 [7] eval-rmse:0.813786 train-rmse:0.212835 [8] eval-rmse:0.81194 train-rmse:0.190969 [9] eval-rmse:0.814219 train-rmse:0.159447模型持久化
models_path = "/home/fonttian/Models/Sklearn_book/xgboost/" bst_with_evallist.save_model(models_path+'bst_with_evallist_0001.model')模型與特征映射也可以轉存到文本文件中
# dump model bst_with_evallist.dump_model(models_path+'dump.raw.txt') # dump model with feature map bst_with_evallist.dump_model(models_path+'dump.raw.txt', models_path+'featmap.txt')可以按如下方式加載已保存的模型:
bst_with_evallist = xgb.Booster({'nthread': 4}) # init model bst_with_evallist.load_model(models_path+'bst_with_evallist_0001.model') # load data早停
如果您有一個驗證集, 你可以使用提前停止找到最佳數量的 boosting rounds(梯度次數). 提前停止至少需要一個 evals 集合. 如果有多個, 它將使用最后一個。
train(..., evals=evals, early_stopping_rounds=10)該模型將開始訓練, 直到驗證得分停止提高為止. 驗證錯誤需要至少每個 early_stopping_rounds 減少以繼續訓練.
如果提前停止,模型將有三個額外的字段: bst.best_score, bst.best_iteration 和 bst.best_ntree_limit. 請注意 train() 將從上一次迭代中返回一個模型, 而不是最好的一個.
這與兩個度量標準一起使用以達到最小化(RMSE, 對數損失等)和最大化(MAP, NDCG, AUC). 請注意, 如果您指定多個評估指標, 則 param [‘eval_metric’] 中的最后一個用于提前停止.
bst_with_evallist_and_early_stopping_10 = xgb.train(param, dtrain, num_round*100, evallist,early_stopping_rounds=10) [0] eval-rmse:0.793859 train-rmse:0.68806 Multiple eval metrics have been passed: 'train-rmse' will be used for early stopping.Will train until train-rmse hasn't improved in 10 rounds. [1] eval-rmse:0.796485 train-rmse:0.474253 [2] eval-rmse:0.796662 train-rmse:0.450195 [3] eval-rmse:0.778571 train-rmse:0.400886...[57] eval-rmse:0.822859 train-rmse:0.000586 [58] eval-rmse:0.822859 train-rmse:0.000586 Stopping. Best iteration: [48] eval-rmse:0.822859 train-rmse:0.000586 bst_with_evallist_and_early_stopping_100 = xgb.train(param, dtrain, num_round*100, evallist,early_stopping_rounds=100) [0] eval-rmse:0.793859 train-rmse:0.68806 Multiple eval metrics have been passed: 'train-rmse' will be used for early stopping.Will train until train-rmse hasn't improved in 100 rounds. [1] eval-rmse:0.796485 train-rmse:0.474253 [2] eval-rmse:0.796662 train-rmse:0.450195...[148] eval-rmse:0.822859 train-rmse:0.000586 Stopping. Best iteration: [48] eval-rmse:0.822859 train-rmse:0.000586預測
預測結果
當您 訓練/加載 一個模型并且準備好數據之后, 即可以開始做預測了.
dpredict = xgb.DMatrix(x_predict) # 啥都沒有 ypred_without_evallist = bst_without_evallist.predict(dpredict) # 沒有早停 ypred_with_evallist = bst_with_evallist.predict(dpredict) #有早停 ypred_with_evallist_and_early_stopping_100 = bst_with_evallist_and_early_stopping_100.predict(dpredict,ntree_limit=bst_with_evallist_and_early_stopping_100.best_ntree_limit)測試誤差
現在我們就可以對之前三種數據使用模式得到的模型進行性能對比。效果如下。不過值得注意的是,本處代碼重在展示使用方法,并不代表普適性。實際上,這里模型的最終效果表現確實也十分糟糕,我會在更之后的博客中,在同一數據集上展示其他使用方法和數據挖掘技巧,最終獲得效果更加明顯的模型。
from sklearn.metrics import mean_squared_error print("RMSE of bst_without_evallist :", np.sqrt(mean_squared_error(y_true=y_predict,y_pred=ypred_without_evallist)))print("RMSE of bst_with_evallist :", np.sqrt(mean_squared_error(y_true=y_predict,y_pred=ypred_with_evallist)))print("RMSE of bst_with_evallist_and_early_stopping_100 :", np.sqrt(mean_squared_error(y_true=y_predict,y_pred=ypred_with_evallist_and_early_stopping_100))) RMSE of bst_without_evallist : 0.7115641528672897 RMSE of bst_with_evallist : 0.7115641528672897 RMSE of bst_with_evallist_and_early_stopping_100 : 0.7051095825211103繪圖
您可以使用 plotting(繪圖)模塊來繪制出 importance(重要性)以及輸出的 tree(樹).如果需要直接輸出重要程度排名的話,則可以使用get_score方法或者get_fscore方法,兩者不同之處在于前者可以通過importance_type參數添加權重。
要繪制出 importance(重要性), 可以使用 plot_importance. 該函數需要安裝 matplotlib.
xgb.plot_importance(bst_with_evallist_and_early_stopping_100) <matplotlib.axes._subplots.AxesSubplot at 0x7f2707a6a080>輸出的 tree(樹)會通過 matplotlib 來展示, 使用 plot_tree 指定 target tree(目標樹)的序號. 該函數需要 graphviz 和 matplotlib.而且有一點要注意的是graphviz不僅僅是需要通過pip install graphviz來安裝,還需要在你的系統中安裝該軟件,否則xgboost中的該部分將無法使用。此處可以參考我的另外一篇文章
除此之外我們還需要為plot_tree輸入一個 matplotlib的ax,以控制輸出圖片的尺寸。
# xgb.plot_tree(bst, num_trees=2) xgb.to_graphviz(bst_with_evallist_and_early_stopping_100, num_trees=2) import matplotlib.pyplot as plt fig = plt.figure() ax = fig.add_axes([18.5,18.5,10.5,10.5]) xgb.plot_tree(bst_with_evallist_and_early_stopping_100, num_trees=2,ax=ax) plt.show()總結
以上是生活随笔為你收集整理的在Python中使用XGBoost的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 在Hyperopt框架下使用XGboos
- 下一篇: 在Python中使用lightgbm
