当lm的预测值无方差时,为什么会有R ^ 2值(由它决定)?


10

考虑以下R代码:

example <- function(n) {
    X <- 1:n
    Y <- rep(1,n)
    return(lm(Y~X))
}
#(2.13.0, i386-pc-mingw32)
summary(example(7))    #R^2 = .1963
summary(example(62))   #R^2 = .4529
summary(example(4540)) #R^2 = .7832
summary(example(104))) #R^2 = 0
#I did a search for n 6:10000, the result for R^2 is NaN for
#n = 2, 4, 16, 64, 256, 1024, 2085 (not a typo), 4096, 6175 (not a typo), and 8340 (not a typo)

查看http://svn.r-project.org/R/trunk/src/appl/dqrls.f)并没有帮助我了解发生了什么,因为我不知道Fortran。在另一个问题中,有人回答说,X的系数接近但不为0时,应该归因于浮点机公差误差。

[R2当的值coef(example(n))["X"]接近0 时,会更大。但是...

  1. 为什么根本没有值? [R2
  2. (具体地)确定什么?
  3. 为什么NaN结果看似有序发展?
  4. 为什么违反这种进展?
  5. 这是什么“预期”行为?

注意:7的R ^ 2应该为0.4542,以查看更具建设性的内容。:-)

1
好吧,公平地讲,用户应该在使用工具之前实际上了解统计方法(不像Excel用户(好的,对不起,不好意思))。由于很明显R ^ 2接近1且误差接近零,因此我们比将NaN值与函数的限制混淆更了解。现在,如果存在R ^ 2发散为ynoise-> 0的问题(例如,用替换上面的Y语句Y <- rep(1,n)+runif(n)*ynoise),那将很有趣:-)
Carl

@eznme:我认为结果是特定于机器的,或者至少是32或64位的;我有一台32位计算机,其0.1为7,但是我的64位计算机为NaN。有趣的是,在64位计算机上,不是NaN的R ^ 2都非常接近0.5。当我想到它时,这是有道理的,但一开始让我感到惊讶。
亚伦(Aaron)

1
您正在研究双精度舍入误差。看一下系数;例如apply(as.matrix(2:17), 1, function(n){example(n)$coefficients[-1]})。(我的结果是,在Win 7 x64 Xeon上,范围从-8e-17到+ 3e-16;大约一半是真零。)顺便说一句,Fortran源代码没有帮助:它只是dqrdc的包装;这就是您要查看的代码。
ub

1
(续)但是,作为用户,选择简历是一个更好的选择,原因很简单,勤奋的统计分析是用户而不是开发人员的责任。如果用户看到相对于RSS幅度的错误,那么他们应该在进一步报告之前进行自己的后处理。在编程方面,我想知道如何尽可能地避免这些数字问题,但是我认为这些问题无法逃脱,这是拥有勤奋的用户和教育他人的重要条件。[R2
Iterator

Answers:


6

正如Ben Bolker所说,该问题的答案可以在的代码中找到summary.lm()

这是标题:

function (object, correlation = FALSE, symbolic.cor = FALSE, 
    ...) 
{

因此,让我们x <- 1:1000; y <- rep(1,1000); z <- lm(y ~ x)看一下经过稍微修改的摘录:

    p <- z$rank
    rdf <- z$df.residual
    Qr <- stats:::qr.lm(z)
    n <- NROW(Qr$qr)
    r <- z$residuals
    f <- z$fitted.values
    w <- z$weights
    if (is.null(w)) {
        mss <- sum((f - mean(f))^2)
        rss <- sum(r^2)
    }
    ans <- z[c("call", "terms")]
    if (p != attr(z$terms, "intercept")) {
        df.int <- 1L
        ans$r.squared <- mss/(mss + rss)
        ans$adj.r.squared <- 1 - (1 - ans$r.squared) * ((n - 
            df.int)/rdf)
    }

0.4998923

用一个问题回答一个问题:我们从中得出什么?:)

mssrss[R2mssrss0/0NaN2^(1:k)


更新1:这是R帮助的一个不错的线程,解决了R中未解决下溢警告的一些原因。

此外,此SO Q&A包含许多有趣的帖子,以及有关下溢,高精度算术等的有用链接。


8

我很好奇您提出这个问题的动机。我想不出这种行为应有的实际原因。出于好奇心是另一种原因(而IMO更明智)。我认为您不需要了解FORTRAN即可回答此问题,但我想您确实需要了解QR分解及其在线性回归中的使用。如果您将其dqrls视为计算QR分解并返回有关它的各种信息的黑匣子,则可以跟踪这些步骤...或直接进入summary.lm并跟踪以了解R ^ 2的计算方式。特别是:

mss <- if (attr(z$terms, "intercept")) 
          sum((f - mean(f))^2)
       else sum(f^2)
rss <- sum(r^2)
## ... stuff ...
ans$r.squared <- mss/(mss + rss)

然后,您必须返回lm.fit并看到拟合值的计算方式为r1 <- y - z$residuals(即,响应减去残差)。现在您可以找出决定残差值的原因以及该值减去均值的精确度是否为零,然后从中找出计算结果...


求知欲是我提出问题的主要原因。一位同事报告了此行为,我想四处看看,看看是否可以解决。在超出我的能力范围追查了该问题之后,我决定问这个问题。作为一个实际问题,有时会分批进行分析,否则会发生其他错误,这种行为使我感到“奇怪”。
russellpierce 2012年

1
mms和rss都是z的结果,z是summary.lm中lm对象的名称。因此,一个答案可能确实需要解释QR分解,其在线性回归中的使用,并特别要说明一些细节,这些细节在R底层的代码中实例化了QR分解,以解释为什么QR分解最终以近似0而不是0本身结束。
russellpierce 2012年

mssrss[R2[R2

[R2

0

[R2[R2=1个-SSË[R[RSSŤØŤ


1
您能否给出一种实际的情况,在这种情况下,这种行为很重要?
Ben Bolker

3
@Brandon-Iterator放进了笑脸,但你还是疯了!
卡尔·威索夫特

2
@eznme虽然错误很好,但是要抓住所有出现浮点问题的地方都非常困难,特别是在IEEE-754算法中。这里的教训是,即使使用R进行面包和黄油的计算也应谨慎处理。
Iterator 2012年

2
这些考虑尤为重要,因为约翰·钱伯斯(John Chambers)(S的创始人之一,因此是R的“祖父”)强烈强调使用R进行可靠的计算。 例如,参见钱伯斯(Chambers)的《用于数据分析的软件:使用R进行编程》(Springer Verlag 2008):“用于数据分析的计算和软件应该是值得信赖的:它们应该按照自己的主张去做,并且应该这样做。” [在第 3.]
whuber

2
问题是,无论好坏,R-core都无法(通过他们的看法)以很多很多检查来阻止代码的使用,从而拦截所有极端情况以及可能的奇怪用户错误-他们担心(我认为) (a)将花费大量时间,(b)使代码库大得多且难以阅读(因为实际上有数千种特殊情况),并且(c)通过一直强制执行此类检查来减慢执行速度即使在很多次重复计算的情况下。
Ben Bolker
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.