2016-02-26 14 views
5

Próbuję użyć XGBoost do modelowania częstotliwości roszczeń danych generowanych przez okresy nierównej długości ekspozycji, ale nie udało się uzyskać modelu, który by prawidłowo traktował ekspozycję. Normalnie zrobiłbym to poprzez ustawienie log (ekspozycji) jako przesunięcia - czy możesz to zrobić w XGBoost?XGBoost - Rozkład Poissona z różną ekspozycją/przesunięciem

(Podobny pytanie zamieszczone tutaj: xgboost, offset exposure?)

celu zilustrowania problemu, kodowania R poniżej wytwarza jakieś dane z pól:

  • X1, X2 - czynniki (0 lub 1)
  • ekspozycja - długość okresu polityki w zakresie obserwowanych danych
  • częstotliwości - średnia liczba zastrzeżeń na ekspozycji jednostkowej
  • zastrzeżeniach - liczba obserwowanych zastrz s ~ Poisson (częstotliwość * ekspozycji)

Celem jest przewidywanie częstotliwości za pomocą x1 i x2 - prawdziwym modelem jest: częstotliwość = 2 jeśli x1 = x2 = 1, częstotliwość = 1 w przeciwnym razie.

Ekspozycji nie można wykorzystać do przewidywania częstotliwości, ponieważ nie jest znana na początku polisy. Jedyny sposób, w jaki możemy go użyć, to powiedzieć: oczekiwana liczba roszczeń = ekspozycja o częstotliwości *.

Kod stara się przewidzieć, to za pomocą XGBoost przez:

  1. Ustawianie ekspozycji jako masy w matrycy modelu
  2. Ustawienie logu (ekspozycji) jako offset

poniżej tych, I "Pokazałem, jak poradziłbym sobie z sytuacją drzewa (rpart) lub gbm.

set.seed(1) 
size<-10000 
d <- data.frame(
    x1 = sample(c(0,1),size,replace=T,prob=c(0.5,0.5)), 
    x2 = sample(c(0,1),size,replace=T,prob=c(0.5,0.5)), 
    exposure = runif(size, 1, 10)*0.3 
) 
d$frequency <- 2^(d$x1==1 & d$x2==1) 
d$claims <- rpois(size, lambda = d$frequency * d$exposure) 

#### Try to fit using XGBoost 
require(xgboost) 
param0 <- list(
    "objective" = "count:poisson" 
    , "eval_metric" = "logloss" 
    , "eta" = 1 
    , "subsample" = 1 
    , "colsample_bytree" = 1 
    , "min_child_weight" = 1 
    , "max_depth" = 2 
) 

## 1 - set weight in xgb.Matrix 

xgtrain = xgb.DMatrix(as.matrix(d[,c("x1","x2")]), label = d$claims, weight = d$exposure) 
xgb = xgb.train(
    nrounds = 1 
    , params = param0 
    , data = xgtrain 
) 

d$XGB_P_1 <- predict(xgb, xgtrain) 

## 2 - set as offset in xgb.Matrix 
xgtrain.mf <- model.frame(as.formula("claims~x1+x2+offset(log(exposure))"),d) 
xgtrain.m <- model.matrix(attr(xgtrain.mf,"terms"),data = d) 
xgtrain <- xgb.DMatrix(xgtrain.m,label = d$claims) 

xgb = xgb.train(
    nrounds = 1 
    , params = param0 
    , data = xgtrain 
) 

d$XGB_P_2 <- predict(model, xgtrain) 

#### Fit a tree 
require(rpart) 
d[,"tree_response"] <- cbind(d$exposure,d$claims) 
tree <- rpart(tree_response ~ x1 + x2, 
       data = d, 
       method = "poisson") 

d$Tree_F <- predict(tree, newdata = d) 

#### Fit a GBM 

gbm <- gbm(claims~x1+x2+offset(log(exposure)), 
      data = d, 
      distribution = "poisson", 
      n.trees = 1, 
      shrinkage=1, 
      interaction.depth=2, 
      bag.fraction = 0.5) 

d$GBM_F <- predict(gbm, newdata = d, n.trees = 1, type="response") 

Odpowiedz

1

przynajmniej funkcji glm w R, modelowanie count ~ x1 + x2 + offset(log(exposure)) z family=poisson(link='log') odpowiada modelowania I(count/exposure) ~ x1 + x2 z family=poisson(link='log') i weight=exposure. Oznacza to normalizację liczby przez ekspozycję na częstotliwość, a częstotliwość modelu z ekspozycją jako wagę. Twoje oszacowane współczynniki powinny być takie same w obu przypadkach, gdy używasz glm do regresji Poissona. Wypróbuj za pomocą przykładowego zestawu danych:

Nie jestem do końca pewien, co odpowiada objective='count:poisson', ale spodziewam się ustawić zmienną docelową jako częstotliwość (liczba/ekspozycja) i używając ekspozycji, ponieważ waga w xgboost byłaby do zrobienia, gdy ekspozycje są różne.

+0

Dzięki Vinh. Jest to jedna z opcji, które wypróbowałem, ale nie sprawdziła się w prostych przypadkach. Wierzę, że znalazłem rozwiązanie i opublikowałem je tutaj. –

1

Mam teraz pracowali się, jak to zrobić za pomocą SetInfo zmienić atrybut base_margin być przesunięte (jako predyktora liniowego), tj:

setinfo(xgtrain, "base_margin", log(d$exposure)) 
Powiązane problemy