Durante la charla de Carlos Ortega del pasado jueves sobre el paquete caret
y sus concomitancias, se planteó el asunto de la optimización de los parámetros de un modelo usando rejillas (grids) de búsqueda.
Cuando un determinado algoritmo depende de, p.e., cuatro parámetros, se puede definir una rejilla como en
gbmGrid <- expand.grid(interaction.depth = c(1, 5, 9),
n.trees = (1:30)*50,
shrinkage = 0.1,
n.minobsinnode = 20)
Tengo por delante otro proyecto que tiene mucho de análisis exploratorio de datos. Sospecho que más de un árbol construiré. Los árboles son como la Wikipedia: prácticamente nunca el último pero casi siempre el primer recurso.
Esta vez, además, por entretenerme un poco, probaré el paquete [evtree](http://cran.r-project.org/web/packages/evtree/index.html)
. Aunque no porque espere sorprendentes mejoras con respecto a los tradicionales, ctree
y rpart
.
¿Qué tiene aquél que los diferencie de los otros dos? Que la optimización es global. Tanto ctree
como rpart
utilizan algoritmos recursivos: al definir un nuevo corte del espacio, el algoritmo solo tiene en cuenta la región definida por los cortes anteriores. La optimización es local. evtree
utiliza un algoritmo global de la familia de los evolucionarios (¡qué tufillo a lentorro!). Los detalles están aquí.
Avisé en mi entrada del otro día: no me preguntéis por qué (imponer restricciones en un problema de mínimos cuadrados).
Pero cuanto más pienso sobre ello, menos claro lo tengo. ¿Por qué restricciones?
Primero, el contexto. O el casi contexto. Porque no es exactamente así. Pero sí parecido. Supongamos que queremos predecir algo y construimos, p.e., 4 modelos. Se nos ocurre (y hay buenas razones para ello) combinar los predictores.
Sí, había restricciones. No me preguntéis por qué, pero los coeficientes tenían que ser positivos y sumar uno. Es decir, buscaba la combinación convexa de cuatro vectores que más se aproximase a y
en alguna métrica razonable. Y lo resolví así:
# prepare constrained optimization
y <- dat.clean$actual
x <- t(dat.clean[,2:5])
# target function: L2 first, then other metrics
L2 <- function(coef){
sum(abs((y - colSums(x * coef)))^1.5)
}
# restrictions: coefs > 0, sum(coefs) ~ 1
ui <- rbind(diag(4), c(-1,-1,-1,-1), c(1,1,1,1))
ci <- c(0,0,0,0,-1.000001,0.999999)
theta <- rep(0.25, 4)
best.coef <- constrOptim(theta, L2,
grad = NULL, ui = ui, ci = ci)
coefs <- best.coef$par
Esta entrada tiene un notable contenido publicitario: el pasado viernes se inauguró Martina Cocina (nota: la página es provisional), una cafetería-restaurante en el que ostento una participación del 50%.
Se trata de un lugar al que, por supuesto, mis lectores están invitados a descubrir en número 11 de la castiza plaza de Cascorro de Madrid.
Pero como estoy en un foro al que me obligo a no traer temas extemporáneos, confesaré a mis lectores que tengo dos proyectos en mente que guardan relación tanto con Martina Cocina como con los asuntos que esperan encontrar en estas páginas. El primero es que (si me dejan) trataré de aplicar lo que Dan Arieli nos enseña en Predictably Irrational a, principalmente aunque no exclusivamente, el diseño de la carta y los precios de los productos para ayudaros a vosotros, los clientes a elegir, ejem, más convenientemente (¿para quién?).