新しい観測によるなげなわ近似の更新


12

L1正規化線形回帰を非常に大きなデータセットに適合させています(n >> p)。変数は事前にわかっていますが、観測値は小さな塊で到着します。各チャンクの後に投げ縄の適合を維持したいと思います。

新しい観測セットをそれぞれ確認した後、モデル全体を明らかに再適合させることができます。ただし、大量のデータがある場合、これは非常に非効率的です。各ステップに到着する新しいデータの量は非常に少なく、適合度がステップ間で大きく変わることはほとんどありません。

全体的な計算負荷を軽減するためにできることはありますか?

エフロンらのLARSアルゴリズムを見ていましたが、上記の方法で「ウォームスタート」できる場合は、他のフィッティング方法を検討できます。

ノート:

  1. 私は主にアルゴリズムを探していますが、これを行うことができる既存のソフトウェアパッケージへのポインタも洞察力があるかもしれません。
  2. 現在のなげなわ軌跡に加えて、アルゴリズムはもちろん他の状態を維持することを歓迎します。

Bradley Efron、Trevor Hastie、Iain JohnstoneおよびRobert Tibshirani、 Least Angle RegressionAnnals of Statistics(議論あり)(2004)32(2)、407--499。

回答:


7

投げ縄は、LARS(いくつかの初期推定から始まる反復プロセスを介して装着されている)。デフォルトではβ 0 = 0 のpはできますが、ほとんどの実装でこれを変更(および最適でそれを置き換えることができβ * oをリットルのDあなたが既に持っています)。最も近いβの* O リットルのdがすることであるβ * nはE wは LARSの数は、あなたがステップになりますイテレーション小さいがために取得するには、β * n個の電子ワットをβ0β0=0pβoldβoldβnewβnew

編集:

からのコメントの user2763361ため、元の回答に詳細を追加します。

以下のコメントから、user2763361は、元の回答を補完して、非常に効率的でありながら(棚から離れて)直接使用できるものに変えることを提案していることを収集します。

最初の部分を実行するために、おもちゃの例で段階的に提案する解決策を説明します。2番目の部分を満たすために、最近の高品質の内点ソルバーを使用してこれを行います。これは、LARSまたはシンプレックスアルゴリズムをハッキングして最適化を非標準的な出発点(ただし、2番目の会場も可能です)。

(古い本では)線形プログラムを解くための内点アプローチはシンプレックスアプローチよりも遅いと主張されることがあることに注意してください。 (これが、ほとんどのプロのライブラリcplexが内点法アルゴリズムを使用する理由です)、質問は少なくとも暗黙的に大規模な問題についてです。また、私が使用する内点ソルバーはスパース行列を完全に処理するため、LARSに大きなパフォーマンスギャップが生じるとは思わないことに注意してください(LARSを使用する最初の動機は、当時の多くの一般的なLPソルバーがスパース行列をうまく処理できず、これらはLASSO問題の特徴的な機能です)。

内部ポイントアルゴリズムの(非常に)優れたオープンソース実装はipoptCOIN-ORライブラリ内にあります。私が使用するもう1つの理由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

次に、rootとして、Rdoで(デフォルトでsvnsubversionファイルをコピーしたと仮定~/します):

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
  • 新しい観察結果が病理学的に影響を与えない場合、たとえば、既存のデータを生成した確率的プロセスと一致する場合。
  • 更新のサイズが既存のデータのサイズに比べて小さい場合。

p+1ββ00p

@aix:なげなわパス全体を更新しますか、それともソリ​​ューションのみを更新しますか?(つまり、スパースペナルティは修正されていますか?)。
user603

λ
β^lasso=argminβ{12i=1N(yiβ0j=1pxijβj)2+λj=1p|βj|}

β

1
ソースコードを編集することなくこれを実行できるライブラリを知っていますか?
user2763361 14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.