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:
- Ustawianie ekspozycji jako masy w matrycy modelu
- 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")
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. –