2015-12-05 2 views
1

Pourquoi prédire avec biglm différer de prédire avec lm?Prédire avec des facteurs biglm

Voici mon code pour générer des données: (certes bâclée)

require(data.table) 
require(biganalytics) 

#create a data set with factor variables and one continuous numerical variable 
LETTERS702 <- c(LETTERS, sapply(LETTERS, function(x) paste0(x, LETTERS))) 
data = data.table(ded = runif(100), cont = runif(100), fac1 = as.factor(LETTERS702[1:10])) 
data[, cont := as.factor(ifelse(cont < .25, 100, 
        ifelse(cont < .5, 200, 
         ifelse(cont < .75, 300, 
           cont))))] 
newdata = data.table(ded = runif(50), cont = runif(50), fac1 = as.factor(LETTERS702[7:12])) 
newdata[, cont := as.factor(ifelse(cont < .25, 100, 
        ifelse(cont < .5, 200, 
          ifelse(cont < .75, 300, 
            cont))))] 

#add the levels from the old data to the new data 
levels(newdata$fac1) = c(levels(newdata$fac1),levels(data$fac1)) 
levels(newdata$cont) = c(levels(newdata$cont),levels(data$cont)) 

levels(data$fac1) = c(levels(data$fac1),levels(newdata$fac1)) 
levels(data$cont) = c(levels(data$cont),levels(newdata$cont)) 

Maintenant, quand je lance une régression de film et d'essayer de créer des valeurs prévues dans le nouveau tableau de données, cela fonctionne comme prévu:

reg =lm(ded ~ fac1 + cont, data = data) 
summary(reg) 

newdata[fac1 %in% data$fac1 & cont %in% data$cont, ded_hat := predict(reg, newdata[fac1 %in% data$fac1 & cont %in% data$cont, ])] 

head(newdata) 
     ded cont fac1 ded_hat 
1: 0.1820960 200 G 0.4636306 
2: 0.2561465 300 H 0.5412485 
3: 0.8711127 300 I 0.5351451 
4: 0.9839877 200 J 0.5737994 
5: 0.8802973 200 K  NA 
6: 0.1385486 200 L  NA 

Mais quand j'essaie d'utiliser biglm, Toutes les nouvelles valeurs prédites sont NA:

reg = biglm(ded ~ fac1 + cont, data = data) 
summary(reg) 

newdata[fac1 %in% data$fac1 & cont %in% data$cont, ded_hat := predict(reg, newdata[fac1 %in% data$fac1 & cont %in% data$cont, ])] 

head(newdata) 
     ded cont fac1 ded_hat 
1: 0.1820960 200 G  NA 
2: 0.2561465 300 H  NA 
3: 0.8711127 300 I  NA 
4: 0.9839877 200 J  NA 
5: 0.8802973 200 K  NA 
6: 0.1385486 200 L  NA 

Que se passe-t-il ici? Qu'est-ce que j'ai besoin de changer pour avoir la prédiction de travailler pour biglm?

Répondre

1

est ici le travail autour je me suis retrouvé à l'aide:

  1. Assurez-vous que les nouvelles données a toutes les niveaux des anciennes données
  2. Utilisez le package mannequins de se développer dans des variables muettes pour chaque niveau manuellement
  3. Exécuter la régression et de faire la prédiction

    require(data.table) 
    require(dummies) 
    
    #create a data set with factor variables and one continuous numerical variable 
    LETTERS702 <- c(LETTERS, sapply(LETTERS, function(x) paste0(x, LETTERS))) 
    data = data.table(ded = runif(100), cont = runif(100), fac1 = as.factor(LETTERS702[1:10])) 
    data[, cont := as.factor(ifelse(cont < .25, 100, 
           ifelse(cont < .5, 200, 
            ifelse(cont < .75, 300, 
              cont))))] 
    
    newdata = data.table(ded = runif(50), cont = runif(50), fac1 = as.factor(LETTERS702[7:12])) 
    newdata[, cont := as.factor(ifelse(cont < .25, 100, 
           ifelse(cont < .5, 200, 
             ifelse(cont < .75, 300, 
               cont))))] 
    
    #add the levels from the old data to the new data 
    levels(newdata$fac1) = c(levels(newdata$fac1),levels(data$fac1)) 
    levels(newdata$cont) = c(levels(newdata$cont),levels(data$cont)) 
    
    #generate a dummy for each fac1 
    data = as.data.table(dummy.data.frame(data, names = c("fac1","cont"))) 
    newdata = as.data.table(dummy.data.frame(newdata, names = c("fac1","cont"), drop = F)) 
    
    #a list of variable names in both data sets 
    datanames = (names(data)) 
    newdatanames = (names(newdata)) 
    varnames = subset(newdatanames, newdatanames %in% datanames) 
    
    #regression 
    reg = lm(ded ~ ., data = data) 
    
    #prediction 
    newdata[, ded_hat := predict(reg, newdata)] 
    
1

Il semble que biglm ne supprime pas automatiquement les niveaux inutilisés ou ne les ajuste pas de manière sophistiquée pour différents niveaux de facteur.

Si vous

reg1 = lm(ded ~ fac1 + cont, data = data) 
reg2 = biglm(ded ~ fac1 + cont, data = data) 

et comparez les coefficients, vous verrez que les non NA valeurs correspondent, mais il y a 14 NA supplémentaires des valeurs ... qui se propagent probablement par le calcul de prédiction.

length(coef(reg1)) 
## [1] 36 
length(coef(reg2)) 
## [1] 50 
## unname() and c() remove extraneous attributes 
all.equal(unname(coef(reg1)),unname(c(na.omit(coef(reg2))))) ## TRUE 

Si vous utilisez droplevels

reg3 = biglm(ded ~ fac1 + cont, data = droplevels(data)) 

alors les coefficients correspondent, mais la prédiction différente échoue (Error in x %*% coef(object) : non-conformable arguments), vraisemblablement parce qu'il ya un ensemble différent de niveaux dans les nouvelles données - vous aurez de travailler un peu plus difficile à définir les niveaux de facteur de sorte qu'ils correspondent ...