本教程是[學習機器學習](https://www.kaggle.com/dansbecker/learn-machine-learning)系列的一部分。 在此步驟中,您將學習如何使用功能強大的xgboost庫構建和優化模型.

什麼是 XGBoost

XGBoost 是處理標準表格類數據的主要模型(例如Pandas DataFrames中存儲的數據類型,而不是像圖像和視頻這樣的數據類型)。 XGBoost模型在目前的許多Kaggle比賽中佔據主導地位。

為了達到峯值準確度,XGBoost模型需要比Random Forest等技術更多的知識和_model調整。 在本教程之後,你將能夠

  • Follow XGBoost的完整建模工作流程
  • fine-tune XGBoost model以獲得最佳性能

XGBoost是Gradient Boosted Decision Trees(梯度提升決策樹) 演算法的實現(scikit-learn有另一個版本的演算法,但XGBoost有一些技術優勢。)什麼是Gradient Boosted Decision Trees? 我們將通過一個圖表展示

循環構建這些新模型並將它們組合成一個ensemble模型。 首先我們通過計算數據集中每個觀察值的誤差來開始循環。 下一步我們構建一個新模型來預測這些誤差。 然後將此error-predicting模型的預測添加到「ensemble of models」中。

我們根據所有之前模型的結果做一個預測。計算預測值與真實值的誤差,構建下一個模型,並將其添加到ensemble中。

我們需要一些基礎預測來開始這個循環。 在實踐中,最初的預測可能非常naive。 即使它的預測非常不準確,隨後的訓練也將解決這些錯誤。

這個過程可能聽起來很複雜,但使用xgboost的代碼很簡單。 我們將在下面的model tuning增加一些額外的解釋性細節。

例子

數據集來自kaggle.com/c/house-pric

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import Imputer

data = pd.read_csv(../input/train.csv)
data.dropna(axis=0, subset=[SalePrice], inplace=True)
y = data.SalePrice
X = data.drop([SalePrice], axis=1).select_dtypes(exclude=[object])
train_X, test_X, train_y, test_y = train_test_split(X.as_matrix(), y.as_matrix(), test_size=0.25)

my_imputer = Imputer()
train_X = my_imputer.fit_transform(train_X)
test_X = my_imputer.transform(test_X)
print(train_X.shape)
print(test_X.shape)
print(train_y.shape)
print(test_y.shape)

創建並訓練XGboost回歸模型

from xgboost import XGBRegressor

my_model = XGBRegressor()
# Add silent=True to avoid printing out updates with each cycle
my_model.fit(train_X, train_y, verbose=False)

評估並預測模型

# make predictions
predictions = my_model.predict(test_X)

from sklearn.metrics import mean_absolute_error
print("Mean Absolute Error : " + str(mean_absolute_error(predictions, test_y)))

模型調優

XGBoost有一些參數可以顯著影響模型的準確性和訓練速度。 應該瞭解的第一個參數是:n_estimators and early_stopping_roundsn_estimators 指定訓練循環次數

在 欠擬合 vs 過擬合 圖表, n_estimators讓訓練沿著圖表向右移動。 值太低會導致欠擬合,這對訓練數據和新數據的預測都是不準確的。 太大的值會導致過度擬合,這是對訓練數據的準確預測,但對新數據的預測不準確(這是我們關心的)。 通過實際實驗來找到理想的n_estimators。 典型值範圍為100-1000,但這很大程度上取決於下面討論的learning rate

early_stopping_rounds 提供了一種自動查找理想值的方法。 early_stopping_rounds會導致模型在validation score停止改善時停止迭代,即使迭代次數還沒有到n_estimators。為n_estimators設置一個高值然後使用early_stopping_rounds來找到停止迭代的最佳時間是明智的。

存在隨機的情況有時會導致validation score無法改善,因此需要指定一個數字,以確定在停止前允許多少輪退化。early_stopping_rounds = 5是一個合理的值。 因此,在五輪validation score無法改善之後訓練將停止。 以下是early_stopping的代碼:

my_model = XGBRegressor(n_estimators=1000)
my_model.fit(train_X, train_y, early_stopping_rounds=5,
eval_set=[(test_X, test_y)], verbose=False)
predictions = my_model.predict(test_X)

from sklearn.metrics import mean_absolute_error
print("Mean Absolute Error : " + str(mean_absolute_error(predictions, test_y)))

當使用early_stopping_rounds時,需要留出一些數據來檢查要使用的輪數。 如果以後想要使所有數據擬合模型,請將n_estimators設置為在早期停止運行時發現的最佳值。

learning_rate

對於更好的XGBoost模型,這是一個微妙但重要的技巧:

XGBoost模型不是通過簡單地將每個組件模型中的預測相加來獲得預測,而是在將它們添加之前將每個模型的預測乘以一個小數字。這意味著我們添加到集合中的每個樹都不會對最後結果有決定性的影響。在實踐中,這降低了模型過度擬合的傾向。

因此,使用一個較大的n_estimators值並不會造成過擬合。如果使用early_stopping_rounds,樹的數量會被設置成一個合適的值。

通常,較小的learning rate(以及大量的estimators)將產生更準確的XGBoost模型,但是由於它在整個循環中進行更多迭代,因此也將使模型更長時間進行訓練。 包含學習率的代碼如下:

my_model = XGBRegressor(n_estimators=1000, learning_rate=0.05)
my_model.fit(train_X, train_y, early_stopping_rounds=5,
eval_set=[(test_X, test_y)], verbose=False)
predictions = my_model.predict(test_X)

from sklearn.metrics import mean_absolute_error
print("Mean Absolute Error : " + str(mean_absolute_error(predictions, test_y)))

n_jobs

在考慮處理較大數據集時,可以使用並行度來更快地構建模型。 將參數n_jobs設置為機器上的核心數是很常見的做法。 如果跑較小的數據集,n_jobs參數的作用不明顯。

總結

XGBoost目前是用於在傳統數據(也稱為表格或結構數據)上構建精確模型的主要演算法。去應用它來改進你的模型吧!

from xgboost import XGBRegressor
from sklearn.metrics import mean_absolute_error

my_model1 = XGBRegressor()
my_model1.fit(train_X, train_y, verbose=False)
predictions = my_model1.predict(test_X)
print("Mean Absolute Error 1: " + str(mean_absolute_error(predictions, test_y)))

my_model2 = XGBRegressor(n_estimators=1000)
my_model2.fit(train_X, train_y, early_stopping_rounds=5,
eval_set=[(test_X, test_y)], verbose=False)
predictions = my_model2.predict(test_X)
print("Mean Absolute Error 2: " + str(mean_absolute_error(predictions, test_y)))

my_model3 = XGBRegressor(n_estimators=1000, learning_rate=0.05)
my_model3.fit(train_X, train_y,
eval_set=[(test_X, test_y)], verbose=False)
predictions = my_model3.predict(test_X)
print("Mean Absolute Error 3: " + str(mean_absolute_error(predictions, test_y)))

實踐

通過數據集做一些測試tianchi.aliyun.com/comp

我們先簡單看這個模型的訓練情況

import pandas as pd
from matplotlib import pyplot as plt
import xgboost as xgb
from sklearn.model_selection import learning_curve, train_test_split,GridSearchCV
from sklearn.metrics import accuracy_score

## 準備訓練集和測試集

data = pd.read_csv(../data/happiness_train_abbr.csv)
y=data[happiness]
data.drop(happiness,axis=1,inplace=True)
X=data
train_x, test_x, train_y, test_y = train_test_split (X, y, test_size =0.30, random_state = 33)

第一次設置300次的迭代,評測的指標是"merror","mlogloss",這是一個多分類問題。


## xgboost訓練

model = xgb.XGBClassifier(n_estimators=300)
model
eval_set = [(train_x, train_y), (test_x, test_y)]
model.fit(train_x, train_y, eval_set=eval_set, eval_metric=["merror", "mlogloss"],verbose=True)
predictions = model.predict(test_x)
from sklearn.metrics import mean_absolute_error
print("Mean Absolute Error : " + str(mean_absolute_error(predictions, test_y)))
accuracy = accuracy_score(test_y, predictions)
print("Accuracy: %.2f%%" % (accuracy * 100.0))

## 可視化訓練過程

results = model.evals_result()
epochs = len(results[validation_0][merror])
x_axis = range(0, epochs)
from matplotlib import pyplot
fig, ax = pyplot.subplots(1,2,figsize=(10,5))
ax[0].plot(x_axis, results[validation_0][mlogloss], label=Train)
ax[0].plot(x_axis, results[validation_1][mlogloss], label=Test)
ax[0].legend()
ax[0].set_title(XGBoost Log Loss)
ax[0].set_ylabel(Log Loss)
ax[0].set_xlabel(epochs)

ax[1].plot(x_axis, results[validation_0][merror], label=Train)
ax[1].plot(x_axis, results[validation_1][merror], label=Test)
ax[1].legend()
ax[1].set_title(XGBoost Classification Error)
ax[1].set_ylabel(Classification Error)
ax[1].set_xlabel(epochs)
pyplot.show()

可以看到在大約128次迭代之後,測試集上的誤差開始上升,已經進入了過擬合了。

如果設置了early_stopping_rounds,我們可以看看效果如何

model.fit(train_x, train_y, early_stopping_rounds=10,eval_set=eval_set, eval_metric=["merror", "mlogloss"],verbose=True)

這裡設置early_stopping_rounds=10,當mlogloss在10輪迭代之內,都沒有顯著改善的話,就停止訓練。

實際訓練效果,在第146次迭代就停止了,說明最好的效果實在136次左右。根據許多大牛的實踐經驗,選擇early_stopping_rounds=10%*n_estimators。

根據最佳訓練結果進行預測

print ("best iteration:",model.best_iteration)
limit = model.best_iteration
predictions = model.predict(test_x,ntree_limit=limit)
print("Mean Absolute Error : " + str(mean_absolute_error(predictions, test_y)))
accuracy = accuracy_score(test_y, predictions)
print("Accuracy: %.2f%%" % (accuracy * 100.0))

參考資料

kaggle.com/dansbecker/x

blog.csdn.net/lujiandon


推薦閱讀:
相關文章