Jawaban yang agak anti-iklim untuk " Apakah ada yang tahu mengapa ini? " Adalah bahwa tidak ada yang cukup peduli untuk menerapkan rutinitas regresi ridge non-negatif. Salah satu alasan utama adalah bahwa orang-orang sudah mulai menerapkan
rutin jaring elastis non-negatif (misalnya di sini dan di sini ). Jaring elastis mencakup regresi punggungan sebagai kasus khusus (satu dasarnya mengatur bagian LASSO memiliki bobot nol). Karya-karya ini relatif baru sehingga belum dimasukkan dalam scikit-learn atau paket penggunaan umum serupa. Anda mungkin ingin menanyakan kode ini kepada pembuat makalah ini.
EDIT:
Seperti @amoeba dan saya bahas di komentar implementasi sebenarnya ini relatif sederhana. Katakanlah seseorang memiliki masalah regresi berikut untuk:
y= 2 x1- x2+ ϵ ,ϵ ∼ N( 0 , 0,22)
di mana dan x 2 keduanya normals standar seperti: x p ∼ N ( 0 ,x1x2 . Perhatikan saya menggunakan variabel prediktor standar sehingga saya tidak harus menormalisasi setelahnya. Untuk kesederhanaan saya juga tidak menyertakan intersep. Kita dapat segera menyelesaikan masalah regresi ini dengan menggunakan regresi linier standar. Jadi di R itu harus seperti ini:xhal∼ N( 0 , 1 )
rm(list = ls());
library(MASS);
set.seed(123);
N = 1e6;
x1 = rnorm(N)
x2 = rnorm(N)
y = 2 * x1 - 1 * x2 + rnorm(N,sd = 0.2)
simpleLR = lm(y ~ -1 + x1 + x2 )
matrixX = model.matrix(simpleLR); # This is close to standardised
vectorY = y
all.equal(coef(simpleLR), qr.solve(matrixX, vectorY), tolerance = 1e-7) # TRUE
Perhatikan baris terakhir. Hampir semua rutinitas regresi linier menggunakan dekomposisi QR untuk memperkirakan . Kami ingin menggunakan hal yang sama untuk masalah regresi ridge kami. Pada titik ini baca posting ini oleh @whuber; kami akan menerapkan prosedur ini dengan tepat . Singkatnya, kita akan menambah matriks desain asli X kitaβX dengan matriks diagonal dan vektor respons kamiydenganpnol. Dengan cara itu kita akan dapat kembali mengungkapkan masalah regresi ridge asli(XTX+λI) - 1 XTysebagai ( ˉ X T ˉ X ) - 1 ˉ X T ˉ y mana ¯λ--√sayahalyhal( XTX+ λ I)- 1XTy( X¯TX¯)- 1X¯Ty¯¯melambangkan versi augmented. Lihat slide 18-19 dari catatan ini juga untuk kelengkapannya, saya menemukannya cukup mudah. Jadi dalam R kami ingin beberapa hal berikut:
myLambda = 100;
simpleRR = lm.ridge(y ~ -1 + x1 + x2, lambda = myLambda)
newVecY = c(vectorY, rep(0, 2))
newMatX = rbind(matrixX, sqrt(myLambda) * diag(2))
all.equal(coef(simpleRR), qr.solve(newMatX, newVecY), tolerance = 1e-7) # TRUE
dan itu berhasil. OK, jadi kami mendapat bagian regresi ridge. Kita dapat menyelesaikannya dengan cara lain, kita dapat memformulasikannya sebagai masalah optimisasi di mana jumlah sisa kuadrat adalah fungsi biaya dan kemudian mengoptimalkannya, yaitu. minβ| | y¯- X¯β| |22 . Cukup yakin kita bisa melakukan itu:
myRSS <- function(X,y,b){ return( sum( (y - X%*%b)^2 ) ) }
bfgsOptim = optim(myRSS, par = c(1,1), X = newMatX, y= newVecY,
method = 'L-BFGS-B')
all.equal(coef(simpleRR), bfgsOptim$par, check.attributes = FALSE,
tolerance = 1e-7) # TRUE
yang seperti yang diharapkan lagi berfungsi. Jadi sekarang kita hanya ingin: mana β ≥minβ| | y¯- X¯β| |22β≥ 0
bfgsOptimConst = optim(myRSS, par = c(1,1), X=newMatX, y= newVecY,
method = 'L-BFGS-B', lower = c(0,0))
all(bfgsOptimConst$par >=0) # TRUE
(bfgsOptimConst$par) # 2.000504 0.000000
yang menunjukkan bahwa tugas regresi ridge non-negatif yang asli dapat diselesaikan dengan merumuskan kembali sebagai masalah optimisasi terbatas yang sederhana. Beberapa peringatan:
- Saya menggunakan (secara praktis) variabel prediktor yang dinormalisasi. Anda harus memperhitungkan normalisasi sendiri.
- Hal yang sama berlaku untuk non normalisasi intersep.
- Saya menggunakan
optim
's L-BFGS-B argumen. Ini adalah pemecah vanilla R paling yang menerima batas. Saya yakin Anda akan menemukan lusinan pemecah yang lebih baik.
- Secara umum kendala linear kuadrat-terkecil masalah diajukan sebagai tugas optimasi kuadrat . Ini adalah kerja keras untuk posting ini tetapi perlu diingat bahwa Anda bisa mendapatkan kecepatan yang lebih baik jika diperlukan.
- Seperti disebutkan dalam komentar, Anda dapat melewati regresi ridge sebagai bagian augmented-linear-regression dan secara langsung menyandikan fungsi biaya ridge sebagai masalah optimisasi. Ini akan menjadi jauh lebih sederhana dan posting ini jauh lebih kecil. Demi argumen saya menambahkan solusi kedua ini juga.
- Saya tidak sepenuhnya berbicara dalam Python tetapi pada dasarnya Anda dapat meniru pekerjaan ini dengan menggunakan linalg.solve NumPy dan fungsi optimalisasi SciPy .
- λ
Kode untuk poin 5:
myRidgeRSS <- function(X,y,b, lambda){
return( sum( (y - X%*%b)^2 ) + lambda * sum(b^2) )
}
bfgsOptimConst2 = optim(myRidgeRSS, par = c(1,1), X = matrixX, y = vectorY,
method = 'L-BFGS-B', lower = c(0,0), lambda = myLambda)
all(bfgsOptimConst2$par >0) # TRUE
(bfgsOptimConst2$par) # 2.000504 0.000000