On Aug 24, 2010, at 3:16 PM, Daniel Yarlett wrote:

Hello,

I am using R to train a logistic regression model and save the resulting model to disk. I am then subsequently reloading these saved objects, and using predict.glm on them in order to make predictions about single- row data frames that are generated in real-time from requests arriving at an HTTP server. The following code demonstrates the sort of R calls that I have in
mind:

cases <- 2000000
data <-
data .frame (x1=runif(cases),x2=runif(cases),y=sample(0:1,cases,replace=TRUE))
lr1 <- glm(y~x1*x2,family=binomial,data=data)
new_data <- data.frame(x1=0,x2=0)
out <- predict(lr1,type="response",newdata=new_data)

The first thing I am noticing is that the models that I am storing are very
large because I am using large data-sets, and the models seem to store
residuals, fitted values and so on, by default.

object.size(lr1)
1056071320 bytes

Access to all this information is not necessary for my application -- all I really need is access to model$coefficients in order to make my predictions -- so I am wondering if there is some way to prevent this information from getting stored in the glm objects when they are created (or of removing it
after the models have been trained)? I have discovered the
model=FALSE,x=FALSE,y=FALSE switches to glm() and these seem to help
somewhat, but perhaps there is some other way of only recording the
coefficients of the model and other minimal details?

Perhaps instead:

lr2 <- coef ( glm (y~x1*x2,family=binomial,data=data,model=FALSE,x=FALSE,y=FALSE) )

object.size(lr2)

Will be much smaller


Secondly, on data-sets of the scale I am using, predict.glm seems to be
taking a very long time to make its predictions.

print(system.time(predict(lr1,type="response",newdata=new_data)))
  user  system elapsed
 0.136   0.040   0.175
print(system.time(predict(lr2,type="response",newdata=new_data)))
  user  system elapsed
 0.109   0.013   0.121

This may be an issue of swap-time, and so it could potentially be solved by addressing my first question above. However, given that I am essentially
asking R to compute

1 / (1 + exp(-(b0 + b1*x1 + b2*x2 + b3*x1*x2)))

I can't see any reason why this request should be taking longer than a
hundredth or a thousandth of a second, say.

You could try crossprod with a data.matrix and a matrix of coefficients.

1 / (1 + exp(-(crossprod(lr2, new_data)))

> cases <- 2000
> data <- data .frame(x1=runif(cases),x2=runif(cases),y=sample(0:1,cases,replace=TRUE))
> lr1 <- coef(glm(y~x1*x2,family=binomial,data=data))
> new_data <- matrix(c(1, x1=0,x2=0, x1x2=0), nrow=4)
# took me a while to figure out that I needed an interaction entry.
> out <- 1 / (1 + exp(-(crossprod(new_data,lr1))))
> out
          [,1]
[1,] 0.5107252
> lr1
(Intercept)          x1          x2       x1:x2
 0.04290728 -0.16826991 -0.03561711  0.06229122
> > object.size(lr1)
456 bytes


Obviously R is providing a much
greater level of functionality than I am requiring in this particular
instance, so my overall question is what is the best way for me to reduce the size of the data I have to store in my GLM models, and to increase the speed at which I can use R to generate predictions of this sort (i.e. for
novel x1,x2 pairs)?

I could obviously write a custom function / class which only stores the
model coefficients and computes predictions based on these using the
equation above, but before I go down this route I wanted to get come advice from the R community about whether there might be a better way to address this problem and/or whether I have missed something obvious (to others). I also want to avoid writing custom code if possible because that obviously means sacrificing the great generality and power of R which could clearly be
useful in my application down the line.

Many thanks in advance for your assistance,

Dan.


David Winsemius, MD
West Hartford, CT

______________________________________________
[email protected] mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.

Reply via email to