在固定效应建模中,包括线性模型和广义线性模型,不可能得到新的因子水平的估计。 glm(以及lm)记录模型拟合过程中呈现和使用的因子水平,可以在testreg$xlevels中找到。
您的模型估计公式为:
returnShipment ~ size + color + price + manufacturerID + salutation +
state + age + deliverytime
然后predict 抱怨manufactureID 的新因子水平为 125、136、137。这意味着,这些级别不在testreg$xlevels$manufactureID 内,因此没有相关的预测系数。在这种情况下,我们必须删除这个因子变量并使用预测公式:
returnShipment ~ size + color + price + salutation +
state + age + deliverytime
但是,标准的predict 例程无法采用您自定义的预测公式。通常有两种解决方案:
- 从
testreg中提取模型矩阵和模型系数,并通过矩阵向量乘法手动预测我们想要的模型项。这就是您帖子中给出的the link 的建议;
- 将
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!!
最后,我们通过减去因子估计来调整这个线性预测器:
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)
我们得到一个错误:
eval(expr, envir, enclos) 中的错误:找不到对象 'foo'
好的风格是指定从函数的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"
这可以解释两件事:
- 您在评论中向我抱怨说,当您执行
testreg$xlevels$manufactureID 时,您会得到NULL;
-
您发布的预测错误
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。