R的lm函数如何处理因子水平(在C_Cdqrls中?)?

Chr*_*oph 5 r linear-regression lm

或者换句话说:在这种情况下使用哪种算法?我想他们使用判别分析,如第4.4章所述。在詹姆斯等。等 “ R语言中的统计学习及其应用简介”?

输入意见后,我还可以按如下方式重述该问题:

  • 魔术的第一部分出现在ans <- .External2(C_modelmatrix, t, data)model.matrix.default其中)中,模型根据因子水平而变化=> 我想我理解这部分。
  • 第二部分仍然涉及z <- .Call(C_Cdqrls, x, y, tol, FALSE)并且我不希望线性回归和判别分析在数学水平上是相同的。 我会错过明显的东西吗?同样,我的stats程序包是二进制文件,我无权访问源代码...

我在本文中找到了非常有用的解释,但在某些时候它仅说明

... [解构]可能是一项复杂的任务,因此我们将不做详细介绍,以免将我们带到太远的地方...

我在文档中找不到任何内容,也无法debug(lm) 使用可再现的示例了解我所理解的情况:

n <- 10
p <- 6
set.seed(1)
x <- seq(0, 20, length.out = n) + rnorm(n, 0, 1)
y <- c(1:3)
y <- sample(y, n, replace = TRUE)
z <- 10*y*x + 10*y + 10 + rnorm(n, 0, 1)
debug(lm)
fit <- lm(z ~ x*y)
Run Code Online (Sandbox Code Playgroud)

之后mt <- attr(mf, "terms")看起来像

mt
# ...
# attr(,"dataClasses")
#         z         x         y 
# "numeric" "numeric" "numeric" 
Run Code Online (Sandbox Code Playgroud)

而之后

n <- 10
p <- 6
set.seed(1)
x <- seq(0, 20, length.out = n) + rnorm(n, 0, 1)
y <- c(1:3)
y <- sample(y, n, replace = TRUE)
z <- 10*y*x + 10*y + 10 + rnorm(n, 0, 1)
y <- as.factor(y)
debug(lm)
fit <- lm(z ~ x*y)
Run Code Online (Sandbox Code Playgroud)

mt <- attr(mf, "terms")看起来像

mt
# ...
# attr(,"dataClasses")
#         z         x         y 
# "numeric" "numeric"  "factor"
Run Code Online (Sandbox Code Playgroud)

但是后来看来,他们随时调用lm.fit(x, y, offset = offset, singular.ok = singular.ok, ...),并有z <- .Call(C_Cdqrls, x, y, tol, FALSE)我以为只是工作没有因素。上面的链接很好地解释了模型矩阵和qr分解的所有内容,我认为在有因素的情况下这是行不通的。

编辑:之后的模型矩阵x <- model.matrix(mt, mf, contrasts)已经不同。如果是数字

x
   (Intercept)          x y       x:y
1            1 -0.6264538 3 -1.879361
2            1  2.4058655 1  2.405866
3            1  3.6088158 2  7.217632
4            1  8.2619475 1  8.261947
5            1  9.2183967 1  9.218397
6            1 10.2906427 2 20.581285
7            1 13.8207624 1 13.820762
8            1 16.2938803 2 32.587761
9            1 18.3535591 3 55.060677
10           1 19.6946116 2 39.389223
attr(,"assign")
[1] 0 1 2 3
Run Code Online (Sandbox Code Playgroud)

如果有因素

x
   (Intercept)          x y2 y3      x:y2       x:y3
1            1 -0.6264538  0  1  0.000000 -0.6264538
2            1  2.4058655  0  0  0.000000  0.0000000
3            1  3.6088158  1  0  3.608816  0.0000000
4            1  8.2619475  0  0  0.000000  0.0000000
5            1  9.2183967  0  0  0.000000  0.0000000
6            1 10.2906427  1  0 10.290643  0.0000000
7            1 13.8207624  0  0  0.000000  0.0000000
8            1 16.2938803  1  0 16.293880  0.0000000
9            1 18.3535591  0  1  0.000000 18.3535591
10           1 19.6946116  1  0 19.694612  0.0000000
attr(,"assign")
[1] 0 1 2 2 3 3
attr(,"contrasts")
attr(,"contrasts")$`y`
[1] "contr.treatment"
Run Code Online (Sandbox Code Playgroud)

编辑2:部分问题也可以在这里找到

Chr*_*oph 0

借助这个问题的答案,我意识到答案很简单:

\n\n

如果因素属于变量(预测变量),则model.matrix只会变大。由此可见,C_Cdqrls可以处理模型矩阵。

\n\n

仅当因变量包含因素、线性回归或lm无法正常工作时,判别分析才是一种可能性。(乍一看,似乎stats::glm使用了 logit 模型。

\n\n

来自维基百科

\n\n
\n

判别函数分析与逻辑回归非常相似,\n 两者都可以用来回答相同的研究问题。\n 逻辑回归没有判别分析\n 那么多的假设和限制。但是,当满足判别分析\xe2\x80\x99\n 假设时,它比逻辑回归更强大。\n 与逻辑回归不同,判别分析可用于\n 小样本量。事实证明,当样本量相等且方差/协方差同质性成立时,判别分析更加准确。考虑到所有这些,逻辑回归已成为常见的选择,因为判别分析的假设很少得到满足。

\n
\n\n
\n\n

例子:

\n\n
x <- seq(0, 10, length.out = 21)\ny <- c(0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)\ny <- as.factor(y)\ndf <- data.frame(x = x, y = y)\n\n# see ??numeric and the \xe2\x80\x98Warning\xe2\x80\x99 section in factor:\nplot(x, as.numeric(levels(y))[y], ylim = c(0, 1.2))\n\nfit <- lm(y ~ x, data = df)\nprint(summary(fit))\n\nfit_glm <- stats::glm(y ~ x, family = binomial(link = "logit"), data = df, control = list(maxit = 50))\nprint(summary(fit_glm))\n\ndf$glm.probs <- stats::predict(fit_glm, newdata = df, type = "response")\ndf$glm.pred = ifelse(glm.probs > 0.5, 1, 0)\npoints(x, df$glm.pred + 0.05, col = "red")\n
Run Code Online (Sandbox Code Playgroud)\n