새로운 관측치로 올가미 업데이트


12

L1 정규 선형 회귀 분석을 매우 큰 데이터 세트에 맞추고 있습니다 (n >> p 사용) 변수는 미리 알려져 있지만 관측치는 작은 덩어리로 도착합니다. 각 덩어리 후에 올가미 맞춤을 유지하고 싶습니다.

각각의 새로운 관측 값 세트를 본 후 전체 모델을 다시 맞출 수 있습니다. 그러나 이것은 많은 데이터가 있다는 점에서 상당히 비효율적입니다. 각 단계에 도달 하는 데이터 의 양은 매우 적으며 단계간에 적합하지 않을 수 있습니다.

전체 계산 부담을 줄이기 위해 내가 할 수있는 일이 있습니까?

나는 Efron et al.의 LARS 알고리즘을보고 있었지만 위에서 설명한 방식으로 "웜 스타트 (warm-start)"할 수 있다면 다른 피팅 방법을 고려해 보겠습니다.

노트:

  1. 주로 알고리즘을 찾고 있지만이를 수행 할 수있는 기존 소프트웨어 패키지에 대한 포인터도 통찰력이있을 수 있습니다.
  2. 현재의 올가미 궤도 외에도, 알고리즘은 다른 상태를 유지하는 것을 환영합니다.

Bradley Efron, Trevor Hastie, Iain Johnstone 및 Robert Tibshirani, Least Angle Regression , Annals of Statistics (토론 포함) (2004) 32 (2), 407-499.

답변:


7

올가미는 LARS (반복 프로세스, 초기 추정치 에서 시작)를 통해 적합합니다 . 기본적으로 이지만 대부분의 구현에서이 값을 변경할 수 있습니다 (그리고 이미 가지고 있는 최적의 바꿉니다 ). 가장 가까운 이다 , LARS의 수는 당신이 얻을 단계로해야합니다 반복 작은 .β 0 = 0 p β o l d β o l d β n e w β n e wβ0β0=0pβoldβoldβnewβnew

편집하다:

의견으로 인해 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 ) )

내 요점은, 새로운 데이터가 있다면

  1. 새로운 관측치를 설명하기 위해 구속 조건 행렬과 목적 함수 벡터를 업데이트 ( 대체 하지 않음 )합니다.
  2. 내부 지점의 시작점을

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

    이전에 찾은 솔루션 벡터에 새 데이터를 추가하기 전에 여기의 논리는 다음과 같습니다. 새로운 계수 벡터 (업데이트 후 데이터 세트에 해당하는)와 원래 계수를 나타냅니다 . 또한 위 코드에서 벡터 를 표시하십시오 (이것은 내부 포인트 방법의 일반적인 시작입니다). 그렇다면 아이디어는 다음과 같습니다.βnewβoldβinitx0

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

그러면 순진한 보다 에서 내부 지점을 시작하여 훨씬 빠르게 얻을 수 있습니다 . 데이터 세트의 치수 ( 및 )가 클 때 게인이 더 중요합니다 .βnewβoldβinitnp

불평등 (1)이 유지되는 조건은 다음과 같습니다.

  • 경우 에 비해 크다 (이는 보통의 경우 일 때 , 설계 변수의 수에 비해 큰 , 관측 횟수)λ|βOLS|1pn
  • 새로운 관측치가 병리학 적으로 영향을 미치지 않는 경우, 예를 들어 기존 데이터를 생성 한 확률 적 프로세스와 일치하는 경우.
  • 업데이트의 크기가 기존 데이터의 크기에 비해 작은 경우

고마워,하지만 내가 따르지 않을 까봐 두려워 LARS는 조각 별 선형 경로를 생성합니다 ( 최소 각도에 대해 정확히 포인트, 올가미에 대해 더 많은 포인트 포함). 각 포인트에는 고유 한 세트가 있습니다. 더 많은 관측치를 추가하면 모든 베타가 이동할 수 있습니다 ( 제외 , 항상 . 답을 넓힐 수 있습니까? 감사. β β 0 0 Pp+1ββ00p
NPE

@ aix : 전체 올가미 경로 또는 솔루션을 업데이트 하시겠습니까? (즉, 희소성 패널티는 고정되어 있습니까?).
user603

전체 경로를 업데이트하려고했습니다. 그러나 고정 된 페널티 ( 아래 식에서 에 대해 좋은 방법이 있다면 이것이 좋은 시작일 수 있습니다. 이것이 당신이 제안하는 것입니까? β L S S O = argmin β { 1λ
β^lasso=argminβ{12i=1N(yiβ0j=1pxijβj)2+λj=1p|βj|}
NPE

@aix. 예, 사용하는 구현 및 액세스 할 수있는 시설에 따라 다릅니다. 예를 들어, 좋은 lp 솔버에 액세스 할 수 있으면 과거의 최적의 값으로 피드를 제공 할 수 있으며 1-2 단계를 새로운 솔루션으로 매우 효율적으로 전달할 수 있습니다. 이러한 세부 사항을 질문에 추가해야합니다. β
user603

1
소스 코드를 편집 할 필요없이이 작업을 수행 할 수있는 라이브러리가 있습니까?
user2763361
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.