Catatan : Saya telah memposting versi yang diperluas dari jawaban ini di situs web saya .
Apakah Anda akan mempertimbangkan untuk mengirim jawaban yang mirip dengan mesin R yang sebenarnya?
Yakin! Kita pergi ke lubang kelinci.
Lapisan pertama adalah lm
, antarmuka terkena programmer R. Anda dapat melihat sumbernya hanya dengan mengetik lm
di konsol R. Mayoritas (seperti sebagian besar kode tingkat produksi) sibuk memeriksa input, mengatur atribut objek, dan melempar kesalahan; tapi garis ini menonjol
lm.fit(x, y, offset = offset, singular.ok = singular.ok,
...)
lm.fit
adalah fungsi R lain, Anda bisa menyebutnya sendiri. Sementara dengan lm
mudah bekerja dengan formula dan bingkai data, membutuhkan lm.fit
matriks, jadi itu satu tingkat abstraksi dihapus. Memeriksa sumber untuk lm.fit
, lebih banyak pekerjaan, dan baris yang sangat menarik berikut
z <- .Call(C_Cdqrls, x, y, tol, FALSE)
Sekarang kita menuju suatu tempat. .Call
adalah cara R memanggil ke kode C. Ada fungsi C, C_Cdqrls di sumber R di suatu tempat, dan kita perlu menemukannya. Ini dia .
Melihat fungsi C, sekali lagi, kami menemukan sebagian besar batas memeriksa, pembersihan kesalahan, dan pekerjaan yang sibuk. Tetapi garis ini berbeda
F77_CALL(dqrls)(REAL(qr), &n, &p, REAL(y), &ny, &rtol,
REAL(coefficients), REAL(residuals), REAL(effects),
&rank, INTEGER(pivot), REAL(qraux), work);
Jadi sekarang kita menggunakan bahasa ketiga kita, R telah memanggil C yang memanggil fortran. Ini kode fortran .
Komentar pertama menceritakan semuanya
c dqrfit is a subroutine to compute least squares solutions
c to the system
c
c (1) x * b = y
(Menariknya, sepertinya nama rutin ini diubah di beberapa titik, tetapi seseorang lupa memperbarui komentar). Jadi kita akhirnya pada titik di mana kita dapat melakukan beberapa aljabar linier, dan benar-benar menyelesaikan sistem persamaan. Ini adalah hal yang benar-benar bagus untuk fortran, yang menjelaskan mengapa kami melewati begitu banyak lapisan untuk sampai ke sini.
Komentar tersebut juga menjelaskan apa yang akan dilakukan kode
c on return
c
c x contains the output array from dqrdc2.
c namely the qr decomposition of x stored in
c compact form.
Jadi fortran akan memecahkan sistem dengan mencari dekomposisi.Q R
Hal pertama yang terjadi, dan yang paling penting, adalah
call dqrdc2(x,n,n,p,tol,k,qraux,jpvt,work)
Ini memanggil fungsi fortran dqrdc2
pada matriks input kami x
. Apa ini?
c dqrfit uses the linpack routines dqrdc and dqrsl.
Jadi kami akhirnya berhasil linpack . Linpack adalah perpustakaan aljabar linear fortran yang telah ada sejak tahun 70-an. Aljabar linear yang paling serius akhirnya menemukan cara untuk linpack. Dalam kasus kami, kami menggunakan fungsi dqrdc2
c dqrdc2 uses householder transformations to compute the qr
c factorization of an n by p matrix x.
Di sinilah pekerjaan yang sebenarnya dilakukan. Butuh satu hari penuh yang baik bagi saya untuk mencari tahu apa yang dilakukan kode ini, levelnya serendah itu. Tetapi secara umum, kami memiliki matriks X dan kami ingin memfaktorkannya ke dalam produk mana Q adalah matriks ortogonal dan R adalah matriks segitiga atas. Ini adalah hal yang cerdas untuk dilakukan, karena begitu Anda memiliki Q dan R, Anda dapat menyelesaikan persamaan linear untuk regresiX= Q RQRQR
XtXβ= XtY
sangat mudah. Memang
XtX=RtQtQ R = RtR
jadi seluruh sistem menjadi
RtRβ= RtQty
tapi adalah segitiga atas dan memiliki peringkat yang sama seperti X t X , sehingga selama masalah kita baik yang ditimbulkan, itu adalah peringkat penuh, dan kami mungkin juga hanya memecahkan sistem berkurangRXtX
R β= Qty
Tapi ini hal yang luar biasa. adalah segitiga atas, jadi persamaan linear terakhir di sini adalah adil , jadi penyelesaian untuk β n adalah sepele. Anda kemudian bisa naik baris, satu per satu, dan gantikan di βRconstant * beta_n = constant
βnβ s yang sudah Anda ketahui, setiap kali mendapatkan persamaan linear satu variabel sederhana untuk dipecahkan. Jadi, setelah Anda memiliki dan R , semuanya runtuh menjadi apa yang disebut substitusi mundur , yang mudah. Anda dapat membaca tentang ini secara lebih rinci di sini , di mana contoh kecil eksplisit sepenuhnya dikerjakan.QR