Lưu ý : Tôi đã đăng phiên bản mở rộng của câu trả lời này trên trang web của mình .
Bạn có vui lòng xem xét việc đăng một câu trả lời tương tự với công cụ R thực tế được đưa ra không?
Chắc chắn rồi! Xuống hố thỏ chúng tôi đi.
Lớp đầu tiên là lm
, giao diện tiếp xúc với lập trình viên R. Bạn có thể xem nguồn cho việc này bằng cách chỉ cần gõ lm
vào bảng điều khiển R. Phần lớn của nó (giống như phần lớn mã phần lớn mức sản xuất) đang bận kiểm tra các đầu vào, thiết lập các thuộc tính đối tượng và ném lỗi; nhưng dòng này dính ra
lm.fit(x, y, offset = offset, singular.ok = singular.ok,
...)
lm.fit
là một hàm R khác, bạn có thể tự gọi nó. Mặc dù lm
hoạt động thuận tiện với các công thức và khung dữ liệu, lm.fit
muốn có ma trận, do đó, một mức độ trừu tượng được loại bỏ. Kiểm tra nguồn cho lm.fit
, công việc bận rộn hơn và dòng thực sự thú vị sau đây
z <- .Call(C_Cdqrls, x, y, tol, FALSE)
Bây giờ chúng tôi đang nhận được ở đâu đó. .Call
là cách gọi của R vào mã C. Có một hàm C, C_Cdqrls trong nguồn R ở đâu đó và chúng ta cần tìm nó. Ở đây nó là .
Nhìn vào chức năng C, một lần nữa, chúng tôi thấy chủ yếu là kiểm tra giới hạn, dọn dẹp lỗi và công việc bận rộn. Nhưng dòng này thì khác
F77_CALL(dqrls)(REAL(qr), &n, &p, REAL(y), &ny, &rtol,
REAL(coefficients), REAL(residuals), REAL(effects),
&rank, INTEGER(pivot), REAL(qraux), work);
Vì vậy, bây giờ chúng tôi đang sử dụng ngôn ngữ thứ ba của mình, R đã gọi C đang gọi vào fortran. Đây là mã fortran .
Bình luận đầu tiên nói lên tất cả
c dqrfit is a subroutine to compute least squares solutions
c to the system
c
c (1) x * b = y
(thật thú vị, có vẻ như tên của thói quen này đã được thay đổi tại một số điểm, nhưng ai đó đã quên cập nhật nhận xét). Vì vậy, cuối cùng chúng ta đã ở điểm chúng ta có thể thực hiện một số đại số tuyến tính và thực sự giải được hệ phương trình. Đây là thứ mà fortran thực sự giỏi, điều này giải thích tại sao chúng tôi đã đi qua rất nhiều lớp để đến đây.
Nhận xét cũng giải thích những gì mã sẽ làm
c on return
c
c x contains the output array from dqrdc2.
c namely the qr decomposition of x stored in
c compact form.
Vì vậy fortran sẽ giải quyết hệ thống bằng cách tìm phân tách QR
Điều đầu tiên xảy ra, và cho đến nay, điều quan trọng nhất là
call dqrdc2(x,n,n,p,tol,k,qraux,jpvt,work)
Điều này gọi hàm fortran dqrdc2
trên ma trận đầu vào của chúng tôi x
. Đây là gì?
c dqrfit uses the linpack routines dqrdc and dqrsl.
Vì vậy, cuối cùng chúng tôi đã làm cho nó để linpack . Linpack là một thư viện đại số tuyến tính fortran đã có từ những năm 70. Hầu hết các đại số tuyến tính nghiêm trọng cuối cùng tìm thấy đường đến linpack. Trong trường hợp của chúng tôi, chúng tôi đang sử dụng chức năng dqrdc2
c dqrdc2 uses householder transformations to compute the qr
c factorization of an n by p matrix x.
Đây là nơi công việc thực tế được thực hiện. Sẽ mất cả ngày để tôi tìm ra mã này đang làm gì, nó ở mức độ thấp như chúng đến. Nhưng nói chung, chúng ta có một ma trận và chúng ta muốn đưa nó vào một sản phẩm X = Q R trong đó Q là một ma trận trực giao và R là một ma trận tam giác trên. Đây là một điều thông minh để làm, bởi vì một khi bạn có Q và R, bạn có thể giải các phương trình tuyến tính cho hồi quyXX=QRQRQR
XtXβ=XtY
rất dễ dàng Thật
XtX=RtQtQR=RtR
vì vậy toàn bộ hệ thống trở thành
RtRβ=RtQty
nhưng là tam giác trên và có cùng thứ hạng với X t X , miễn là vấn đề của chúng ta được đặt ra, đó là thứ hạng đầy đủ, và chúng ta cũng có thể giải quyết hệ thống rút gọnRXtX
Rβ=Qty
Nhưng đây là điều tuyệt vời. là thượng tam giác, vì vậy phương trình tuyến tính trước đây chỉ là , vì vậy giải quyết cho β n là tầm thường. Sau đó bạn có thể đi lên các hàng, từng người một, và thay thế trong β s bạn đã biết, mỗi lần nhận được một biến đơn giản tuyến tính phương trình để giải quyết. Vì vậy, một khi bạn có Q và R , toàn bộ điều này sẽ sụp đổ với cái được gọi là sự thay thế ngược , rất dễ dàng. Bạn có thể đọc về điều này chi tiết hơn ở đây , nơi một ví dụ nhỏ rõ ràng được thực hiện đầy đủ.Rconstant * beta_n = constant
βnβQR