R : 나만의 그래디언트 부스팅 알고리즘 구현


10

내 자신의 그라디언트 부스팅 알고리즘을 작성하려고합니다. 나는이 같은 기존 패키지는 이해 gbm하고 xgboost,있지만이 알고리즘은 내 자신을 작성하여 작동 방식을 이해하고 싶었다.

iris데이터 세트를 사용하고 있으며 결과는 Sepal.Length(연속)입니다. 내 손실 함수는 mean(1/2*(y-yhat)^2)(기본적으로 앞면이 1/2 인 평균 제곱 오차)이므로 해당 그라디언트는 잔차 y - yhat입니다. 0에서 예측을 초기화하고 있습니다.

library(rpart)
data(iris)

#Define gradient
grad.fun <- function(y, yhat) {return(y - yhat)}

mod <- list()

grad_boost <- function(data, learning.rate, M, grad.fun) {
  # Initialize fit to be 0
  fit <- rep(0, nrow(data))
  grad <- grad.fun(y = data$Sepal.Length, yhat = fit)

  # Initialize model
  mod[[1]] <- fit

  # Loop over a total of M iterations
  for(i in 1:M){

    # Fit base learner (tree) to the gradient
    tmp <- data$Sepal.Length
    data$Sepal.Length <- grad
    base_learner <- rpart(Sepal.Length ~ ., data = data, control = ("maxdepth = 2"))
    data$Sepal.Length <- tmp

    # Fitted values by fitting current model
    fit <- fit + learning.rate * as.vector(predict(base_learner, newdata = data))

    # Update gradient
    grad <- grad.fun(y = data$Sepal.Length, yhat = fit)

    # Store current model (index is i + 1 because i = 1 contain the initialized estiamtes)
    mod[[i + 1]] <- base_learner

  }
  return(mod)
}

이를 통해 iris데이터 세트를 교육 및 테스트 데이터 세트로 나누고 모델을 적합하게 만듭니다.

train.dat <- iris[1:100, ]
test.dat <- iris[101:150, ]
learning.rate <- 0.001
M = 1000
my.model <- grad_boost(data = train.dat, learning.rate = learning.rate, M = M, grad.fun = grad.fun)

이제에서 예측 값을 계산합니다 my.model. 에 대한 my.model적합치는 다음과 같습니다 0 (vector of initial estimates) + learning.rate * predictions from tree 1 + learning rate * predictions from tree 2 + ... + learning.rate * predictions from tree M.

yhats.mymod <- apply(sapply(2:length(my.model), function(x) learning.rate * predict(my.model[[x]], newdata = test.dat)), 1, sum)

# Calculate RMSE
> sqrt(mean((test.dat$Sepal.Length - yhats.mymod)^2))
[1] 2.612972

몇 가지 질문이 있습니다

  1. 그래디언트 부스팅 알고리즘이 올바르게 보입니까?
  2. 예측값을 yhats.mymod올바르게 계산 했습니까 ?

답변:


0
  1. 그렇습니다. 각 단계에서, 유사-잔차에 적합하고, 적합에 대한 손실의 미분으로 계산됩니다. 당신은 질문의 시작 부분 에서이 그라디언트를 올바르게 도출했으며 심지어 2의 계수를 얻는 것을 귀찮게했습니다.
  2. 이것도 정확 해 보입니다. 훈련 중에했던 것처럼 학습 속도에 따라 가중치를 적용한 모델을 집계하고 있습니다.

그러나 요청되지 않은 문제를 해결하기 위해 훈련 설정에 몇 가지 단점이 있음을 알았습니다.

  • iris세트 동등 3 종 (setosa, 베르, virginica) 및 이들 데이터 사이의 인접한 분할된다. 훈련 데이터에는 모든 setosa와 versicolor가 있고 테스트 세트에는 모든 virginica 예제가 있습니다. 오버랩이 없으므로 샘플에서 벗어난 문제가 발생합니다. 이를 피하기 위해 훈련과 테스트 세트의 균형을 맞추는 것이 좋습니다.
  • 학습 속도와 모델 수의 조합이 나에게 너무 낮게 보입니다. 적합은로 수렴됩니다 (1-lr)^n. 로 lr = 1e-3그리고 n = 1000당신은 단지 데이터 크기의 63.2 %를 모델링 할 수 있습니다. 즉, 모든 모형이 모든 표본을 정확하게 예측하더라도 정확한 값의 63.2 %를 추정하게됩니다. 0 대신 평균으로 피팅을 초기화하면 효과가 단지 드래그 대신 평균에 대한 회귀이므로 도움이 될 것입니다.

귀하의 의견에 감사드립니다. "fit이 (1-lr) ^ n"으로 수렴하는 이유를 확장 할 수 있습니까? 이것의 근거는 무엇입니까?
YQW

잔차가 fit <- fit + learning.rate * prediction어디에 있기 때문이다 . 그래서 , 나 . 이것은 지수 이동 평균입니다. 당 위키 "K 조건 후 정지 생략 중량이다 (총 중량 부족" 학습 속도되어 있다 ). 평균 대신 추정값 0으로 시작하므로이 가중치를 생략하면 예측에서 바로 나옵니다. predictiontarget - fitfit <- fit + lr * (target - fit)fit <- fit * (1 - lr) + target * lr(1-α)^kαkn
mcskinner
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.