เหตุใดจึงมีค่า 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

R2จะยิ่งใหญ่กว่าเมื่อค่าที่coef(example(n))["X"]ใกล้กว่า 0 แต่ ...

  1. ทำไมถึงมีค่าเลย? R2
  2. อะไรคือสิ่งที่กำหนดเป็นพิเศษ?
  3. ทำไมความก้าวหน้าของNaNผลลัพธ์ดูเหมือนเป็นระเบียบ?
  4. ทำไมการละเมิดของความก้าวหน้านั้น
  5. สิ่งนี้คือพฤติกรรมที่ 'คาดหวัง'

หมายเหตุ: 7 ของ R ^ 2 ควรเป็น 0.4542 เพื่อดูสิ่งที่สร้างสรรค์กว่าดูคำตอบของฉัน :-)

1
เพื่อความเป็นธรรมผู้ใช้ควรจะรู้อะไรบางอย่างเกี่ยวกับวิธีการทางสถิติก่อนใช้เครื่องมือ เนื่องจากค่อนข้างชัดเจนว่า 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 ^ 2s ที่ไม่ใช่ NaN นั้นทั้งหมดอยู่ใกล้กับ 0.5 มาก ทำให้รู้สึกเมื่อฉันคิดเกี่ยวกับมัน แต่มันทำให้ฉันประหลาดใจในตอนแรก
Aaron ออกจาก Stack Overflow

1
คุณกำลังศึกษาข้อผิดพลาดในการปัดเศษความแม่นยำสองเท่า ลองดูที่ค่าสัมประสิทธิ์; เช่นapply(as.matrix(2:17), 1, function(n){example(n)$coefficients[-1]}). (ผลลัพธ์ของฉันบน Win 7 x64 Xeon อยู่ในช่วง -8e-17 ถึง + 3e-16; ประมาณครึ่งหนึ่งเป็นศูนย์จริง) BTW แหล่ง Fortran ไม่มีความช่วยเหลือ: มันเป็นเพียงเสื้อคลุมสำหรับ dqrdc; นั่นคือรหัสที่คุณต้องการดู
whuber

1
(ต่อ) แต่ในฐานะผู้ใช้ตัวเลือก CV เป็นเว็บไซต์ที่ดีกว่าด้วยเหตุผลง่ายๆที่การวิเคราะห์ทางสถิติอย่างขยันขันแข็งเป็นความรับผิดชอบของผู้ใช้ไม่ใช่นักพัฒนา หากผู้ใช้เห็นข้อผิดพลาดสัมพันธ์กับขนาดของ RSS พวกเขาควรทำการโพสต์ของตนเองก่อนที่จะรายงานเพิ่มเติม การเขียนโปรแกรมที่ชาญฉลาดฉันต้องการทราบวิธีหลีกเลี่ยงปัญหาเชิงตัวเลขเหล่านี้ให้มากที่สุด แต่ฉันคิดว่าพวกเขาไม่สามารถหลบหนีได้และนั่นเป็นสิ่งสำคัญที่จะต้องมีผู้ใช้ที่ขยันและให้ความรู้แก่ผู้อื่น R2
Iterator

คำตอบ:


6

ขณะที่เบน 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)
    }

ขอให้สังเกตว่า ans $ r.squared คือ ...0.4998923

หากต้องการตอบคำถามด้วยคำถาม: เราทำอะไรจากสิ่งนี้ :)

ฉันเชื่อว่าคำตอบนั้นขึ้นอยู่กับวิธีที่ R จัดการกับจำนวนจุดลอยตัว ฉันคิดว่าmssและrssเป็นผลรวมของข้อผิดพลาดการปัดเศษที่เล็กมาก (กำลังสอง) ดังนั้นเหตุผลคือประมาณ 0.5 สำหรับความคืบหน้าฉันสงสัยว่านี้จะทำอย่างไรกับจำนวนของค่าว่าจะใช้เวลาสำหรับการประมาณ +/- เพื่อยกเลิกการออกเป็น 0 (ทั้งและเป็นมีแนวโน้มว่าแหล่งที่มาของเหล่านี้ค่า) ฉันไม่รู้ว่าทำไมค่าต่างไปจากความก้าวหน้าR2mssrss0/0NaN2^(1:k)


อัปเดต 1: ต่อไปนี้เป็นเธรดที่ดีจากการช่วยเหลือ R เพื่อจัดการกับสาเหตุบางประการที่คำเตือนอันเดอร์โฟล์ไม่ได้รับการแก้ไขใน R

นอกจากนี้คำถามและคำตอบ SO นี้มีจำนวนโพสต์ที่น่าสนใจและลิงค์ที่มีประโยชน์เกี่ยวกับอันเดอร์โฟล์เลขคณิตความแม่นยำสูง ฯลฯ


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

@drknexus ฉันไม่เห็นด้วย ถอดรหัส QR เป็นหนึ่งในอัลกอริทึมเชิงตัวเลขมากมาย หากปัญหาพื้นฐานคือความแม่นยำเชิงตัวเลขสิ่งนี้จะครอบตัดใน QR การคูณเมทริกซ์ตัวแก้แบบไม่เชิงเส้นและที่อื่น ๆ มากมาย ลำดับสำคัญคือง่าย: ค่าสัมประสิทธิ์จะปิดเล็กน้อย (ควรเป็น (0,1)); สิ่งนี้ไม่ได้ไร้เหตุผล แต่สร้างmssและrss"เสียง" มันเป็นหลักการของ GIGO ที่รับรองว่านั้นแม่นยำ แต่ไม่ถูกต้อง ฉันต้องการแทรก "เครื่องตรวจจับขยะ" ก่อนที่จะคำนวณมากกว่าที่จะแก้ไข QR algo เพราะฉันสงสัยว่าความถูกต้องจะดีขึ้น R 2R2R2
Iterator

สำหรับฉันดูเหมือนว่าเครื่องตรวจจับขยะควรอยู่ที่รหัส QR หรือก่อนหน้านั้น การตรวจสติอย่างง่ายเกี่ยวกับความแปรปรวนของ Y และเตือนว่า Y ที่ไม่มีความแปรปรวนจะเป็นเรื่องปกติ (ฉันอาจเขียน wrapper lm สำหรับเพื่อนของฉันที่ทำสิ่งนี้) สำหรับผมแล้วดูเหมือนว่าในเวลาที่คุณคำนวณมีใครอยู่ไกลเกินรูกระต่ายที่คำนวณได้เพื่อที่จะรู้ว่ามีคนดูขยะหรือไม่ R2
russellpierce

0

R 2 = 1 - SS e r rR2หมายถึง ( http://en.wikipedia.org/wiki/R_squared ) ดังนั้นหากผลรวมของกำลังสองรวมเป็น 0 จะไม่ได้กำหนด ในความคิดของฉัน R ควรแสดงข้อความข้อผิดพลาดR2=1SSerrSStot


1
คุณสามารถให้สถานการณ์จริงที่พฤติกรรมนี้มีความสำคัญได้หรือไม่?
Ben Bolker

3
@Brandon - Iterator ใส่รอยยิ้มในนั้นและคุณยังคงได้รับหวือ!
Carl Witthoft

2
@eznme ในขณะที่ข้อผิดพลาดเป็นสิ่งที่ดีมันค่อนข้างยากที่จะจับทุกสถานที่ที่เกิดปัญหาจุดลอยตัวโดยเฉพาะอย่างยิ่งในโลกของเลขคณิต IEEE-754 บทเรียนที่นี่คือแม้แต่การคำนวณขนมปังและเนยด้วย R ก็ควรได้รับการจัดการอย่างประณีต
Iterator

2
ข้อพิจารณาเหล่านี้มีความสำคัญอย่างยิ่งเพราะในงานเขียนของเขา John Chambers (หนึ่งในผู้สร้างของ S และดังนั้น "ปู่" ของ R) จึงเน้นการใช้ R สำหรับการคำนวณที่เชื่อถือได้ เช่นดู Chambers ซอฟต์แวร์สำหรับการวิเคราะห์ข้อมูล: การเขียนโปรแกรมด้วย R (Springer Verlag 2008): "การคำนวณและซอฟต์แวร์สำหรับการวิเคราะห์ข้อมูลควรเชื่อถือได้: พวกเขาควรทำในสิ่งที่พวกเขาอ้างและเห็นว่าเป็นเช่นนั้น" [ที่หน้า 3. ]
whuber

2
ปัญหาคือว่าดีกว่าหรือแย่กว่า R-core สามารถต้านทาน (ตามที่พวกเขาเห็น) ประดับประดาด้วยรหัสตรวจสอบจำนวนมากที่ดักกรณีมุมทั้งหมดและข้อผิดพลาดของผู้ใช้ที่เป็นไปได้ - พวกเขากลัว (ฉันคิดว่า) (a) ใช้เวลาจำนวนมาก (b) ทำให้โค้ดมีขนาดใหญ่และยากต่อการอ่านมากขึ้น (เนื่องจากมีกรณีพิเศษนับพันรายการ) และ (c) ชะลอการดำเนินการโดยบังคับให้เช็คดังกล่าวตลอดเวลา แม้ในสถานการณ์ที่การคำนวณซ้ำหลายครั้งหลายครั้ง
Ben Bolker
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.