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

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

  1. Чому взагалі існує значення ? R2
  2. Що (конкретно) це визначає?
  3. Чому, здавалося б, впорядковане прогресування NaNрезультатів?
  4. Чому порушення цієї прогресії?
  5. Що з цього - "очікувана" поведінка?

Примітка: R ^ 2 7 має бути 0,4542, щоб побачити щось більш конструктивне, побачити мою відповідь. :-)

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

@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; приблизно половина - справжні нулі.) До речі, джерело Fortran не допомагає: це просто обгортка для dqrdc; це код, який ви хочете подивитися.
качан

1
(Продовження) Але, як користувач, вибір резюме є кращим сайтом з тієї простої причини, що ретельний статистичний аналіз - це відповідальність користувача, а не розробника. Якщо користувач бачить помилковий щодо величини RSS, то він повинен зробити свою власну післяобробку, перш ніж подавати звіт. Програмуючи, я хотів би знати, як максимально уникнути цих числових питань, але я думаю, що їх не можна уникнути, і саме тут важливо старанного користувача та навчання інших. 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)
    }

Зверніть увагу, що ans $ r.squared становить ...0.4998923

Щоб відповісти на запитання запитанням: що ми з цього беремо? :)

mssrssR2mssrss0/0NaN2^(1:k)


Оновлення 1: Ось приємна нитка з R-довідки, яка стосується деяких причин того, що попередження, що переповнюються, не розглядаються в Р.

Окрім цього, у цьому питанні та питанні є низка цікавих постів та корисних посилань щодо переливу, арифметики вищої точності тощо.


8

Мені цікаво твоя мотивація на запитання. Я не можу придумати практичну причину, коли ця поведінка має значення; інтелектуальна цікавість - це альтернативна (і ІМО набагато розумніша) причина. Я думаю, що вам не потрібно розуміти 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
@Brandon - Ітератор поклав смайлик туди, і ти все ще шумив!
Карл Віттофт

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

2
Ці міркування особливо важливі, оскільки у своїх працях Джон Чемберс (один із авторів проекту S і, отже, "дід" R) сильно наголошує на використанні R для надійних обчислень. Наприклад, див. Чемберс, Програмне забезпечення для аналізу даних: Програмування з R (Springer Verlag 2008): "Обчислення та програмне забезпечення для аналізу даних повинні бути надійними: вони повинні робити те, що вони вимагають, і бачити, що вони роблять". [На с. 3.]
блукань

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