假设我有一个包含两个分类预测变量(a,b)和二元目标(y)变量的数据集。
> df <- data.frame(
> a = factor(c("cat1","cat2","cat3","cat1","cat2")),
> b = factor(c("cat1","cat1","cat3","cat2","cat2")),
> y = factor(c(T,F,T,F,T))
> )
数据中存在以下逻辑关系:
if (a = cat3) then (b = cat3 and y = true)
else if (a = b) then (y = true) else y = false
我想使用glm
为我的数据集构建模型。
glm
会自动对我的分类变量a和b应用参考单元格编码。它还会为每个因子变量找到正确数量的代码,因此不会引入alias
个变量(解释为here)。
然而,对于上面的数据集,可能会发生在为变量a生成的一个参考代码和一个变量b的参考代码之间存在线性关系。
查看我的模型的输出:
> model <- glm(y ~ ., family=binomial(link='logit'), data=df)
> summary(model)
...
Coefficients: (1 not defined because of singularities)
Estimate Std. Error z value Pr(>|z|)
(Intercept) 1.965e-16 1.732e+00 0.000 1.000
acat2 -2.396e-16 2.000e+00 0.000 1.000
acat3 1.857e+01 6.523e+03 0.003 0.998
bcat2 0.000e+00 2.000e+00 0.000 1.000
bcat3 NA NA NA NA # <- get rid of this?
我该如何处理这个案子?
有没有办法告诉glm省略一些生成的参考代码?
在实际问题中,我的"cat3"
值对应NA
。我在我的数据集的完全相同的实例中有两个有意义的因子变量NA
。
修改
经过检查的答案解决了这个问题,但是,在这个具体案例中,如评论中所指出的那样,可以简单地忽略奇点。
答案 0 :(得分:0)
根据该问题提出的意见是相关的,但尝试删除NA模型矩阵列可能仍然有用,这样您就可以将其与不进行此类排除进行比较,以便在等效性方面满足自己。
特别是,您可以在第二次运行中运行glm
两次删除冗余模型矩阵列:
model <- glm(y ~ ., family=binomial(link='logit'), data=df) # as in question
mm <- model.matrix(model)[, !is.na(coef(model)) ]
df0 <- data.frame(y = df$y, mm[, -1])
update(model, data = df0)
,并提供:
Call: glm(formula = y ~ ., family = binomial(link = "logit"), data = df0)
Coefficients:
(Intercept) acat2 acat3 bcat2
1.965e-16 -2.396e-16 1.857e+01 0.000e+00
Degrees of Freedom: 4 Total (i.e. Null); 1 Residual
Null Deviance: 6.73
Residual Deviance: 5.545 AIC: 13.55
请注意,如果您不想使用我们知道响应名为y的事实,那么我们可以提取响应及其名称,将上述df0
的分配替换为:
df0 <- data.frame(model.response(model.frame(model)), mm[, -1])
names(df0)[1] <- as.character(attr(terms(model), "variables")[[2]])