如何忽略因子参考单元格编码引入的线性相关变量
How to ignore linearly correlated variables introduced by factor reference cell coding
假设我有一个包含两个分类预测变量 (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
在我的数据集的完全相同的实例中。
编辑:
检查的答案解决了问题,但是,在这种特定情况下,正如评论中指出的那样,可以简单地忽略奇点。
问题下的评论是中肯的,但尝试消除 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]])
假设我有一个包含两个分类预测变量 (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
在我的数据集的完全相同的实例中。
编辑:
检查的答案解决了问题,但是,在这种特定情况下,正如评论中指出的那样,可以简单地忽略奇点。
问题下的评论是中肯的,但尝试消除 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]])