การคำนวณพีชคณิตเชิงเส้นอย่างน้อยกำลังสองน้อยที่สุด


22

เพื่อเป็นการตอบคำถามเกี่ยวกับโมเดลเชิงเส้นผสมใน R และเพื่อเป็นการอ้างอิงสำหรับผู้สนใจรักการเริ่มต้น / ขั้นกลางทางสถิติฉันตัดสินใจที่จะโพสต์ในฐานะ "Q & A-style" อิสระขั้นตอนที่เกี่ยวข้องกับการคำนวณ "คู่มือ" ของ ค่าสัมประสิทธิ์และค่าทำนายของการถดถอยเชิงเส้นอย่างง่าย

ตัวอย่างคือชุดข้อมูล R ที่สร้างขึ้นmtcarsและจะถูกตั้งค่าเป็นไมล์ต่อแกลลอนที่ใช้โดยยานพาหนะที่ทำหน้าที่เป็นตัวแปรอิสระซึ่งควบคุมน้ำหนักของรถ (ตัวแปรต่อเนื่อง) และจำนวนกระบอกสูบเป็น ปัจจัยที่มีสามระดับ (4, 6 หรือ 8) โดยไม่มีการโต้ตอบ

แก้ไข: ถ้าคุณมีความสนใจในคำถามนี้แน่นอนคุณจะพบคำตอบที่มีรายละเอียดและความพึงพอใจในเรื่องนี้โพสต์โดยแมทธิว Drury นอก CV


เมื่อคุณพูดว่า "การคำนวณด้วยตนเอง" คุณจะค้นหาอะไร มันค่อนข้างตรงไปตรงมาที่จะแสดงชุดของขั้นตอนง่าย ๆ ที่จะได้รับการประมาณค่าพารามิเตอร์และอื่น ๆ (ผ่าน Gram-Schmidt orthogonalization ตัวอย่างหรือโดยผู้ประกอบการ SWEEP) แต่นั่นไม่ใช่วิธีที่ R ทำการคำนวณภายใน (และแพคเกจสถิติอื่น ๆ ส่วนใหญ่) ใช้การสลายตัว QR (กล่าวถึงในจำนวนโพสต์ในเว็บไซต์ - การค้นหาการสลายตัว QRจะเปิดขึ้นจำนวนโพสต์ไม่กี่ที่คุณอาจได้รับค่าโดยตรงจาก)
Glen_b -Reinstate Monica

ใช่. ฉันเชื่อว่านี่เป็นคำตอบของ MD โดยละเอียดฉันควรจะแก้ไขโพสต์ของฉันบางทีอาจจะเน้นไปที่วิธีการทางเรขาคณิตที่อยู่เบื้องหลังคำตอบของฉัน - พื้นที่คอลัมน์, เมทริกซ์การฉายภาพ ...
Antoni Parellada

อ้อ! @Matthew Drury คุณต้องการให้ฉันลบบรรทัดนั้นใน OP หรืออัปเดตลิงก์หรือไม่
Antoni Parellada

1
ไม่แน่ใจว่าคุณมีลิงค์นี้หรือไม่ แต่นี่มีความเกี่ยวข้องกันมากและฉันชอบคำตอบของ JM มาก stats.stackexchange.com/questions/1829/…
Haitao Du

คำตอบ:


51

หมายเหตุ : ผมได้โพสต์รุ่นขยายของคำตอบนี้บนเว็บไซต์ของฉัน

คุณช่วยกรุณาพิจารณาการโพสต์คำตอบที่คล้ายกันกับเครื่องยนต์ R จริงสัมผัส?

แน่นอน! เราลงไปที่โพรงกระต่าย

ชั้นแรกคือlmอินเตอร์เฟซที่สัมผัสกับโปรแกรมเมอร์ R คุณสามารถดูที่มาของสิ่งนี้ได้โดยเพียงพิมพ์lmที่คอนโซล R ส่วนใหญ่ของมัน (เช่นรหัสระดับการผลิตส่วนใหญ่) คือการตรวจสอบอินพุต, การตั้งค่าคุณสมบัติของวัตถุและการโยนข้อผิดพลาด; แต่บรรทัดนี้โผล่ออกมา

lm.fit(x, y, offset = offset, singular.ok = singular.ok, 
                ...)

lm.fitเป็นอีกฟังก์ชั่น R คุณสามารถเรียกมันด้วยตัวเอง ในขณะที่lmทำงานได้อย่างสะดวกกับสูตรและกรอบข้อมูลlm.fitต้องการเมทริกซ์ดังนั้นนั่นคือการลบระดับหนึ่ง ตรวจสอบแหล่งที่มาlm.fitยุ่งมากขึ้นและบรรทัดที่น่าสนใจจริง ๆ ดังต่อไปนี้

z <- .Call(C_Cdqrls, x, y, tol, FALSE)

ตอนนี้เรากำลังเดินทางอยู่ที่ไหนซักแห่ง .Callเป็นวิธีของ R ในการโทรเข้ารหัส C มีฟังก์ชั่น C คือ C_Cdqrls ในแหล่ง R ที่ใดที่หนึ่งและเราจำเป็นต้องค้นหามัน นี่มันเป็น

เมื่อมองที่ฟังก์ชั่น C อีกครั้งเราพบว่าการตรวจสอบขอบเขตส่วนใหญ่การล้างข้อผิดพลาดและงานยุ่ง แต่บรรทัดนี้แตกต่างกัน

F77_CALL(dqrls)(REAL(qr), &n, &p, REAL(y), &ny, &rtol,
        REAL(coefficients), REAL(residuals), REAL(effects),
        &rank, INTEGER(pivot), REAL(qraux), work);

ดังนั้นตอนนี้เราใช้ภาษาที่สามของเราแล้ว R ได้เรียก C ซึ่งเรียกว่า Fortran นี่คือรหัส Fortran

ความคิดเห็นแรกบอกทุกอย่าง

c     dqrfit is a subroutine to compute least squares solutions
c     to the system
c
c     (1)               x * b = y

(น่าสนใจดูเหมือนว่าชื่อของรูทีนนี้จะเปลี่ยนไปในบางจุด แต่มีคนลืมที่จะอัปเดตความคิดเห็น) ในที่สุดเราก็มาถึงจุดที่เราสามารถทำพีชคณิตเชิงเส้นและแก้ระบบสมการได้ นี่คือสิ่งที่ Fortran ทำได้ดีมากซึ่งอธิบายว่าทำไมเราผ่านหลายชั้นมาที่นี่

ความคิดเห็นยังอธิบายสิ่งที่รหัสกำลังจะทำ

c     on return
c
c        x      contains the output array from dqrdc2.
c               namely the qr decomposition of x stored in
c               compact form.

ดังนั้นฟอร์แทรนจะแก้ปัญหาระบบโดยค้นหาการย่อยสลายQR

สิ่งแรกที่เกิดขึ้นและที่สำคัญที่สุดคือ

call dqrdc2(x,n,n,p,tol,k,qraux,jpvt,work)

นี้เรียกฟังก์ชัน Fortran บนเมทริกซ์ป้อนข้อมูลของเราdqrdc2 xอะไรนะ

 c     dqrfit uses the linpack routines dqrdc and dqrsl.

ดังนั้นเราจึงได้ทำในที่สุดมันLinpack Linpack เป็นห้องสมุดพีชคณิตเชิงเส้นของฟอร์แทรนที่มีมาตั้งแต่ยุค 70 ในที่สุดพีชคณิตเชิงเส้นที่ร้ายแรงที่สุดหาทางไปสู่ ​​linpack ในกรณีของเราเราใช้ฟังก์ชันdqrdc2

c     dqrdc2 uses householder transformations to compute the qr
c     factorization of an n by p matrix x.

นี่คือที่ทำงานจริงจะทำ มันจะใช้เวลาทั้งวันที่ดีสำหรับฉันที่จะคิดออกว่ารหัสนี้ทำอะไรอยู่ในระดับต่ำเท่าที่พวกเขามา แต่โดยทั่วไปเรามีเมทริกซ์และเราต้องการแยกมันเป็นผลิตภัณฑ์X = Q Rโดยที่Qคือเมทริกซ์มุมฉากและRคือเมทริกซ์สามเหลี่ยมด้านบน นี่เป็นสิ่งที่ต้องทำอย่างชาญฉลาดเพราะเมื่อคุณมีQและRคุณสามารถแก้สมการเชิงเส้นสำหรับการถดถอยXX=QRQRQR

XtXβ=XtY

ง่ายมาก จริง

XtX=RtQtQR=RtR

ดังนั้นระบบทั้งหมดจึงกลายเป็น

RtRβ=RtQty

แต่เป็นรูปสามเหลี่ยมบนและมีอันดับเดียวกับX t Xดังนั้นตราบใดที่ปัญหาของเราถูกวางอย่างดีมันเป็นอันดับเต็มและเราก็อาจแก้ระบบที่ลดลงได้RXtX

Rβ=Qty

แต่นี่คือสิ่งที่น่ากลัว คือสามเหลี่ยมด้านบนดังนั้นสมการเชิงเส้นสุดท้ายตรงนี้จึงเป็นแค่การแก้สำหรับβ nนั้นเป็นเรื่องไม่สำคัญ จากนั้นคุณสามารถขึ้นไปแถวที่หนึ่งโดยหนึ่งและตัวแทนในβ s คุณรู้อยู่แล้วว่าทุกครั้งที่ได้รับตัวแปรหนึ่งง่ายสมการที่จะแก้ปัญหา ดังนั้นเมื่อคุณมีQและRแล้วสิ่งทั้งปวงก็จะยุบตัวไปสู่สิ่งที่เรียกว่าการทดแทนแบบย้อนหลังซึ่งเป็นเรื่องง่าย คุณสามารถอ่านรายละเอียดเพิ่มเติมได้ที่นี่ซึ่งเป็นตัวอย่างเล็ก ๆ ที่ชัดเจนRconstant * beta_n = constantβnβQR


4
นี่เป็นบทความเรียงความสั้น ๆ ทางคณิตศาสตร์ / การเข้ารหัสที่สนุกที่สุดที่คุณจินตนาการได้ ฉันรู้ว่าไม่มีอะไรเกี่ยวกับการเขียนโค้ด แต่ "ทัวร์" ของคุณผ่านความกล้าหาญของฟังก์ชั่น R ที่ดูเหมือนจะไม่มีอันตรายนั้นเป็นการเปิดหูเปิดตาอย่างแท้จริง การเขียนที่ยอดเยี่ยม! เนื่องจาก "กรุณา" ใช้กลอุบาย ... คุณช่วยกรุณาพิจารณาเรื่องนี้เป็นความท้าทายที่เกี่ยวข้องได้ไหม :-)
Antoni Parellada

6
+1 ฉันไม่เคยเห็นสิ่งนี้มาก่อนสรุปดีมาก เพียงเพิ่มข้อมูลเล็กน้อยในกรณีที่ @Antoni ไม่คุ้นเคยกับการเปลี่ยนเจ้าของบ้าน มันคือการแปลงเชิงเส้นที่ให้คุณเป็นศูนย์ส่วนหนึ่งของเมทริกซ์ R ที่คุณพยายามทำโดยไม่ทำให้ชิ้นส่วนที่คุณจัดการนั้นยุ่งเหยิงไป (ตราบเท่าที่คุณผ่านมันไปในลำดับที่ถูกต้อง) ทำให้มันเป็นอุดมคติ สำหรับการแปลงเมทริกซ์เป็นรูปสามเหลี่ยมบน (การหมุนของ Givens ทำหน้าที่คล้ายกันและอาจจะง่ายต่อการมองเห็น แต่จะช้ากว่าเล็กน้อย) ในขณะที่คุณสร้าง R คุณต้องสร้างโครงสร้าง Q
Glen_b

2
แมทธิว (+1) ผมแนะนำให้คุณเริ่มต้นหรือสิ้นสุดการโพสต์ของคุณด้วยการเชื่อมโยงไปยังรายละเอียดอื่น ๆ อีกมากมายที่คุณเขียนขึ้นmadrury.github.io/jekyll/update/2016/07/20/lm-in-R.html
อะมีบาพูดว่า Reinstate Monica

3
-1 สำหรับการทำให้ไก่ออกมาและไม่ลงไปที่รหัสเครื่อง
S. Kolassa - Reinstate Monica

3
(ขออภัยแค่ล้อเล่น ;-)
S. Kolassa - Reinstate Monica

8

การคำนวณทีละขั้นตอนจริงใน R นั้นได้อธิบายไว้อย่างสวยงามในคำตอบของ Matthew Drury ในหัวข้อเดียวกันนี้ ในคำตอบนี้ฉันต้องการเดินผ่านขั้นตอนการพิสูจน์ตัวเองว่าผลลัพธ์ใน R ด้วยตัวอย่างง่ายๆสามารถเข้าถึงได้หลังจากพีชคณิตเชิงเส้นของการฉายลงบนพื้นที่คอลัมน์และแนวคิดข้อผิดพลาดตั้งฉาก (จุดผลิตภัณฑ์) ซึ่งแสดงในโพสต์ที่แตกต่างกัน และอย่างที่อธิบายไว้โดยดร. แปลกในพีชคณิตเชิงเส้นและการประยุกต์ใช้และเข้าถึงได้อย่างง่ายดายที่นี่

เพื่อประมาณค่าสัมประสิทธิ์ในการถดถอยβ

mpg=intercept(cyl=4)+β1weight+D1intercept(cyl=6)+D2intercept(cyl=8)[]

D1D2X

attach(mtcars)    
x1 <- wt

    x2 <- cyl; x2[x2==4] <- 1; x2[!x2==1] <-0

    x3 <- cyl; x3[x3==6] <- 1; x3[!x3==1] <-0

    x4 <- cyl; x4[x4==8] <- 1; x4[!x4==1] <-0

    X <- cbind(x1, x2, x3, x4)
    colnames(X) <-c('wt','4cyl', '6cyl', '8cyl')

head(X)
        wt 4cyl 6cyl 8cyl
[1,] 2.620    0    1    0
[2,] 2.875    0    1    0
[3,] 2.320    1    0    0
[4,] 3.215    0    1    0
[5,] 3.440    0    0    1
[6,] 3.460    0    1    0

[]lm

βProjMatrix=(XTX)1XT[ProjMatrix][y]=[RegrCoefs](XTX)1XTy=β

X_tr_X_inv <- solve(t(X) %*% X)    
Proj_M <- X_tr_X_inv %*% t(X)
Proj_M %*% mpg

          [,1]
wt   -3.205613
4cyl 33.990794
6cyl 29.735212
8cyl 27.919934

coef(lm(mpg ~ wt + as.factor(cyl)-1))เหมือนกับ:

HatMatrix=X(XTX)1XT

HAT <- X %*% X_tr_X_inv %*% t(X)

y^X(XTX)1XTyy_hat <- HAT %*% mpg

cyl <- as.factor(cyl); OLS <- lm(mpg ~ wt + cyl); predict(OLS):

y_hat <- as.numeric(y_hat)
predicted <- as.numeric(predict(OLS))
all.equal(y_hat,predicted)
[1] TRUE

1
โดยทั่วไปในการคำนวณเชิงตัวเลขฉันเชื่อว่ามันเป็นการดีที่สุดที่จะแก้สมการเชิงเส้นแทนที่จะคำนวณเมทริกซ์ผกผัน ดังนั้นผมคิดว่าเป็นในทางปฏิบัติที่ถูกต้องมากกว่าbeta = solve(t(X) %*% X, t(X) %*% y) solve(t(X) %*% X) %*% t(X) %*% y
Matthew Drury

R ไม่ได้ทำเช่นนั้น - ใช้การย่อยสลาย QR หากคุณกำลังจะอธิบายถึงอัลกอริทึมที่ใช้บนคอมพิวเตอร์ฉันสงสัยว่าจะมีใครใช้อันที่คุณแสดงอยู่
Reinstate Monica - G. Simpson

ไม่ใช่หลังจากอัลกอริธึมแค่พยายามทำความเข้าใจพีชคณิตเชิงเส้นที่อยู่ข้างใต้
Antoni Parellada

@ AntonellParellada แม้ในกรณีนี้ฉันยังคงคิดในแง่ของสมการเชิงเส้นที่ให้ความกระจ่างมากขึ้นในหลาย ๆ สถานการณ์
Matthew Drury

1
ด้วยความสัมพันธ์รอบข้างของหัวข้อนี้กับวัตถุประสงค์ของเว็บไซต์ของเราในขณะที่เห็นคุณค่าในการอธิบายการใช้งานRสำหรับการคำนวณที่สำคัญฉันขอแนะนำให้คุณพิจารณาเปลี่ยนเป็นส่วนร่วมในบล็อกของเรา
whuber
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.