以下內容屬于經驗總結的建模模塊,建模模塊目前包括 lasso 和 XGBoost,文章內容屬于 XGBoost。
建模
XGBoost
功能介紹
xgboost 是大規模并行 boosted tree 的工具。
XGBoost 支持以 CART 作為基分類器、線性分類器,相當于帶 L1 和 L2 正則化項的邏輯斯蒂回歸(分類問題)或者線性回歸問題。
XGBoost 在優化時對代價函數進行了二階泰勒展開,同時用到了一階和二階導數,并支持自定義代價函數,只要函數可一階和二階求導。
XGBoost 在代價函數里加入了正則項,用于控制模型的復雜度。正則項里包含了樹的葉子節點個數、每個葉子節點上輸出的 Score 的 L2 模的平方和。從 bias-variance tradeoff 角度來講,正則項降低了模型的 vairance,使學習出來的模型更加簡單,防止過擬合。
XGBoost 在進行完一次迭代后,會將葉子節點的權重乘上該系數,主要是為了削弱每棵樹的影響,讓后面有更大的學習空間,實際應用中,一般將學習速率 eta 設置得小一點,然后迭代次數設置得大一點。
XGBoost 支持列抽樣(column subsampling),能夠降低過擬合,還能減少計算。
對于缺失值的處理,對于特征的值有缺失的樣本,XGBoost 可以自動學習出它的分裂方向。
-
xgboost工具支持并行。XGBoost 的并行不是 tree 粒度的并行,XGBoost 也是一次迭代完才能進行下一次迭代的(第 t 次迭代的代價函數里包含了前面t-1次迭代的預測值)。XGBoost 的并行是在特征粒度上的。我們知道,決策樹的學習最耗時的一個步驟就是對特征的值進行排序(因為要確定最佳分割點),XGBoost 在訓練之前,預先對數據進行了排序,然后保存為 block 結構,后面的迭代中重復地使用這個結構,大大減小計算量。這個 block 結構也使得并行成為了可能,在進行節點的分裂時,需要計算每個特征的增益,最終選增益最大的那個特征去做分裂,那么各個特征的增益計算就可以開多線程進行。
?
利用 xgboost 進一步優化模型,提升 kaggle 機器學習模型的得分。
語法
import xgboost as xgb
dtrain = xgb.DMatrix(X_train, label = y)#DMatrix 是 xgb 存儲信息的單位,本步驟把數據放進這里面去
dtest = xgb.DMatrix(X_test)
params = {"max_depth":2, "eta":0.1}#max_depth:最大深度。eta 和 gradiant boosting 中的 learning rate 參數類似。通過減少每一步的權重,可以提高模型的穩定性。 典型值為 0.01-0.2。
model = xgb.cv(params, dtrain, num_boost_round=500, early_stopping_rounds=100)# CV 用法及參數見下文
model.loc[30:,["test-rmse-mean", "train-rmse-mean"]].plot()
Early_stopping_rounds: 提前終止程序
如果有評價數據,可以提前終止程序,這樣可以找到最優的迭代次數。如果要提前終止程序必須至少有一個評價數據在參數evals
中。 超過一個則使用最后一個。
train(..., evals=evals, early_stopping_rounds=10)
此模型下,機器會一直學習到 validation score 不再增長。每經過 early_stopping_rounds 輪,誤差應該都有所下降,否則不應該繼續學習。
如果出現了提前終止,模型會出現兩個額外情況:bst.best_score
和 bst.best_iteration
. 注意此處 train() 會返回最后一次循環的模型,而非最好的循環的模型。
此方法適用于各類最低 (RMSE, log loss, etc.) 或最高 (MAP, NDCG, AUC) 誤差計算。
觀察誤差情況
語法如下:
model.loc[30:,["test-rmse-mean", "train-rmse-mean"]].plot()
橫軸 boost round,最大 500;縱軸是平均誤差。
利用 XGBoost 建模
語法如下:
model_xgb = xgb.XGBRegressor(n_estimators=360, max_depth=2, learning_rate=0.1) #用了xgb.cv 調參。n_estimators:訓練的輪數;max_depth:最大深度。
model_xgb.fit(X_train, y)
利用 lasso 驗證 XGBoost
語法如下:
xgb_preds = np.expm1(model_xgb.predict(X_test))
lasso_preds = np.expm1(model_lasso.predict(X_test))
predictions = pd.DataFrame({"xgb":xgb_preds, "lasso":lasso_preds})
predictions.plot(x = "xgb", y = "lasso", kind = "scatter")
橫軸:xgb 預測值,縱軸:lasso 預測值。散點圖可以看出強線性相關,兩個預測結果大部分基本一致。
很多情況下把不相關的結果進行加權平均是有用的,通常能夠優化結果,雖然在這個案例里幫助不大。
最終結果
preds = 0.7*lasso_preds + 0.3*xgb_preds#把 lasso 和 xgb 加權后得到最終預測值,為啥是 0.7 和 0.3?經驗吧
solution = pd.DataFrame({"id":test.Id, "SalePrice":preds})
solution.to_csv("ridge_sol.csv", index = False)
XGBoost 的參數
1. eta [默認 0.3]
和 GBM 中的 learning rate 參數類似。 通過減少每一步的權重,可以提高模型的穩定性。 典型值為 0.01-0.2。
2. min_child_weight [默認 1]
決定最小葉子節點樣本權重和。和 GBM 的 min_child_leaf 參數類似,但不完全一樣。XGBoost 的這個參數是最小樣本權重的和,而 GBM 參數是最小樣本總數。這個參數用于避免過擬合。當它的值較大時,可以避免模型學習到局部的特殊樣本。但是如果這個值過高,會導致欠擬合。這個參數需要使用 CV 來調整。
3. max_depth [默認 6]
和 GBM 中的參數相同,這個值為樹的最大深度。這個值也是用來避免過擬合的。max_depth 越大,模型會學到更具體更局部的樣本。需要使用 CV 函數來進行調優。 典型值:3-10
4. max_leaf_nodes
樹上最大的節點或葉子的數量。 可以替代 max_depth 的作用。因為如果生成的是二叉樹,一個深度為 n 的樹最多生成 n2 個葉子。 如果定義了這個參數,GBM 會忽略 max_depth 參數。
5. gamma [默認 0]
在節點分裂時,只有分裂后損失函數的值下降了,才會分裂這個節點。Gamma 指定了節點分裂所需的最小損失函數下降值。 這個參數的值越大,算法越保守。這個參數的值和損失函數息息相關,所以是需要調整的。
6、max_delta_step[默認 0]
這參數限制每棵樹權重改變的最大步長。如果這個參數的值為 0,那就意味著沒有約束。如果它被賦予了某個正值,那么它會讓這個算法更加保守。 通常,這個參數不需要設置。但是當各類別的樣本十分不平衡時,它對邏輯回歸是很有幫助的。 這個參數一般用不到,但是你可以挖掘出來它更多的用處。
7. subsample [默認 1]
和 GBM 中的 subsample 參數一模一樣。這個參數控制對于每棵樹,隨機采樣的比例。 減小這個參數的值,算法會更加保守,避免過擬合。但是,如果這個值設置得過小,它可能會導致欠擬合。 典型值:0.5-1
8. colsample_bytree [默認 1]
和 GBM 里面的 max_features 參數類似。用來控制每棵隨機采樣的列數的占比 (每一列是一個特征)。 典型值:0.5-1
9. colsample_bylevel [默認 1]
用來控制樹的每一級的每一次分裂,對列數的采樣的占比。 我個人一般不太用這個參數,因為 subsample 參數和 colsample_bytree 參數可以起到相同的作用。但是如果感興趣,可以挖掘這個參數更多的用處。
10. lambda [默認 1]
權重的 L2 正則化項。(和 Ridge regression 類似)。 這個參數是用來控制 XGBoost 的正則化部分的。雖然大部分數據科學家很少用到這個參數,但是這個參數在減少過擬合上還是可以挖掘出更多用處的。
11. alpha [默認 1]
權重的 L1 正則化項。(和 Lasso regression 類似)。 可以應用在很高維度的情況下,使得算法的速度更快。
12. scale_pos_weight [默認 1]
在各類別樣本十分不平衡時,把這個參數設定為一個正值,可以使算法更快收斂。
學習目標參數
這個參數用來控制理想的優化目標和每一步結果的度量方法。
1. objective [默認 reg:linear]
這個參數定義需要被最小化的損失函數。最常用的值有:
binary:logistic 二分類的邏輯回歸,返回預測的概率 (不是類別)。 multi:softmax 使用 softmax 的多分類器,返回預測的類別 (不是概率)。
在這種情況下,你還需要多設一個參數:num_class(類別數目)。 multi:softprob 和 multi:softmax 參數一樣,但是返回的是每個數據屬于各個類別的概率。
2. eval_metric [默認值取決于 objective 參數的取值]
對于有效數據的度量方法。對于回歸問題,默認值是 rmse,對于分類問題,默認值是 error。 典型值有:
rmse 均方根誤差、mae 平均絕對誤差、logloss 負對數似然函數值、error 二分類錯誤率 (閾值為 0.5)、merror 多分類錯誤率、mlogloss 多分類 logloss 損失函數、auc 曲線下面積
3. seed [默認 0]
隨機數的種子設置它可以復現隨機數據的結果,也可以用于調整參數。