Memperbarui laso fit dengan pengamatan baru

12

Saya menyesuaikan regresi linier yang teregulasi L1 ke dataset yang sangat besar (dengan n >> p.) Variabel-variabel tersebut diketahui sebelumnya, tetapi pengamatannya tiba dalam potongan-potongan kecil. Saya ingin mempertahankan laso setelah setiap potong.

Saya jelas dapat menyesuaikan kembali seluruh model setelah melihat setiap set pengamatan baru. Ini, bagaimanapun, akan sangat tidak efisien mengingat bahwa ada banyak data. Jumlah data baru yang tiba di setiap langkah sangat kecil, dan kecocokan tidak mungkin banyak berubah di antara langkah-langkah.

Adakah yang bisa saya lakukan untuk mengurangi beban komputasi secara keseluruhan?

Saya sedang melihat algoritma LARS dari Efron et al., Tetapi akan dengan senang hati mempertimbangkan metode pemasangan lainnya jika dapat dibuat untuk "memulaikan" dengan cara yang dijelaskan di atas.

Catatan:

  1. Saya terutama mencari algoritme, tetapi petunjuk ke paket perangkat lunak yang ada yang dapat melakukan ini juga dapat membuktikan wawasan.
  2. Selain lintasan laso saat ini, algoritma ini tentu saja selamat datang untuk menjaga keadaan lainnya.

Bradley Efron, Trevor Hastie, Iain Johnstone dan Robert Tibshirani, Least Angle Regression , Annals of Statistics (dengan diskusi) (2004) 32 (2), 407-499.

NPE
sumber

Jawaban:

7

Laso dipasang melalui LARS (proses berulang, yang dimulai pada beberapa estimasi awal ). Secara default tetapi Anda dapat mengubahnya di sebagian besar implementasi (dan menggantinya dengan optimal yang sudah Anda miliki). Yang paling dekat adalah untuk , semakin kecil jumlah Lars iterasi Anda harus langkah untuk mendapatkan .β0β o l d β o l d β n e w β n e wβ0=0pβoldβoldβnewβnew

EDIT:

Karena komentar dari user2763361saya menambahkan lebih banyak detail ke jawaban asli saya.

Dari komentar di bawah ini saya kumpulkan bahwa user2763361 menyarankan untuk melengkapi jawaban asli saya untuk mengubahnya menjadi yang dapat digunakan secara langsung (dari rak) sementara juga sangat efisien.

Untuk melakukan bagian pertama, saya akan menggambarkan solusi yang saya usulkan langkah demi langkah pada contoh mainan. Untuk memenuhi bagian kedua, saya akan melakukannya menggunakan pemecah titik interior berkualitas tinggi baru-baru ini. Ini karena, lebih mudah untuk mendapatkan implementasi kinerja tinggi dari solusi yang saya usulkan menggunakan perpustakaan yang dapat memecahkan masalah laso dengan pendekatan titik interior daripada mencoba untuk meretas LARS atau algoritma simpleks untuk memulai optimasi dari non- titik awal standar (meskipun venue kedua juga dimungkinkan).

Perhatikan bahwa kadang-kadang diklaim (dalam buku-buku yang lebih tua) bahwa pendekatan titik interior untuk menyelesaikan program linier lebih lambat daripada pendekatan simpleks dan yang mungkin benar sejak lama, tetapi itu umumnya tidak benar hari ini dan tentu saja tidak berlaku untuk masalah skala besar (Inilah sebabnya kebanyakan perpustakaan profesional suka cplexmenggunakan algoritma titik interior) dan pertanyaannya adalah setidaknya secara implisit tentang masalah skala besar. Perhatikan juga bahwa pemecah titik interior yang saya gunakan sepenuhnya menangani matriks jarang jadi saya tidak berpikir akan ada kesenjangan kinerja yang besar dengan LARS (motivasi asli untuk menggunakan LARS adalah bahwa banyak pemecah LP populer pada saat itu tidak menangani matriks jarang dengan baik dan ini adalah fitur karakteristik dari masalah LASSO).

Implementasi open source yang bagus dari algoritma titik interior adalah ipopt, di COIN-ORperpustakaan. Alasan lain yang akan saya gunakan ipoptadalah bahwa ia memiliki antarmuka R ipoptr,. Anda akan menemukan panduan instalasi yang lebih lengkap di sini , di bawah ini saya memberikan perintah standar untuk menginstalnya ubuntu.

di bash, lakukan:

sudo apt-get install gcc g++ gfortran subversion patch wget
svn co https://projects.coin-or.org/svn/Ipopt/stable/3.11 CoinIpopt
cd ~/CoinIpopt
./configure
make 
make install

Kemudian, sebagai root, di Rdo (saya berasumsi svntelah menyalin file subversi ~/seperti yang dilakukan secara default):

install.packages("~/CoinIpopt/Ipopt/contrib/RInterface",repos=NULL,type="source")

Dari sini, saya memberikan contoh kecil (kebanyakan dari contoh mainan yang diberikan oleh Jelmer Ypma sebagai bagian dari Rpembungkusnya ipopt):

library('ipoptr')
# Experiment parameters.
lambda <- 1                                # Level of L1 regularization.
n      <- 100                              # Number of training examples.
e      <- 1                                # Std. dev. in noise of outputs.
beta   <- c( 0, 0, 2, -4, 0, 0, -1, 3 )    # "True" regression coefficients.
# Set the random number generator seed.
ranseed <- 7
set.seed( ranseed )
# CREATE DATA SET.
# Generate the input vectors from the standard normal, and generate the
# responses from the regression with some additional noise. The variable 
# "beta" is the set of true regression coefficients.
m     <- length(beta)                           # Number of features.
A     <- matrix( rnorm(n*m), nrow=n, ncol=m )   # The n x m matrix of examples.
noise <- rnorm(n, sd=e)                         # Noise in outputs.
y     <- A %*% beta + noise                     # The outputs.
# DEFINE LASSO FUNCTIONS
# m, lambda, y, A are all defined in the ipoptr_environment
eval_f <- function(x) {
    # separate x in two parts
    w <- x[  1:m ]          # parameters
    u <- x[ (m+1):(2*m) ]

    return( sum( (y - A %*% w)^2 )/2 + lambda*sum(u) )
}
# ------------------------------------------------------------------
eval_grad_f <- function(x) {
    w <- x[ 1:m ]
    return( c( -t(A) %*% (y - A %*% w),  
               rep(lambda,m) ) )
}
# ------------------------------------------------------------------
eval_g <- function(x) {
    # separate x in two parts
    w <- x[  1:m ]          # parameters
    u <- x[ (m+1):(2*m) ]
    return( c( w + u, u - w ) )
}
eval_jac_g <- function(x) {
    # return a vector of 1 and minus 1, since those are the values of the non-zero elements
    return( c( rep( 1, 2*m ), rep( c(-1,1), m ) ) )
}
# ------------------------------------------------------------------
# rename lambda so it doesn't cause confusion with lambda in auxdata
eval_h <- function( x, obj_factor, hessian_lambda ) {
    H <- t(A) %*% A
    H <- unlist( lapply( 1:m, function(i) { H[i,1:i] } ) )
    return( obj_factor * H )
}
eval_h_structure <- c( lapply( 1:m, function(x) { return( c(1:x) ) } ),
                       lapply( 1:m, function(x) { return( c() ) } ) )
# The starting point.
x0 = c( rep(0, m), 
        rep(1, m) )
# The constraint functions are bounded from below by zero.
constraint_lb = rep(   0, 2*m )
constraint_ub = rep( Inf, 2*m )
ipoptr_opts <- list( "jac_d_constant"   = 'yes',
                     "hessian_constant" = 'yes',
                     "mu_strategy"      = 'adaptive',
                     "max_iter"         = 100,
                     "tol"              = 1e-8 )
# Set up the auxiliary data.
auxdata <- new.env()
auxdata$m <- m
    auxdata$A <- A
auxdata$y <- y
    auxdata$lambda <- lambda
# COMPUTE SOLUTION WITH IPOPT.
# Compute the L1-regularized maximum likelihood estimator.
print( ipoptr( x0=x0, 
               eval_f=eval_f, 
               eval_grad_f=eval_grad_f, 
               eval_g=eval_g, 
               eval_jac_g=eval_jac_g,
               eval_jac_g_structure=eval_jac_g_structure,
               constraint_lb=constraint_lb, 
               constraint_ub=constraint_ub,
               eval_h=eval_h,
               eval_h_structure=eval_h_structure,
               opts=ipoptr_opts,
               ipoptr_environment=auxdata ) )

Maksud saya adalah, jika Anda memiliki data baru, Anda hanya perlu

  1. memperbarui ( tidak menggantikan) matriks kendala dan vektor fungsi tujuan untuk menjelaskan pengamatan baru.
  2. mengubah titik awal dari titik interior dari

    x0 = c (rep (0, m), rep (1, m))

    ke vektor solusi yang Anda temukan sebelumnya (sebelum data baru ditambahkan). Logikanya di sini adalah sebagai berikut. Mendenotasikan vektor baru koefisien (yang sesuai dengan kumpulan data setelah update) dan yang asli. Juga tunjukkan vektor dalam kode di atas (ini adalah awal yang biasa untuk metode titik interior). Maka idenya adalah jika: β o l d β i n i tβnewβoldβinitx0

|βinitβnew|1>|βnewβold|1(1)

kemudian, seseorang bisa mendapatkan lebih cepat dengan memulai titik interior dari daripada naive . Gain akan menjadi lebih penting ketika dimensi dari set data ( dan ) lebih besar.βnewβHaildβsayansayatnhal

Adapun kondisi di mana ketidaksetaraan (1) berlangsung, mereka adalah:

  • ketika besar dibandingkan dengan (ini biasanya terjadi ketika , jumlah variabel desain besar dibandingkan dengan , jumlah pengamatan)λ|βHAILS|1haln
  • ketika pengamatan baru tidak berpengaruh secara patologis, misalnya misalnya ketika mereka konsisten dengan proses stokastik yang telah menghasilkan data yang ada.
  • ketika ukuran pembaruan relatif kecil dengan ukuran data yang ada.
pengguna603
sumber
hal+1ββ00hal
@aix: apakah Anda ingin memperbarui seluruh jalur laso atau hanya solusinya? (Yaitu apakah hukuman sparsity tetap?).
user603
λ
β^lSebuahssHai=Argminβ{12saya=1N(ysaya-β0-j=1halxsayajβj)2+λj=1hal|βj|}
β
1
Adakah perpustakaan yang Anda kenal yang dapat melakukan ini tanpa perlu mengedit kode sumber?
user2763361