Menggunakan LASSO dari paket lars (atau glmnet) di R untuk pemilihan variabel

39

Maaf jika pertanyaan ini sedikit mendasar.

Saya mencari untuk menggunakan pemilihan variabel LASSO untuk model regresi linier berganda di R. Saya memiliki 15 prediktor, salah satunya adalah kategorikal (akankah itu menyebabkan masalah?). Setelah mengatur dan saya menggunakan perintah berikut:yxy

model = lars(x, y)
coef(model)

Masalah saya adalah ketika saya menggunakan coef(model). Ini mengembalikan matriks dengan 15 baris, dengan satu prediktor tambahan ditambahkan setiap kali. Namun tidak ada saran untuk model mana yang harus dipilih. Apakah saya melewatkan sesuatu? Apakah ada cara saya bisa mendapatkan paket lars hanya untuk mengembalikan satu model " terbaik "?

Ada posting lain yang menyarankan untuk menggunakan glmnettetapi ini tampaknya lebih rumit. Upaya adalah sebagai berikut, menggunakan dan . Apakah saya melewatkan sesuatu di sini ?: yxy

cv = cv.glmnet(x, y)
model = glmnet(x, y, type.gaussian="covariance", lambda=cv$lambda.min)
predict(model, type="coefficients")

Perintah terakhir mengembalikan daftar variabel saya, mayoritas dengan koefisien meskipun ada yang = 0. Apakah ini pilihan model " terbaik " yang benar yang dipilih oleh LASSO? Jika saya kemudian cocok dengan model linier dengan semua variabel saya yang memiliki koefisien, not=0saya mendapatkan estimasi koefisien yang sangat mirip, tetapi sedikit berbeda. Apakah ada alasan untuk perbedaan ini? Apakah dapat diterima untuk mereparasi model linier dengan variabel-variabel ini dipilih oleh LASSO dan menganggapnya sebagai model terakhir saya? Kalau tidak, saya tidak bisa melihat nilai p apa pun untuk signifikansi. Apakah saya melewatkan sesuatu?

Apakah

type.gaussian="covariance" 

memastikan bahwa yang glmnetmenggunakan regresi linier berganda?

Apakah normalisasi otomatis variabel mempengaruhi koefisien sama sekali? Apakah ada cara untuk memasukkan istilah interaksi dalam prosedur LASSO?

Saya ingin menggunakan prosedur ini lebih sebagai demonstrasi bagaimana LASSO dapat digunakan daripada untuk model apa pun yang benar-benar akan digunakan untuk inferensi / prediksi penting jika itu mengubah apa pun.

Terima kasih telah meluangkan waktu untuk membaca ini. Setiap komentar umum tentang LASSO / lars / glmnet juga akan sangat dihargai.

James
sumber
4
Sebagai komentar sampingan, jika Anda ingin menafsirkan hasil, pastikan untuk menunjukkan bahwa set variabel yang dipilih oleh laso stabil. Ini dapat dilakukan menggunakan simulasi Monte Carlo atau dengan bootstrap dataset Anda sendiri.
Frank Harrell

Jawaban:

28

Menggunakannya glmnetsangat mudah setelah Anda memahami hal itu berkat sketsa yang luar biasa di http://web.stanford.edu/~hastie/glmnet/glmnet_alpha.html (Anda juga dapat memeriksa halaman paket CRAN). Adapun lambda terbaik untuk glmnet, aturan praktis adalah menggunakan

cvfit <- glmnet::cv.glmnet(x, y)
coef(cvfit, s = "lambda.1se")

bukannya lambda.min.

Untuk melakukan hal yang sama, larsAnda harus melakukannya dengan tangan. Ini solusinya

cv <- lars::cv.lars(x, y, plot.it = FALSE, mode = "step")
idx <- which.max(cv$cv - cv$cv.error <= min(cv$cv))
coef(lars::lars(x, y))[idx,]

Ingatlah bahwa ini tidak persis sama, karena ini berhenti pada simpul laso (ketika variabel masuk) daripada pada titik mana pun.

Harap perhatikan bahwa glmnetini adalah paket yang disukai sekarang, ini dipelihara secara aktif, lebih dari itu lars, dan bahwa ada pertanyaan tentang glmnetvs larsdijawab sebelumnya (algoritma yang digunakan berbeda).

Adapun pertanyaan Anda tentang menggunakan laso untuk memilih variabel dan kemudian cocok dengan OLS, ini adalah perdebatan yang sedang berlangsung. Google untuk OLS memposting Lasso dan ada beberapa makalah yang membahas topik tersebut. Bahkan penulis Elemen Pembelajaran Statistik mengakui itu mungkin.

Sunting : Ini adalah kode untuk mereproduksi dengan lebih akurat apa yang glmnetada dilars

  cv <- lars::cv.lars(x, y, plot.it = FALSE)
  ideal_l1_ratio <- cv$index[which.max(cv$cv - cv$cv.error <= min(cv$cv))]
  obj <- lars::lars(x, y)
  scaled_coefs <- scale(obj$beta, FALSE, 1 / obj$normx)
  l1 <- apply(X = scaled_coefs, MARGIN = 1, FUN = function(x) sum(abs(x)))
  coef(obj)[which.max(l1 / tail(l1, 1) > ideal_l1_ratio),]
Juancentro
sumber
+1 Jawaban bagus! Bisakah Anda atau orang lain menjelaskan mengapa lambda.1se adalah aturan praktis, bukan lambda.min?
Erosennin
Setelah 4 tahun menulis ini (dan tidak menggunakan laso untuk sementara waktu) ingatan saya hilang begitu saja. Maaf!
Juancentro
9

Saya kembali ke pertanyaan ini sejak beberapa waktu yang lalu karena saya pikir saya telah memecahkan solusi yang benar.

Berikut adalah replika menggunakan dataset mtcars:

library(glmnet)
`%ni%`<-Negate(`%in%')
data(mtcars)

x<-model.matrix(mpg~.,data=mtcars)
x=x[,-1]

glmnet1<-cv.glmnet(x=x,y=mtcars$mpg,type.measure='mse',nfolds=5,alpha=.5)

c<-coef(glmnet1,s='lambda.min',exact=TRUE)
inds<-which(c!=0)
variables<-row.names(c)[inds]
variables<-variables[variables %ni% '(Intercept)']

'variabel' memberi Anda daftar variabel yang memecahkan solusi terbaik.

Jason
sumber
1
Saya sedang mencari kode dan saya menemukan bahwa "pengujian" belum didefinisikan dan oleh karena itu kode: "final.list <-testing [-removed] #removing variabel" memberikan kesalahan: objek tidak ditemukan Jadi melihat ke kode I anggaplah bahwa alih-alih menggunakan "pengujian" itu harus digunakan "cp.list" sehingga kode tersebut akan menjadi: final.list <-cp.list [-removed] #removing variabel final.list <-c (final.list, duplikat) #adding pada mereka vars yang baik dihapus kemudian ditambahkan kemudian Biar saya tahu apakah ini benar Kind regards
3
`% ni%` <-Negate (`% ni%`); ## terlihat salah. Sementara `% ni%` <-Negate (`% in%`); ## terlihat benar. Saya pikir formatex stackexchange mengacaukannya ...
Chris
Bisakah Anda menguraikan bagaimana Anda memilih nfolds=5dan alpha=0.5parameter?
Colin
7

Mungkin perbandingan dengan penerusan maju regresi bertahap akan membantu (lihat tautan berikut ke situs oleh salah satu penulis http://www-stat.stanford.edu/~tibs/lasso/simple.html). Ini adalah pendekatan yang digunakan dalam Bab 3.4.4 dari Elemen Pembelajaran Statistik (tersedia online secara gratis). Saya pikir Bab 3.6 dalam buku itu membantu memahami hubungan antara kuadrat terkecil, subset terbaik, dan laso (ditambah beberapa prosedur lain). Saya juga merasa terbantu untuk mengambil transpos koefisien, t (coef (model)) dan write.csv, sehingga saya dapat membukanya di Excel bersama dengan salinan plot (model) di samping. Anda mungkin ingin mengurutkan berdasarkan kolom terakhir, yang berisi perkiraan kuadrat terkecil. Kemudian Anda dapat melihat dengan jelas bagaimana setiap variabel ditambahkan pada setiap langkah masing-masing dan bagaimana koefisien berubah sebagai hasilnya. Tentu saja ini bukan keseluruhan cerita, tetapi mudah-mudahan ini akan menjadi awal.

Joel Cadwell
sumber
3

larsdan glmnetberoperasi pada matriks mentah. Untuk memasukkan istilah interaksi, Anda harus membuat matriks sendiri. Itu berarti satu kolom per interaksi (yang adalah per level per faktor jika Anda memiliki faktor). Lihat ke dalam lm()untuk melihat bagaimana melakukannya (peringatan: ada naga).

Untuk melakukannya sekarang, lakukan sesuatu seperti: Untuk membuat istilah interaksi secara manual, Anda bisa (tetapi mungkin tidak boleh , karena lambat) lakukan:

int = D["x1"]*D["x2"]
names(int) = c("x1*x2")
D = cbind(D, int)

Kemudian untuk menggunakan ini dalam lars (dengan asumsi Anda memiliki ytendangan sekitar):

lars(as.matrix(D), as.matrix(y))

Saya harap saya dapat membantu Anda lebih banyak dengan pertanyaan-pertanyaan lainnya. Saya menemukan ini karena lars memberi saya kesedihan dan dokumentasi di dalamnya dan di web sangat tipis.

kousu
sumber
2
"Peringatan: ada naga" Ini cukup mudah model.matrix().
Gregor
2

LARS memecahkan jalur solusi SELURUH. Jalur solusi bersifat linear - ada sejumlah titik "takik" yang terbatas (yaitu nilai-nilai parameter regularisasi) di mana solusi berubah.

Jadi matriks solusi yang Anda dapatkan adalah semua solusi yang mungkin. Dalam daftar yang dikembalikan, itu juga harus memberi Anda nilai-nilai parameter regularisasi.

Adam
sumber
Terima kasih atas jawaban Anda. Apakah ada cara untuk menampilkan nilai-nilai parameter regularisasi? Selain itu, adakah cara untuk memilih antara solusi berdasarkan parameter ini? (Juga adalah parameter lambda?)
James
Perhatikan bahwa linearitas sedikit demi sedikit tidak berarti bahwa garis-garis itu horisontal, dan dengan demikian solusinya berubah sepanjang waktu dengan lambda. Misalnya, untuk tujuan prediksi, seseorang akan memiliki kotak nilai lambda tidak hanya di tetapi juga di antara simpul. Sangat mungkin bahwa beberapa titik di antara simpul menghasilkan kinerja prediksi terbaik yang lebih baik.
Richard Hardy