올가미는 LARS (반복 프로세스, 초기 추정치 에서 시작)를 통해 적합합니다 . 기본적으로 이지만 대부분의 구현에서이 값을 변경할 수 있습니다 (그리고 이미 가지고 있는 최적의 바꿉니다 ). 가장 가까운 이다 , LARS의 수는 당신이 얻을 단계로해야합니다 반복 작은 .β 0 = 0 p β ∗ o l d β ∗ o l d β ∗ n e w β ∗ n e wβ0β0= 0피β※o l dβ※o l dβ※N E wβ※N E w
편집하다:
의견으로 인해 user2763361
원래 답변에 더 자세한 내용을 추가합니다.
아래 의견에서 user2763361은 원래의 답변을 보완하여 직접 사용할 수있는 선반으로 바꿀 수 있다고 제안합니다.
첫 번째 부분을 수행하기 위해 장난감 예제에서 단계별로 제안하는 솔루션을 설명하겠습니다. 두 번째 부분을 만족시키기 위해 최근 고품질의 내부 포인트 솔버를 사용합니다. LARS 또는 심플 렉스 알고리즘을 해킹하려고 시도하지 않고 내부 포인트 접근 방식으로 올가미 문제를 해결할 수있는 라이브러리를 사용하여 제안하는 솔루션의 고성능 구현을 얻는 것이 더 쉽기 때문입니다. 표준 출발점 (두 번째 장소도 가능하지만).
선형 프로그램을 해결하기위한 내부 접근 방식이 단순 접근 방식보다 느리고 오래 전에 사실 일 수도 있지만 오늘날 일반적으로 사실이 아니며 대규모 문제에 대해서는 사실이 아니라고 주장하는 경우가 있습니다 (오래된 책에서). (이것이 대부분의 전문 라이브러리 cplex
가 내부 포인트 알고리즘을 사용하는 이유입니다 ) 그리고 문제는 적어도 대규모 문제에 관한 것입니다. 또한 내가 사용하는 내부 포인트 솔버는 희소 행렬을 완전히 처리하므로 LARS와의 성능 차이가 크지 않을 것이라고 생각합니다 (LARS 사용의 원래 동기는 당시 많은 인기있는 LP 솔버가 희소 행렬을 잘 처리하지 않았으며 LASSO 문제의 특징입니다).
내부 포인트 알고리즘의 A (매우) 좋은 오픈 소스 구현은 ipopt
에서, COIN-OR
도서관. 내가 사용할 또 다른 이유 ipopt
는 R 인터페이스가 있기 때문 ipoptr
입니다. 여기에 설치를 위한 표준 명령을 제공하는 보다 포괄적 인 설치 안내서가 있습니다ubuntu
.
에서 bash
:
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
그런 다음 루트로 R
수행합니다 ( 기본적으로 svn
하위 버전 파일을 복사 한 것으로 가정 합니다 ~/
).
install.packages("~/CoinIpopt/Ipopt/contrib/RInterface",repos=NULL,type="source")
여기에서 나는 작은 예를 제시합니다 (주로 Jelmer Ypma가 그의 R
랩퍼의 일부로 제공 한 장난감 예 에서 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 ) )
내 요점은, 새로운 데이터가 있다면
- 새로운 관측치를 설명하기 위해 구속 조건 행렬과 목적 함수 벡터를 업데이트 ( 대체 하지 않음 )합니다.
내부 지점의 시작점을
x0 = c (rep (0, m), rep (1, m))
이전에 찾은 솔루션 벡터에 새 데이터를 추가하기 전에 여기의 논리는 다음과 같습니다. 새로운 계수 벡터 (업데이트 후 데이터 세트에 해당하는)와 원래 계수를 나타냅니다 . 또한 위 코드에서 벡터 를 표시하십시오 (이것은 내부 포인트 방법의 일반적인 시작입니다). 그렇다면 아이디어는 다음과 같습니다.βN E wβoldβinitx0
|βinit−βnew|1>|βnew−βold|1(1)
그러면 순진한 보다 에서 내부 지점을 시작하여 훨씬 빠르게
얻을 수 있습니다 . 데이터 세트의 치수 ( 및 )가 클 때 게인이 더 중요합니다 .βnewβoldβinitnp
불평등 (1)이 유지되는 조건은 다음과 같습니다.
- 경우 에 비해 크다 (이는 보통의 경우 일 때 , 설계 변수의 수에 비해 큰 , 관측 횟수)λ|βOLS|1pn
- 새로운 관측치가 병리학 적으로 영향을 미치지 않는 경우, 예를 들어 기존 데이터를 생성 한 확률 적 프로세스와 일치하는 경우.
- 업데이트의 크기가 기존 데이터의 크기에 비해 작은 경우