Tuning xgboost in R:Part 1


第一次調整Boosting算法的參數可能是一個非常艱難的任務。
有很多參數可供選擇,調整不同的參數會有不同的結果產生。
最好的調參可能是取決於數據。
每當我得到一個新的數據集,我都會學到一些新的東西。
對分類和回歸樹(CART)有很好的理解有助於我們理解boosting


我最喜歡的Boosting包是xgboost,它將在下面的所有示例中使用。
在討論數據之前,我們先談談一些我認為最重要的參數。
這些參數大多用於控制模型適合數據的程度。
我們希望能夠捕捉數據的結構,但僅限於真實的結構。
換句話說,我們不希望模型適合噪音(過擬合)

 

eta: 學習(或收縮)參數。
它控制Boosting中將使用來自新樹的多少信息。
該參數必須大於0並且被限制為1.
如果它接近零,我們將僅使用來自每個新樹的一小部分信息。
如果我們將eta設置為1,我們將使用新樹中的所有信息。
eta的大值導致更快的收斂和更多的過度擬合問題。
小數值可能需要許多樹來聚合。colsample_bylevel:就像隨機森林一樣,

有時候只需要看一些變量就可以增長樹中的每個新節點。
如果我們查看所有變量,算法需要更少的樹來收斂。
但例如,查看2/3的變量可能會導致模型更具魯棒性以適應過度擬合。
有一個類似的參數叫做colsample_bytree,它重新采樣每個新樹中的變量,
而不是每個新節點。

max_depth : 控制樹木的最大深度。 更深的樹有更多的終端節點並且適合更多的數據。 如果我們深入發展,融合也需要更少的樹木。 但是,如果樹要深一些,我們將使用來自第一棵樹的大量信息,算法的最終樹對丟失函數的重要性將會降低。 Boosting從使用許多樹木的信息中受益。 因此,巨大的樹木是不可取的。 較小的樹木也會增長得更快,並且因為Boosting在偽剩余中生長新的樹木,我們不需要為單個樹木進行任何驚人的調整。

 

sub_sample : 這個參數決定我們是估計一個Boosting還是一個隨機Boosting。 如果我們使用1,我們會獲得常規的Boosting。 0和1之間的值是隨機的情況。 隨機Boosting只使用一小部分數據來增長每棵樹。 例如,如果我們使用0.5,每棵樹將采樣50%的數據增長。 隨機增強是非常有用的,如果我們有異常值,因為它限制了它們對最終模型的影響,因為它們被放在幾個子樣本上。 而且,對於較小的實例,可能會有顯着的改進,但它們更易於過度擬合。

 

gamma:控制在樹中增長新節點所需的損失函數的最小減少量。 此參數對損失函數的規模很敏感,它將與響應變量的規模相關聯。 使用不同於0的gamma的主要結果是停止生成無用的樹的算法,這些樹幾乎不會減少樣本內誤差,並且可能導致過度擬合。 這個參數以后再說。

 

min_child_weigth :控制終端節點中觀察值(實例)的最小數量。 此參數的最小值為1,這使得樹只有一個觀測值的終端節點。 如果我們使用更大的值,我們將限制可能的完美擬合。 這個參數也將留給第二部分。

 

example:

 

數據服從一下等式:

   這里: ,。變量數量K將被設置為10,實例數量將被設置為1000。

 

實驗將更改每個Boosting參數,使所有其他參數保持不變以嘗試隔離其效果。 標准模型將具有以下參數:

eta:0.1

colsample_bylevel:2/3

sub_sample:0.5

我會將這些參數中的每一個更改為代碼中的值。 我們將分析測試樣本中的收斂性和均方根誤差(RMSE)。 下面的代碼將准備一切運行模型。

library(xgboost)
library(ggplot2)
library(reshape2)
library(Ecdat)
 
set.seed(1)
N = 1000
k = 10
x = matrix(rnorm(N*k),N,k)
b = (-1)^(1:k)
yaux=(x%*%b)^2
e = rnorm(N)
y=yaux+e
 
# = select train and test indexes = #
train=sample(1:N,800)
test=setdiff(1:N,train)
 
# = parameters = #
# = eta candidates = #
eta=c(0.05,0.1,0.2,0.5,1)
# = colsample_bylevel candidates = #
cs=c(1/3,2/3,1)
# = max_depth candidates = #
md=c(2,4,6,10)
# = sub_sample candidates = #
ss=c(0.25,0.5,0.75,1)
 
# = standard model is the second value  of each vector above = #
standard=c(2,2,3,2)
 
# = train and test data = #
xtrain = x[train,]
ytrain = y[train]
xtest = x[test,]
ytest = y[test]

  

eta:我們將開始分析eta參數。 下面的代碼估計每個候選eta的Boosting模型。 首先我們得到了收斂圖,這表明eta的更大值收斂得更快。 然而,圖下方的列車RMSE表明,更快的收斂並不能轉化為良好的樣本外表現。 較小的eta值如0.05和0.1是產生較小誤差的值。 我的觀點是,在這種情況下,0.1給我們一個良好的樣本外性能和可接受的收斂速度。 請注意,eta = 0.5和1的結果與其他結果相比非常糟糕。

set.seed(1)
conv_eta = matrix(NA,500,length(eta))
pred_eta = matrix(NA,length(test), length(eta))
colnames(conv_eta) = colnames(pred_eta) = eta
for(i in 1:length(eta)){
  params=list(eta = eta[i], colsample_bylevel=cs[standard[2]],
              subsample = ss[standard[4]], max_depth = md[standard[3]],
              min_child_weigth = 1)
  xgb=xgboost(xtrain, label = ytrain, nrounds = 500, params = params)
  conv_eta[,i] = xgb$evaluation_log$train_rmse
  pred_eta[,i] = predict(xgb, xtest)
}

  

conv_eta = data.frame(iter=1:500, conv_eta)
conv_eta = melt(conv_eta, id.vars = "iter")
ggplot(data = conv_eta) + geom_line(aes(x = iter, y = value, color = variable))

  

(RMSE_eta = sqrt(colMeans((ytest-pred_eta)^2)))
## 0.05 0.1 0.2 0.5 1 ## 9.964462 10.052367 10.223738 13.691344 20.929690

  

colsample_bylevel:下一個參數控制每個新節點中測試的變量(特征)的比例。 回想一下,如果我們使用1,所有變量都經過測試。 小於1的值只測試相應的變量部分。 收斂性表明該模型對colsample_bylevel不太敏感。 具有較小值的曲線略高於具有較大值的曲線。 最准確的模型似乎是每棵樹中使用25%樣本的模型。 這個結果可能會隨着不同類型的數據而改變。 例如,我們生成的數據使用相同的分布來創建所有響應變量,並且測試向變量賦予相似的權重,這使得采樣不那么重要。

set.seed(1)
conv_cs = matrix(NA,500,length(cs))
pred_cs = matrix(NA,length(test), length(cs))
colnames(conv_cs) = colnames(pred_cs) = cs
for(i in 1:length(cs)){
  params = list(eta = eta[standard[1]], colsample_bylevel = cs[i],
              subsample = ss[standard[4]], max_depth = md[standard[3]],
              min_child_weigth = 1)
  xgb=xgboost(xtrain, label = ytrain,nrounds = 500, params = params)
  conv_cs[,i] = xgb$evaluation_log$train_rmse
  pred_cs[,i] = predict(xgb, xtest)
}

  

conv_cs = data.frame(iter=1:500, conv_cs)
conv_cs = melt(conv_cs, id.vars = "iter")
ggplot(data = conv_cs) + geom_line(aes(x = iter, y = value, color = variable))

  

 

 

(RMSE_cs = sqrt(colMeans((ytest-pred_cs)^2)))

## 0.333333333333333 0.666666666666667                 1
##          10.29836          10.05237          10.20938

  

max_depth:第三個參數是每棵樹中允許的最大深度。 當然,如果我們種植更大的樹木,模型會更快地收斂(見下圖)。 但是,最好的示例外性能是max_depth = 4。 請記住,更大的樹木更可能導致過度貼合。 根據我的經驗,不需要使用大於4到6的值,但可能有例外。

set.seed(1)
conv_md=matrix(NA,500,length(md))
pred_md=matrix(NA,length(test),length(md))
colnames(conv_md)=colnames(pred_md)=md
for(i in 1:length(md)){
  params=list(eta=eta[standard[1]],colsample_bylevel=cs[standard[2]],
              subsample=ss[standard[4]],max_depth=md[i],
              min_child_weigth=1)
  xgb=xgboost(xtrain, label = ytrain,nrounds = 500,params=params)
  conv_md[,i] = xgb$evaluation_log$train_rmse
  pred_md[,i] = predict(xgb, xtest)
}

  

conv_md=data.frame(iter=1:500,conv_md)
conv_md=melt(conv_md,id.vars = "iter")
ggplot(data=conv_md)+geom_line(aes(x=iter,y=value,color=variable))

  

  

(RMSE_md=sqrt(colMeans((ytest-pred_md)^2)))

##         2         4         6        10
## 12.502733  9.374257 10.134965 10.100691

  

 sub_sample:下一個參數決定我們是否估計Boosting或Stochastic Boosting。 較小的值會導致樣本中的誤差更大,但它可能會產生更強大的樣本外估計。 但是,如前所述,對於具有許多特征的樣本,與觀察次數和數據非常嘈雜時相比,您將獲得更大的改進。 這里不是這種情況。 盡管如此,與確定性案例相比有一些改進,我相信這主要是由響應變量中的異常值引起的(boxplot變量y可以看到)。

set.seed(1)
conv_ss=matrix(NA,500,length(ss))
pred_ss=matrix(NA,length(test),length(ss))
colnames(conv_ss)=colnames(pred_ss)=ss
for(i in 1:length(ss)){
  params=list(eta=eta[standard[1]],colsample_bylevel=cs[standard[2]],
              subsample=ss[i],max_depth=md[standard[3]],
              min_child_weigth=1)
  xgb=xgboost(xtrain, label = ytrain,nrounds = 500,params=params)
  conv_ss[,i] = xgb$evaluation_log$train_rmse
  pred_ss[,i] = predict(xgb, xtest)
}

  

conv_ss=data.frame(iter=1:500,conv_ss)
conv_ss=melt(conv_ss,id.vars = "iter")
ggplot(data=conv_ss)+geom_line(aes(x=iter,y=value,color=variable))

  

 

(RMSE_ss=sqrt(colMeans((ytest-pred_ss)^2)))

##      0.25       0.5      0.75         1
##  9.731273 10.052367 11.119535 11.233855

  

這里的主要結論是,調整Boosting模型沒有獨特的規則。 最好的方法是測試幾種配置。

請繼續關注,如果你喜歡這篇文章,我們會盡快討論Boosting。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM