Почему существует значение R ^ 2 (и что его определяет), когда lm не имеет дисперсии в прогнозируемом значении?


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 ) не помог мне понять, что происходит, потому что я не знаю Фортрана. В другом вопросе ответили, что ошибки допусков машин с плавающей запятой были виноваты в коэффициентах для X, которые близки, но не совсем равны 0.

больше, когда значение дляближе к 0. Но ...R2coef(example(n))["X"]

  1. Почему значение вообще? R2
  2. Что (конкретно) это определяет?
  3. Почему, казалось бы, упорядоченная прогрессия NaNрезультатов?
  4. Почему нарушения этой прогрессии?
  5. Что из этого является «ожидаемым» поведением?

Примечание: R 7 для 7 должно быть 0,4542, чтобы увидеть что-то более конструктивное, см. Мой ответ. :-)

1
Ну, честно говоря, пользователь должен знать кое-что о статистических методах, прежде чем использовать инструменты (в отличие, скажем, от пользователей Excel (хорошо, извините за дешевый выстрел)). Поскольку довольно очевидно, что R ^ 2 приближается к 1, когда ошибка приближается к нулю, мы знаем лучше, чем путать значение NaN с пределом функции. Теперь, если бы была проблема с R ^ 2, расходящимся как ynoise -> 0 (скажем, заменим Y оператор выше на Y <- rep(1,n)+runif(n)*ynoise), это было бы интересно :-)
Carl Witthoft

@eznme: Я думаю, что результаты зависят от конкретной машины или, по крайней мере, от 32 до 64 бит; У меня есть 32-битная машина, которая дает 0.1963 для 7, но моя 64-битная машина дает NaN. Интересно, что на 64-битной машине R ^ 2, которые не являются NaN, очень близки к 0,5. Имеет смысл, когда я думаю об этом, но сначала это удивляет меня.
Аарон оставил переполнение стека

1
Вы изучаете ошибку округления двойной точности. Посмотрите на коэффициенты; например, apply(as.matrix(2:17), 1, function(n){example(n)$coefficients[-1]}). (Мои результаты на Win 7 x64 Xeon варьируются от -8e-17 до + 3e-16; около половины - истинные нули.) Кстати, источник на Фортране не поможет: это просто оболочка для dqrdc; это код, который вы хотите посмотреть.
whuber

1
R2

Ответы:


6

Как говорит Бен Болкер, ответ на этот вопрос можно найти в коде для 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

Чтобы ответить на вопрос вопросом: что мы из этого получаем? :)

mssrssR2mssrss0/0NaN2^(1:k)


Обновление 1: Вот хорошая ветка из R-help, в которой рассматриваются некоторые причины, по которым предупреждения о недостаточном объеме не рассматриваются в R.

Кроме того, в этом разделе «Вопросы и ответы» есть ряд интересных постов и полезных ссылок, касающихся недостаточного значения, арифметики высокой точности и т. Д.


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

1
mms и rss оба являются результатами z, который является именем объекта lm внутри summary.lm. Таким образом, ответ, вероятно, требует объяснения QR-декомпозиции, его использования в линейной регрессии и, в частности, некоторых деталей QR-декомпозиции, как показано в коде, лежащем в основе R, чтобы объяснить, почему QR-декомпозиция заканчивается с приближениями 0, а не 0 самого ,
russellpierce

mssrssR2R2

R2

0

R2R2=1SSerrSStot


1
Можете ли вы привести практическую ситуацию, когда это поведение будет иметь значение?
Бен Болкер

3
@ Брэндон - Итератор поместил смайлик туда, и ты все еще получил свист!
Карл Виттофт

2
@eznme Несмотря на то, что ошибка является хорошей, довольно трудно отследить все виды мест, где возникают проблемы с плавающей запятой, особенно в мире арифметики IEEE-754. Урок здесь заключается в том, что даже вычисления с использованием R и хлеба с маслом должны выполняться деликатно.
Итератор

2
Эти соображения особенно важны, потому что в своих работах Джон Чэмберс (один из создателей S и, следовательно, «дедушка» R) настоятельно подчеркивает использование R для надежных вычислений. Например, см. Chambers, Программное обеспечение для анализа данных: программирование на R (Springer Verlag 2008): «Вычисления и программное обеспечение для анализа данных должны быть заслуживающими доверия: они должны делать то, что заявляют, и должны это делать». [На стр. 3.]
whuber

2
Проблема в том, что, к лучшему или к худшему, R-ядро устойчиво (как они это видят) к тому, чтобы усыпить код множеством проверок, которые пересекают все угловые случаи и возможные странные ошибки пользователя - они боятся (я думаю), что это (а) потребует огромного количества времени, (б) сделает базу кода намного больше и труднее для чтения (потому что буквально тысячи таких особых случаев), и (в) замедлит выполнение, заставляя такие проверки все время даже в ситуациях, когда вычисления повторяются много, много раз.
Бен Болкер
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.