我有一个数据集,我将其拆分为测试/训练数据集。在那次拆分之后,我立即创建了一个物流模型:
logModel1 = glm(Y ~ . -var1 -var2 -var3, data=train, family=binomial)
如果我使用该模型对同一列车组进行预测,我不会出错(当然,这不是对我的模型的超级有用的测试)。所以我用下面的代码来预测我的测试集:
predictLog1 <- predict(logModel1, type="response", newdata=test)
但我得到以下错误:
model.frame.default中的错误(Terms,newdata,na.action=na.action,xlev=object$xlevels):因子myCharVar有了新的级别This是对myCharVar的观察,这是另一个。。。
以下是让我特别困惑的地方:
- myCharVar在我的训练集和测试集中都是一个字符变量。我已经向
str(test$myCharVar)
和str(train$myCharVar)
确认了这一点 - 我的模型甚至没有使用myCharVar作为预测的一部分
我在这个SO链接中找到了项目符号2的解释:"因子具有新的水平";变量I';我没有使用
建议从我的训练集和测试集中完全删除字符变量,这为我提供了一个变通方法,至少我不会被耽搁。但这似乎很不雅,而不是用"-myCharVar"将它们从模型中删除。如果有人理解为什么我的测试集中的字符变量会抛出"因子具有新级别"错误,我肯定会感兴趣。
在您链接的帖子中回答问题的人已经说明了为什么模型中仍然考虑myCharVar
。当使用z~.-y
时,公式基本上扩展为z~(x+y)-y
。
现在,为了回答您的另一个问题:考虑predict()
文档中的以下引用:"对于具有数字级别的因子变量,您可以在newdata中指定数值,而无需首先将变量转换为因子。检查这些数值以确保它们与级别匹配,然后将变量内部转换为因子"。
我认为我们可以假设myCharVar
也发生了同样的行为。myCharVar
值首先根据模型中相应的现有级别进行检查,这就是问题所在。测试集包含在模型训练过程中从未遇到的myCharVar
的值(请注意,glm
函数本身也执行因子转换。当需要进行转换时,它会发出警告)。总之,错误基本上意味着模型无法预测测试数据中的未知水平,而这些水平在模型训练过程中从未遇到过。
在这篇文章中,对这个问题进行了另一次澄清。