假设我们有一个玩具数据框:
x <- data.frame(x1 = gl(3, 2, labels = letters[1:3]),
x2 = gl(3, 2, labels = LETTERS[1:3]))
我想构建一个模型矩阵
# x1b x1c x2B x2C
# 1 0 0 0 0
# 2 0 0 0 0
# 3 1 0 1 0
# 4 1 0 1 0
# 5 0 1 0 1
# 6 0 1 0 1
由:
model.matrix(~ x1 + x2 - 1, data = x,
contrasts.arg = list(x1 = contr.treatment(letters[1:3]),
x2 = contr.treatment(LETTERS[1:3])))
但实际上我得到了:
# x1a x1b x1c x2B x2C
# 1 1 0 0 0 0
# 2 1 0 0 0 0
# 3 0 1 0 1 0
# 4 0 1 0 1 0
# 5 0 0 1 0 1
# 6 0 0 1 0 1
# attr(,"assign")
# [1] 1 1 1 2 2
# attr(,"contrasts")
# attr(,"contrasts")$x1
# b c
# a 0 0
# b 1 0
# c 0 1
# attr(,"contrasts")$x2
# B C
# A 0 0
# B 1 0
# C 0 1
我有点困惑:
那我为什么要得到一个有5列的模型矩阵?如何获得我想要的模型矩阵?
答案 0 :(得分:1)
每当我们在R级别失去对某事物的控制时,在C级别必须有一些默认的,不可变的行为。 model.matrix.default()
的C代码可以在R源包中找到:< / p>
R-<release_number>/src/library/stats/src/model.c
我们可以在这里找到解释:
/* If there is no intercept we look through the factor pattern */
/* matrix and adjust the code for the first factor found so that */
/* it will be coded by dummy variables rather than contrasts. */
让我们用数据框
对此进行一个小测试x <- data.frame(x1 = gl(2, 2, labels = letters[1:2]), x2 = sin(1:4))
如果我们在RHS上只有x2
,我们可以成功拦截拦截:
model.matrix(~ x2 - 1, data = x)
# x2
#1 0.8414710
#2 0.9092974
#3 0.1411200
#4 -0.7568025
如果我们在RHS上只有x1
,则不应用对比度:
model.matrix(~ x1 - 1, data = x)
# x1a x1b
#1 1 0
#2 1 0
#3 0 1
#4 0 1
当我们同时拥有x1
和x2
时,不会应用对比度:
model.matrix(~ x1 + x2 - 1, data = x)
# x1a x1b x2
#1 1 0 0.8414710
#2 1 0 0.9092974
#3 0 1 0.1411200
#4 0 1 -0.7568025
这意味着虽然存在差异:
lm(y ~ x2, data = x)
lm(y ~ x2 - 1, data = x)
之间没有区别
lm(y ~ x1, data = x)
lm(y ~ x1 - 1, data = x)
或
lm(y ~ x1 + x2, data = x)
lm(y ~ x1 + x2 - 1, data = x)
这种行为的原因不是为了确保数值稳定性,而是为了确保估计/预测的敏感性。如果我们在将对比度应用于x1
时真的放弃了截距,我们最终会得到一个模型矩阵:
# x1b
#1 0
#2 0
#3 1
#4 1
效果是我们将级别a
的估计约束为0。
在这篇文章中:How can I force dropping intercept or equivalent in this linear model?,我们有一个数据集:
# Y X1 X2
#1 1.8376852 TRUE TRUE
#2 -2.1173739 TRUE FALSE
#3 1.3054450 FALSE TRUE
#4 -0.3476706 TRUE FALSE
#5 1.3219099 FALSE TRUE
#6 0.6781750 FALSE TRUE
此数据集中没有联合存在(X1 = FALSE, X2 = FALSE)
。但从广义上讲,model.matrix()
必须做一些安全和明智的事情。假设训练数据集中没有两个因子水平的联合存在意味着它们不需要被预测,这是有偏见的。如果我们在应用对比时真的放弃拦截,那么这种联合存在被限制在0.然而,该帖子的OP故意想要这种非标准行为(出于某种原因),在这种情况下,我的回答中给出了可能的解决方法