Mengapa Lars dan Glmnet memberikan solusi berbeda untuk masalah Lasso?

22

Saya ingin lebih memahami paket R Larsdan Glmnet, yang digunakan untuk menyelesaikan masalah Lasso: (untuk Variabel dan sampel , lihat www.stanford.edu/~hastie/Papers/glmnet.pdf di halaman 3)p

msayan(β0β)Rhal+1[12Nsaya=1N(ysaya-β0-xsayaTβ)2+λ||β||l1]
halN

Karena itu, saya menerapkan keduanya pada dataset mainan yang sama. Sayangnya, kedua metode ini tidak memberikan solusi yang sama untuk input data yang sama. Adakah yang tahu dari mana perbedaan itu berasal?

Saya memperoleh hasil sebagai berikut: Setelah menghasilkan beberapa data (8 sampel, 12 fitur, desain Toeplitz, semuanya berpusat), saya menghitung seluruh jalur Lasso menggunakan Lars. Kemudian, saya menjalankan Glmnet menggunakan urutan lambdas yang dihitung oleh Lars (dikalikan 0,5) dan berharap mendapatkan solusi yang sama, tetapi saya tidak melakukannya.

Orang dapat melihat bahwa solusinya serupa. Tetapi bagaimana saya bisa menjelaskan perbedaannya? Temukan kode saya di bawah ini. Ada pertanyaan terkait di sini: GLMNET atau LARS untuk menghitung solusi LASSO? , tetapi tidak mengandung jawaban atas pertanyaan saya.

Mendirikan:

# Load packages.
library(lars)
library(glmnet)
library(MASS)

# Set parameters.
nb.features <- 12
nb.samples <- 8
nb.relevant.indices <- 3
snr <- 1
nb.lambdas <- 10

# Create data, not really important. 
sigma <- matrix(0, nb.features, nb.features)
for (i in (1:nb.features)) {
  for (j in (1:nb.features)) {
    sigma[i, j] <- 0.99 ^ (abs(i - j))
  }
}

x <- mvrnorm(n=nb.samples, rep(0, nb.features), sigma, tol=1e-6, empirical=FALSE)
relevant.indices <- sample(1:nb.features, nb.relevant.indices, replace=FALSE)
x <- scale(x)
beta <- rep(0, times=nb.features)
beta[relevant.indices] <- runif(nb.relevant.indices, 0, 1)
epsilon <- matrix(rnorm(nb.samples),nb.samples, 1)
simulated.snr <-(norm(x %*% beta, type="F")) / (norm(epsilon, type="F"))
epsilon <- epsilon * (simulated.snr / snr)
y <- x %*% beta + epsilon
y <- scale(y)

lars:

la <- lars(x, y, intercept=TRUE, max.steps=1000, use.Gram=FALSE)
co.lars <- as.matrix(coef(la, mode="lambda"))
print(round(co.lars, 4))

#          [,1] [,2] [,3]   [,4]   [,5]   [,6]    [,7]   [,8]    [,9]   [,10]
#  [1,]  0.0000    0    0 0.0000 0.0000 0.0000  0.0000 0.0000  0.0000  0.0000
#  [2,]  0.0000    0    0 0.0000 0.0000 0.1735  0.0000 0.0000  0.0000  0.0000
#  [3,]  0.0000    0    0 0.2503 0.0000 0.4238  0.0000 0.0000  0.0000  0.0000
#  [4,]  0.0000    0    0 0.1383 0.0000 0.7578  0.0000 0.0000  0.0000  0.0000
#  [5,] -0.1175    0    0 0.2532 0.0000 0.8506  0.0000 0.0000  0.0000  0.0000
#  [6,] -0.3502    0    0 0.2676 0.3068 0.9935  0.0000 0.0000  0.0000  0.0000
#  [7,] -0.4579    0    0 0.6270 0.0000 0.9436  0.0000 0.0000  0.0000  0.0000
#  [8,] -0.7848    0    0 0.9970 0.0000 0.9856  0.0000 0.0000  0.0000  0.0000
#  [9,] -0.3175    0    0 0.0000 0.0000 3.4488  0.0000 0.0000 -2.1714  0.0000
# [10,] -0.4842    0    0 0.0000 0.0000 4.7731  0.0000 0.0000 -3.4102  0.0000
# [11,] -0.4685    0    0 0.0000 0.0000 4.7958  0.0000 0.1191 -3.6243  0.0000
# [12,] -0.4364    0    0 0.0000 0.0000 5.0424  0.0000 0.3007 -4.0694 -0.4903
# [13,] -0.4373    0    0 0.0000 0.0000 5.0535  0.0000 0.3213 -4.1012 -0.4996
# [14,] -0.4525    0    0 0.0000 0.0000 5.6876 -1.5467 1.5095 -4.7207  0.0000
# [15,] -0.4593    0    0 0.0000 0.0000 5.7355 -1.6242 1.5684 -4.7440  0.0000
# [16,] -0.4490    0    0 0.0000 0.0000 5.8601 -1.8485 1.7767 -4.9291  0.0000
#         [,11]  [,12]
#  [1,]  0.0000 0.0000
#  [2,]  0.0000 0.0000
#  [3,]  0.0000 0.0000
#  [4,] -0.2279 0.0000
#  [5,] -0.3266 0.0000
#  [6,] -0.5791 0.0000
#  [7,] -0.6724 0.2001
#  [8,] -1.0207 0.4462
#  [9,] -0.4912 0.1635
# [10,] -0.5562 0.2958
# [11,] -0.5267 0.3274
# [12,]  0.0000 0.2858
# [13,]  0.0000 0.2964
# [14,]  0.0000 0.1570
# [15,]  0.0000 0.1571

glmnet dengan lambda = (lambda_lars / 2):

glm2 <- glmnet(x, y, family="gaussian", lambda=(0.5 * la$lambda), thresh=1e-16)
co.glm2 <- as.matrix(t(coef(glm2, mode="lambda")))
print(round(co.glm2, 4))

#     (Intercept)      V1 V2 V3     V4     V5     V6      V7     V8      V9
# s0            0  0.0000  0  0 0.0000 0.0000 0.0000  0.0000 0.0000  0.0000
# s1            0  0.0000  0  0 0.0000 0.0000 0.0000  0.0000 0.0000  0.0000
# s2            0  0.0000  0  0 0.2385 0.0000 0.4120  0.0000 0.0000  0.0000
# s3            0  0.0000  0  0 0.2441 0.0000 0.4176  0.0000 0.0000  0.0000
# s4            0  0.0000  0  0 0.2466 0.0000 0.4200  0.0000 0.0000  0.0000
# s5            0  0.0000  0  0 0.2275 0.0000 0.4919  0.0000 0.0000  0.0000
# s6            0  0.0000  0  0 0.1868 0.0000 0.6132  0.0000 0.0000  0.0000
# s7            0 -0.2651  0  0 0.2623 0.1946 0.9413  0.0000 0.0000  0.0000
# s8            0 -0.6609  0  0 0.7328 0.0000 1.6384  0.0000 0.0000 -0.5755
# s9            0 -0.4633  0  0 0.0000 0.0000 4.6069  0.0000 0.0000 -3.2547
# s10           0 -0.4819  0  0 0.0000 0.0000 4.7546  0.0000 0.0000 -3.3929
# s11           0 -0.4767  0  0 0.0000 0.0000 4.7839  0.0000 0.0567 -3.5122
# s12           0 -0.4715  0  0 0.0000 0.0000 4.7915  0.0000 0.0965 -3.5836
# s13           0 -0.4510  0  0 0.0000 0.0000 5.6237 -1.3909 1.3898 -4.6583
# s14           0 -0.4552  0  0 0.0000 0.0000 5.7064 -1.5771 1.5326 -4.7298
#         V10     V11    V12
# s0   0.0000  0.0000 0.0000
# s1   0.0000  0.0000 0.0000
# s2   0.0000  0.0000 0.0000
# s3   0.0000  0.0000 0.0000
# s4   0.0000  0.0000 0.0000
# s5   0.0000 -0.0464 0.0000
# s6   0.0000 -0.1293 0.0000
# s7   0.0000 -0.4868 0.0000
# s8   0.0000 -0.8803 0.3712
# s9   0.0000 -0.5481 0.2792
# s10  0.0000 -0.5553 0.2939
# s11  0.0000 -0.5422 0.3108
# s12  0.0000 -0.5323 0.3214
# s13 -0.0503  0.0000 0.1711
# s14  0.0000  0.0000 0.1571
Andre
sumber

Jawaban:

20

Akhirnya kami dapat menghasilkan solusi yang sama dengan kedua metode! Masalah pertama adalah bahwa glmnet memecahkan masalah laso seperti yang dinyatakan dalam pertanyaan, tetapi lars memiliki normalisasi yang sedikit berbeda dalam fungsi objektif, ia menggantikan oleh . Kedua, kedua metode menormalkan data secara berbeda, sehingga normalisasi harus dibatalkan ketika memanggil metode. 112N12

Untuk mereproduksi itu, dan melihat bahwa solusi yang sama untuk masalah laso dapat dihitung menggunakan lars dan glmnet, baris berikut dalam kode di atas harus diubah:

la <- lars(X,Y,intercept=TRUE, max.steps=1000, use.Gram=FALSE)

untuk

la <- lars(X,Y,intercept=TRUE, normalize=FALSE, max.steps=1000, use.Gram=FALSE)

dan

glm2 <- glmnet(X,Y,family="gaussian",lambda=0.5*la$lambda,thresh=1e-16)

untuk

glm2 <- glmnet(X,Y,family="gaussian",lambda=1/nbSamples*la$lambda,standardize=FALSE,thresh=1e-16)
Andre
sumber
1
Saya senang Anda menemukan ini. Adakah pemikiran tentang metode normalisasi mana yang lebih masuk akal? Saya sebenarnya mendapatkan hasil yang lebih buruk menggunakan normalisasi di glmnet (untuk laso) dan saya masih tidak yakin mengapa.
Ben Ogorek
Saya benar-benar menormalkan data begitu saja dan menerapkan metode ini dan membandingkannya jika mirip. Variabel dengan efek yang lebih kecil biasanya terlihat memiliki koefisien yang berbeda
KarthikS
0

Tentunya jika metode menggunakan model yang berbeda Anda akan mendapatkan jawaban yang berbeda. Mengurangi persyaratan intersep tidak mengarah ke model tanpa intersep karena koefisien fitting terbaik akan berubah dan Anda tidak mengubahnya seperti yang Anda dekati. Anda harus menyesuaikan model yang sama dengan kedua metode jika Anda menginginkan jawaban yang sama atau hampir sama.

Michael R. Chernick
sumber
1
Ya, Anda benar, metode menggunakan model yang sedikit berbeda, saya tidak menyadarinya. Terima kasih atas petunjuknya. (Saya akan menjelaskan perbedaannya secara lebih terperinci dalam jawaban yang terpisah)
Andre
-2

Hasilnya harus sama. Paket lars menggunakan secara default type = "lar", ubah nilainya menjadi type = "lasso". Turunkan parameter 'thresh = 1e-16' untuk glmnet karena penurunan koordinat didasarkan pada konvergensi.

Marcool Lopez Cruz
sumber
2
Terima kasih atas jawaban Anda. Mungkin saya salah membaca, tetapi sepertinya bertentangan dengan resolusi yang diposting dalam jawaban Andre enam tahun lalu. Harap pertimbangkan untuk menguraikan pos Anda untuk menyertakan penjelasan yang lebih lengkap tentang apa yang Anda coba katakan dan tunjukkan mengapa kami harus percaya itu benar dan yang lain tidak.
whuber