Sto tentando di utilizzare XGBoost per modellare la frequenza di reclami dei dati generati da periodi di esposizione di lunghezza non uguale, ma non è stato possibile ottenere il modello per trattare correttamente l'esposizione. Lo farei normalmente impostando il log (esposizione) come offset - sei in grado di farlo in XGBoost?XGBoost - Distribuzione di Poisson con variazione dell'esposizione/offset
(Una domanda simile è stato postato qui: xgboost, offset exposure?)
Per illustrare il problema, il codice R sotto genera alcuni dati con i campi:
- x1, x2 - Fattori (0 o 1)
- esposizione - durata del periodo di politica su dati osservati
- frequenza - numero di rivendicazione osservato - numero dei sinistri per esposizione unità
- sinistri significare s ~ Poisson (frequenza * esposizione)
L'obiettivo è di predire la frequenza utilizzando x1 e x2 - il modello vero è: frequenza = 2 se x1 = x2 = 1, frequenza = 1 altrimenti.
L'esposizione non può essere utilizzata per prevedere la frequenza poiché non è nota all'inizio di una politica. L'unico modo in cui possiamo usarlo è dire: numero previsto di reclami = frequenza * esposizione.
il codice tenta di prevedere questo utilizzando XGBoost da:
- impostazione dell'esposizione come un peso nel modello a matrice
- registro Setting (esposizione) come offset
Sotto questi, Ho mostrato come gestirò la situazione per un albero (rpart) o 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")
Grazie Vinh. Questa è una delle opzioni che ho provato ma non sembra funzionare come previsto in casi semplici. Credo di aver trovato la soluzione e l'ho postata qui. –