model.matrix():在这种情况下,为什么我会失去对比度的控制权

时间:2016-07-01 17:13:29

标签: r regression glm lm anova

假设我们有一个玩具数据框:

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列的模型矩阵?如何获得我想要的模型矩阵?

1 个答案:

答案 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))
  1. 如果我们在RHS上只有x2,我们可以成功拦截拦截:

    model.matrix(~ x2 - 1, data = x)
    #          x2
    #1  0.8414710
    #2  0.9092974
    #3  0.1411200
    #4 -0.7568025
    
  2. 如果我们在RHS上只有x1,则不应用对比度:

    model.matrix(~ x1 - 1, data = x)
    #  x1a x1b
    #1   1   0
    #2   1   0
    #3   0   1
    #4   0   1
    
  3. 当我们同时拥有x1x2时,不会应用对比度:

    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
    
  4. 这意味着虽然存在差异:

    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故意想要这种非标准行为(出于某种原因),在这种情况下,我的回答中给出了可能的解决方法