2012-02-15 27 views
12

Utilizo el paquete R GBM como probablemente mi primera elección para el modelado predictivo. Hay muchas cosas buenas acerca de este algoritmo, pero una "mala" es que no puedo usar fácilmente el código del modelo para obtener nuevos datos fuera de R. Quiero escribir código que pueda usarse en SAS u otro sistema (comenzaré con SAS (sin acceso a IML)).GBM Rule Generation - Consejo de codificación

Digamos que tengo el siguiente conjunto de datos (de GBM manual) y código del modelo:

library(gbm) 
set.seed(1234) 
N <- 1000 
X1 <- runif(N) 
X2 <- 2*runif(N) 
X3 <- ordered(sample(letters[1:4],N,replace=TRUE),levels=letters[4:1]) 
X4 <- factor(sample(letters[1:6],N,replace=TRUE)) 
X5 <- factor(sample(letters[1:3],N,replace=TRUE)) 
X6 <- 3*runif(N) 
mu <- c(-1,0,1,2)[as.numeric(X3)] 
SNR <- 10 # signal-to-noise ratio 
Y <- X1**1.5 + 2 * (X2**.5) + mu 
sigma <- sqrt(var(Y)/SNR) 
Y <- Y + rnorm(N,0,sigma) 
# introduce some missing values 
#X1[sample(1:N,size=500)] <- NA 
X4[sample(1:N,size=300)] <- NA 
X3[sample(1:N,size=30)] <- NA 
data <- data.frame(Y=Y,X1=X1,X2=X2,X3=X3,X4=X4,X5=X5,X6=X6) 
# fit initial model 

gbm1 <- gbm(Y~X1+X2+X3+X4+X5+X6, # formula 
data=data, # dataset 
var.monotone=c(0,0,0,0,0,0), # -1: monotone decrease, 
distribution="gaussian", 
n.trees=2, # number of trees 
shrinkage=0.005, # shrinkage or learning rate, 
# 0.001 to 0.1 usually work 
interaction.depth=5, # 1: additive model, 2: two-way interactions, etc. 
bag.fraction = 1, # subsampling fraction, 0.5 is probably best 
train.fraction = 1, # fraction of data for training, 
# first train.fraction*N used for training 
n.minobsinnode = 10, # minimum total weight needed in each node 
cv.folds = 5, # do 5-fold cross-validation 
keep.data=TRUE, # keep a copy of the dataset with the object 
verbose=TRUE) # print out progress 

ahora puedo ver los árboles individuales utilizando pretty.gbm.tree como en

pretty.gbm.tree(gbm1,i.tree = 1)[1:7] 

que produce

SplitVar SplitCodePred LeftNode RightNode MissingNode ErrorReduction Weight 
0   2 1.5000000000  1   8   15  983.34315 1000 
1   1 1.0309565491  2   6   7  190.62220 501 
2   2 0.5000000000  3   4   5  75.85130 277 
3  -1 -0.0102671518  -1  -1   -1  0.00000 139 
4  -1 -0.0050342273  -1  -1   -1  0.00000 138 
5  -1 -0.0076601353  -1  -1   -1  0.00000 277 
6  -1 -0.0014569934  -1  -1   -1  0.00000 224 
7  -1 -0.0048866747  -1  -1   -1  0.00000 501 
8   1 0.6015416372  9  10   14  160.97007 469 
9  -1 0.0007403551  -1  -1   -1  0.00000 142 
10  2 2.5000000000  11  12   13  85.54573 327 
11  -1 0.0046278704  -1  -1   -1  0.00000 168 
12  -1 0.0097445692  -1  -1   -1  0.00000 159 
13  -1 0.0071158065  -1  -1   -1  0.00000 327 
14  -1 0.0051854993  -1  -1   -1  0.00000 469 
15  -1 0.0005408284  -1  -1   -1  0.00000  30 

La página de manual 18 muestra lo siguiente:

enter image description here

Basado en el manual, la primera división se produce en la tercera variable (cero basado en esta salida), que es gbm1$var.names[3] "X3". La variable es factor ordenado

types<-lapply (lapply(data[,gbm1$var.names],class), function(i) ifelse (strsplit(i[1]," ")[1]=="ordered","ordered",i)) 

types[3] 

Por lo tanto, la división es de 1,5 significa que el valor 'D y C' levels[[3]][1:2.5] (también cero basados) divide al nodo izquierdo y los otros levels[[3]][3:4] ir a la derecha.

A continuación, la regla continúa con una división en gbm1$var.names[2] como se indica mediante SplitVar = 1 en la fila indexada 1.

Alguien ha nada para moverse a través de esta estructura de datos (para cada árbol) por escrito, la construcción de normas tales como :

"Si X3 en ('d', 'c') y X2 < 1,0309565491 y X3 en ('d') entonces scoreTreeOne = -0.0102671518"

que es como creo que la primera regla de esta árbol lee.

¿O tiene algún consejo sobre cómo hacer esto mejor?

+0

Creo que IML en SAS podría ofrecer una solución. Sin embargo, realmente no entiendo R aquí. ¿Podría interpretar más claramente sobre el patrón? –

+0

Hola Robbie: sin acceso a IML. Buscando un paso de datos. Agregué la descripción del contenido de la columna para pretty.gbm.tree. –

+0

Tal vez podría echarle un vistazo a [rattle] (http://cran.r-project.org/web/packages/rattle/index.html) que implementa dicha funcionalidad para los árboles de decisión (como se discutió en [Cross Validated] (http://stats.stackexchange.com/a/12089/930)). No me compruebo si esto se aplica con la salida 'gbm'. – chl

Respuesta

0

Aquí hay una respuesta muy genérica de cómo se puede hacer esto.

Agregue un código R para escribir la salida en un archivo. https://stat.ethz.ch/R-manual/R-devel/library/base/html/sink.html

Luego, a través de SAS, acceda a la capacidad de ejecutar con R: http://support.sas.com/documentation/cdl/en/hostunx/61879/HTML/default/viewer.htm#a000303551.htm (Tendrá que saber dónde está su R ejecutable es de señalar con el código R que ha escrito anteriormente en el ejecutable)

A partir de ahí debería poder manipular la salida dentro de SAS para hacer cualquier puntuación que pueda necesitar.

Si es simplemente una puntuación única y no un proceso, omita la ejecución SAS de R y simplemente desarrolle código SAS para analizar a través del archivo de salida R.

1

El paquete mlmeta tiene una función gbm2sas que exporta un modelo de GBM de R a SAS.