Das Lasso wird durch LARS angepasst (ein iterativer Prozess, der bei einer anfänglichen Schätzung von beginnt ). Standardmäßig ist β 0 = 0 p, aber Sie können dies in den meisten Implementierungen ändern (und es durch das optimale β ∗ o l d ersetzen, das Sie bereits haben). Je näher β ∗ o l d an β ∗ n e w liegt , desto geringer ist die Anzahl der LARS-Iterationen, die Sie ausführen müssen, um zu β ∗ n e w zu gelangen .β0β0=0pβ∗oldβ∗oldβ∗newβ∗new
BEARBEITEN:
Aufgrund der Kommentare von user2763361
füge ich meiner ursprünglichen Antwort weitere Details hinzu.
Aus den Kommentaren unten geht hervor, dass user2763361 vorschlägt, meine ursprüngliche Antwort zu ergänzen, um sie in eine zu verwandeln, die direkt (von der Stange) verwendet werden kann und gleichzeitig sehr effizient ist.
Im ersten Teil werde ich die von mir vorgeschlagene Lösung anhand eines Spielzeugbeispiels schrittweise veranschaulichen. Um den zweiten Teil zu befriedigen, verwende ich einen neuen hochwertigen Innenpunktlöser. Dies liegt daran, dass es einfacher ist, eine Hochleistungsimplementierung der von mir vorgeschlagenen Lösung zu erhalten, indem eine Bibliothek verwendet wird, die das Lasso-Problem durch den Interior-Point-Ansatz lösen kann, anstatt zu versuchen, den LARS- oder Simplex-Algorithmus zu hacken, um die Optimierung von einem Nicht-Lasso-Algorithmus aus zu starten. Standardstartpunkt (obwohl dieser zweite Veranstaltungsort auch möglich ist).
Beachten Sie, dass manchmal (in älteren Büchern) behauptet wird, dass der interne Punktansatz zum Lösen von linearen Programmen langsamer ist als der Simplex-Ansatz und dass dies vor langer Zeit zutraf, aber heute im Allgemeinen nicht mehr zutrifft und sicherlich nicht für große Probleme zutrifft (Aus diesem Grund verwenden die meisten professionellen Bibliotheken gerne cplex
den Algorithmus für Innenpunkte) und die Frage bezieht sich zumindest implizit auf große Probleme. Beachten Sie auch, dass der interne Punktlöser, den ich verwende, spärliche Matrizen vollständig handhabt, so dass ich nicht glaube, dass es eine große Leistungslücke bei LARS geben wird (eine ursprüngliche Motivation für die Verwendung von LARS war, dass viele beliebte LP-Löser zu dieser Zeit spärliche Matrizen nicht gut handhabten und Dies sind charakteristische Merkmale des LASSO-Problems.
Eine (sehr) gute Open-Source-Implementierung des Interior-Point-Algorithmus befindet ipopt
sich in der COIN-OR
Bibliothek. Ein weiterer Grund, den ich verwenden werde, ipopt
ist, dass es eine R - Schnittstelle hat ipoptr
. Eine ausführlichere Installationsanleitung finden Sie hier . Im Folgenden werden die Standardbefehle für die Installation aufgeführt ubuntu
.
in der bash
, mache:
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
Dann, als root, in R
do (ich gehe davon aus svn
, dass die Subversion-Datei ~/
wie standardmäßig kopiert wurde ):
install.packages("~/CoinIpopt/Ipopt/contrib/RInterface",repos=NULL,type="source")
Von hier aus gebe ich ein kleines Beispiel (hauptsächlich aus dem Spielzeugbeispiel, das Jelmer Ypma als Teil seines R
Wrapers an gegeben hat 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 ) )
Mein Punkt ist, wenn Sie neue Daten haben, müssen Sie nur
- Aktualisieren ( nicht ersetzen) Sie die Beschränkungsmatrix und den Zielfunktionsvektor, um die neuen Beobachtungen zu berücksichtigen.
Ändern Sie die Startpunkte des Innenpunkts von
x0 = c (rep (0, m), rep (1, m))
βnewβoldβinitx0
|βinit−βnew|1>|βnew−βold|1(1)
βnewβoldβinitnp
Die Bedingungen, unter denen Ungleichung (1) gilt, sind:
- λ|βOLS|1pn
- wenn die neuen Beobachtungen keinen pathologischen Einfluss haben, z. B. wenn sie mit dem stochastischen Prozess übereinstimmen, der die vorhandenen Daten erzeugt hat.
- wenn die Größe der Aktualisierung im Verhältnis zur Größe der vorhandenen Daten klein ist.