2016-05-18 63 views
0

我有一個名爲data的數據集,它有481 092行。predict.glm()在測試數據中有三個新類別(r)(錯誤)

我分裂data成相等的兩半:

  1. 第一半部(行1:240 546)被稱爲train和被用於glm();
  2. 第二半(行240 547:481 092)被稱爲test並且應該用於驗證模型;

然後,我開始迴歸:

testreg <- glm(train$returnShipment ~ train$size + train$color + train$price + 
       train$manufacturerID + train$salutation + train$state + 
       train$age + train$deliverytime, 
       family=binomial(link="logit"), data=train) 

現在預測:

prediction <- predict.glm(testreg, newdata=test, type="response") 

給我一個錯誤:

Error in model.frame.default(Terms, newdata, na.action=na.action, xlev=object$xlevels): 
Factor 'train$manufacturerID' has new levels 125, 136, 137 

現在我知道,這些水平省略在迴歸中,因爲它沒有顯示任何這些係數水平。

我試過這個:predict.lm() with an unknown factor level in test data。但它以某種方式不適合我,或者我可能只是不知道如何實現它。我想要預測相關的二元變量,但當然只能使用現有的係數。上面的鏈接建議告訴R具有新層次的行應該被稱爲/或被視爲NA。

我該怎麼辦?

編輯,建議的方法由李正東

我的第一步了問題:

xlevels <- testreg$xlevels$manufacturerID 
mID125 <- xlevels[1] 

mID125NULL!我做錯了什麼?

回答

3

由於您根據rownumbers劃分了traintest樣本,因此您的變量的某些因子水平在列車和測試樣本中均不會同等。

您需要進行分層抽樣以確保列車和測試樣本都具有所有因子水平表示。使用splitstackshape包裝中的stratified

3

這是不可能得到的新的因子水平估計,在固定效應模型,包括線性模型和廣義線性模型。 glm(以及lm)記錄了在模型擬合期間呈現和使用的因子水平,可在testreg$xlevels中找到。

您的模型估計模型公式爲:

returnShipment ~ size + color + price + manufacturerID + salutation + 
       state + age + deliverytime 

然後predict抱怨125,136,137 manufactureID新因子水平。這意味着,這些級別不在testreg$xlevels$manufactureID之內,因此沒有用於預測的相關係數。在這種情況下,我們不得不放棄這個因素變量,並使用一個預測公式:

returnShipment ~ size + color + price + salutation + 
       state + age + deliverytime 

然而,標準predict程序不能把你的自定義預測公式。有常用的兩種解決方案:

  1. 提取模型矩陣和模型係數從testreg,並手動預測我們想通過矩陣向量乘法模型項。這是the link在你的文章中給出的建議;
  2. test中的因子水平重置爲出現在testreg$xlevels$manufactureID中的任何一個水平,例如testreg$xlevels$manufactureID[1]。因此,我們仍然可以使用標準predict進行預測。

現在,讓我們先拿起用於模型擬合的因子水平

xlevels <- testreg$xlevels$manufacturerID 
mID125 <- xlevels[1] 

然後我們給這個級別的預測數據:

replacement <- factor(rep(mID125, length = nrow(test)), levels = xlevels) 
test$manufacturerID <- replacement 

而且我們已經準備好預測:

pred <- predict(testreg, test, type = "link") ## don't use type = "response" here!! 

最後,我們調整這個線性預測R,減去係數估計:

est <- coef(testreg)[paste0(manufacturerID, mID125)] 
pred <- pred - est 

最後,如果你想在原有規模的預測,你申請鏈接函數的反函數:

testreg$family$linkinv(pred) 

更新:

您抱怨說您在嘗試上述解決方案時遇到了各種麻煩。這是爲什麼。

您的代碼:

testreg <- glm(train$returnShipment~ train$size + train$color + 
       train$price + train$manufacturerID + train$salutation + 
       train$state + train$age + train$deliverytime, 
       family=binomial(link="logit"), data=train) 

是指定你的模型公式一個非常糟糕的方式。 train$returnShipment等將嚴格限制變量的環境到數據幀train,並且在稍後使用其他數據集(如test)進行預測時會遇到麻煩。

對於這樣的缺點一個簡單的例子,我們模擬了一些玩具的數據和適合GLM:

set.seed(0); y <- rnorm(50, 0, 1) 
set.seed(0); a <- sample(letters[1:4], 50, replace = TRUE) 
foo <- data.frame(y = y, a = factor(a)) 
toy <- glm(foo$y ~ foo$a, data = foo) ## bad style 

> toy$formula 
foo$y ~ foo$a 
> toy$xlevels 
$`foo$a` 
[1] "a" "b" "c" "d" 

現在,我們看到的一切都帶有一個前綴foo$。在預測:

newdata <- foo[1:2, ] ## take first 2 rows of "foo" as "newdata" 
rm(foo) ## remove "foo" from R session 
predict(toy, newdata) 

我們得到一個錯誤:

Error in eval(expr, envir, enclos) : object 'foo' not found

好風格是從功能的data參數指定獲取數據的環境:

foo <- data.frame(y = y, a = factor(a)) 
toy <- glm(y ~ a, data = foo) 

然後foo$消失。

> toy$formula 
y ~ a 
> toy$xlevels 
$a 
[1] "a" "b" "c" "d" 

這可以解釋兩件事情:

  1. 您的評論,當你做testreg$xlevels$manufactureID,你NULL向我抱怨;你貼
  2. 預測誤差

    Error in model.frame.default(Terms, newdata, na.action=na.action, xlev=object$xlevels): 
    Factor 'train$manufacturerID' has new levels 125, 136, 137 
    

    抱怨train$manufacturerID而不是test$manufacturerID

+0

謝謝。但我不想放棄一個完整的因子變量,而只是製造商ID的級別125,136和137。我可以像這樣使用你的第一條代碼行:mID125 < - manufacturerID [125]? – Vinc

+0

好吧,也許我誤解你或單詞因素變量。因此,變量manufacturerID的級別125,136和137未在glm()中使用,但存在於測試數據部分(您稱爲newdata)中。 – Vinc

+0

對不起,但我完全不明白。這就是爲什麼它不起作用。我會編輯我的問題,讓你知道我做得好嗎? – Vinc

相關問題