Kement, LARS (bazı başlangıç tahminlerinde başlayan yinelemeli bir süreç) aracılığıyla takılır . Varsayılan olarak β 0 = 0 p ama çoğu uygulamada bu değiştirebilir (ve optimal tarafından yerine p * o l d zaten var). En yakın β * o l d için p * n, e ağırlık Lars sayısı, adım olacaktır iterasyon küçük almak için, p * n e ağırlık .β0β0= 0pβ*o l dβ*o l dβ*n e wβ*n e w
DÜZENLE:
Yorumlarından dolayı user2763361
orijinal cevabıma daha fazla ayrıntı ekliyorum.
Aşağıdaki yorumlardan, user2763361'in, çok etkili olurken doğrudan (raflardan) kullanılabilecek bir cevaba dönüştürmek için orijinal cevabımı tamamlamayı öneriyorum.
İlk kısmı yapmak için, oyuncak örneğinde adım adım önerdiğim çözümü göstereceğim. İkinci kısmı tatmin etmek için, yakın zamanda yüksek kaliteli bir iç nokta çözücü kullanarak yapacağım. Bunun nedeni, LARS veya simpleks algoritmasını bir non-optimizasyondan başlatmak için kesmek yerine, iç nokta yaklaşımı ile kement problemini çözebilecek bir kütüphane kullanarak önerdiğim çözümün yüksek performanslı bir uygulamasını elde etmek daha kolaydır. standart başlangıç noktası (ikinci mekan da mümkündür).
Bazen (eski kitaplarda) doğrusal programların çözülmesine yönelik iç nokta yaklaşımının simpleks yaklaşımdan daha yavaş olduğu ve bunun uzun zaman önce doğru olabileceğini ancak genellikle bugün doğru olmadığını ve büyük ölçekli problemler için kesinlikle doğru olmadığını iddia ettiğini unutmayın. (bu yüzden çoğu profesyonel kütüphane cplex
iç nokta algoritmasını kullanır) ve soru en azından büyük ölçekli problemlerle ilgilidir. Ayrıca kullandığım iç nokta çözücünün seyrek matrisleri tamamen ele aldığını unutmayın, bu yüzden LARS ile büyük bir performans boşluğu olacağını düşünmüyorum (LARS'ı kullanmak için orijinal bir motivasyon, o zamanlar birçok popüler LP çözücünün seyrek matrisleri iyi işlemediğiydi ve bunlar LASSO sorununun karakteristik özellikleridir).
İç nokta algoritmalarının bir (çok) iyi açık kaynak uygulamasıdır ipopt
içinde, COIN-OR
kütüphanede. Kullanmamın bir başka nedeni ipopt
de bir R arayüzüne sahip olması ipoptr
. Burada daha kapsamlı kurulum kılavuzu bulacaksınız , aşağıda yüklemek için standart komutları veriyorum ubuntu
.
içinde bash
, yapmak:
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
Sonra, root olarak, R
do (varsayılan olarak svn
subversion dosyasını kopyaladığı ~/
varsayılır):
install.packages("~/CoinIpopt/Ipopt/contrib/RInterface",repos=NULL,type="source")
Buradan ben (çoğunlukla onun bir parçası olarak Jelmer Ypma tarafından verilen oyuncak örnekten küçük bir örnek veriyorum R
wraper için 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 ) )
Demek istediğim, eğer yeni verileriniz varsa,
- güncellemek ( değil yeni gözlemler için hesaba kısıt matrisi ve amaç fonksiyonu vektörü değiştirin).
iç noktanın başlangıç noktalarını
x0 = c (rep (0, m), rep (1, m))
βn e wβo l dβben n ben tx0
| βben n ben t- βn e w|1> | βn e w- βo l d|1( 1 )
βn e wβo l dβben n ben tnp
Eşitsizliğin (1) sahip olduğu koşullara gelince, bunlar:
- λ| βO L S|1pn
- yeni gözlemler patolojik olarak etkili olmadığında, örneğin mevcut verileri üreten stokastik süreçle tutarlı olduklarında.
- güncellemenin boyutu mevcut verilerin boyutuna göre küçük olduğunda.