नई टिप्पणियों के साथ लसो फिट को अद्यतन करना


12

मैं एक बहुत बड़े डेटासेट (n >> p।) के साथ एक L1- नियमित रूप से रैखिक प्रतिगमन फिटिंग कर रहा हूं। चर पहले से ज्ञात हैं, लेकिन अवलोकन छोटे विखंडों में आते हैं। मैं प्रत्येक चंक के बाद लसो को फिट बनाए रखना चाहूंगा।

मैं स्पष्ट रूप से टिप्पणियों के प्रत्येक नए सेट को देखने के बाद पूरे मॉडल को फिर से फिट कर सकता हूं। यह, हालांकि, यह काफी अक्षम होगा कि बहुत अधिक डेटा है। प्रत्येक चरण पर आने वाले नए डेटा की मात्रा बहुत कम है, और फिट कदमों के बीच बहुत कुछ बदलने की संभावना नहीं है।

क्या समग्र कम्प्यूटेशनल बोझ को कम करने के लिए मैं कुछ भी कर सकता हूं?

मैं Efron एट अल के लार्स एल्गोरिथ्म को देख रहा था, लेकिन किसी भी अन्य फिटिंग विधि पर विचार करने में खुशी होगी अगर इसे ऊपर वर्णित तरीके से "वार्म-स्टार्ट" किया जा सकता है।

टिप्पणियाँ:

  1. मैं मुख्य रूप से एक एल्गोरिथ्म की तलाश कर रहा हूं, लेकिन मौजूदा सॉफ्टवेयर पैकेजों की ओर इशारा करता है जो ऐसा कर सकते हैं जो व्यावहारिक भी साबित हो सकते हैं।
  2. वर्तमान लैस्सो प्रक्षेपवक्र के अलावा, एल्गोरिथ्म निश्चित रूप से अन्य राज्य रखने के लिए स्वागत है।

ब्रैडली एफ्रॉन, ट्रेवर हस्ती, इयान जॉनस्टोन और रॉबर्ट टिब्शिरानी, लिस्ट एंगल रिग्रेशन , एनल्स ऑफ स्टैटिस्टिक्स (चर्चा के साथ) (2004) 32 (2), 407--499।

जवाबों:


7

लसो को लार्स (एक पुनरावृत्ति प्रक्रिया के माध्यम से फिट किया जाता है, जो कुछ प्रारंभिक अनुमान पर शुरू होता है )। डिफ़ॉल्ट रूप से लेकिन आप इसे अधिकांश कार्यान्वयन में बदल सकते हैं (और इसे इष्टतम आपके पास पहले से है) द्वारा प्रतिस्थापित कर सकते हैं । निकटतम के लिए है , छोटे लार्स की संख्या यात्रा आप कदम करना होगा करने के लिए ।β0β0=0pβoldβoldβnewβnew

संपादित करें:

टिप्पणियों के कारण user2763361मैं अपने मूल उत्तर में अधिक विवरण जोड़ देता हूं।

नीचे दी गई टिप्पणियों से मैं यह इकट्ठा करता हूं कि user2763361 मेरे मूल उत्तर को एक में बदलने के लिए पूरक करने का सुझाव देता है जिसे सीधे (अलमारियों के बाहर) भी उपयोग किया जा सकता है, जबकि यह बहुत कुशल भी है।

पहला भाग करने के लिए, मैं उस समाधान का वर्णन करूँगा जो मैंने एक खिलौना उदाहरण पर कदम से कदम रखा। दूसरे भाग को संतुष्ट करने के लिए, मैं हाल ही में उच्च गुणवत्ता वाले इंटीरियर पॉइंट सॉल्वर का उपयोग करूँगा। ऐसा इसलिए है, क्योंकि मैं एक पुस्तकालय का उपयोग करके प्रस्तावित समाधान का उच्च निष्पादन कार्यान्वयन प्राप्त करना आसान है जो लारसो या सिम्प्लेक्स एल्गोरिदम को हैक करने की कोशिश कर रहा है बजाय गैर से अनुकूलन शुरू करने के लिए लार्स या सिम्प्लेक्स एल्गोरिथ्म को हैक करने की कोशिश कर सकता है। मानक प्रारंभिक बिंदु (हालांकि वह दूसरा स्थान भी संभव है)।

ध्यान दें कि कभी-कभी यह दावा किया जाता है (पुरानी किताबों में) कि रैखिक कार्यक्रमों को हल करने के लिए आंतरिक बिंदु दृष्टिकोण सरल दृष्टिकोण की तुलना में धीमा है और यह बहुत पहले सच हो सकता है, लेकिन यह आमतौर पर आज सच नहीं है और निश्चित रूप से बड़े पैमाने पर समस्याओं के लिए सच नहीं है (यही कारण है कि अधिकांश पेशेवर पुस्तकालय cplexआंतरिक बिंदु एल्गोरिथ्म का उपयोग करते हैं) और सवाल कम से कम बड़े पैमाने पर समस्याओं के बारे में है। यह भी ध्यान दें कि मैं जिस आंतरिक बिंदु सॉल्वर का उपयोग करता हूं, वह पूरी तरह से विरल मैट्रिस का उपयोग करता है, इसलिए मुझे नहीं लगता है कि लार्स के साथ एक बड़ा प्रदर्शन अंतराल होगा (लार्स का उपयोग करने के लिए एक मूल प्रेरणा यह थी कि उस समय कई लोकप्रिय एलपी सॉल्वर विरल मैट्रीस को अच्छी तरह से नहीं बचा रहे थे और ये LASSO समस्या की एक विशेषता है)।

लाइब्रेरी ipoptमें आंतरिक बिंदु एल्गोरिथम का ए (बहुत) अच्छा खुला स्रोत कार्यान्वयन है COIN-OR। एक अन्य कारण मैं का उपयोग किया जाएगा ipopt, यह एक आर इंटरफ़ेस है है कि 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")

यहां से, मैं एक छोटा सा उदाहरण दे रहा हूं (ज्यादातर अपने आवरण के हिस्से के रूप में जेलेर यपमा द्वारा दिए गए खिलौना उदाहरण 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 (प्रतिनिधि (0, m), प्रतिनिधि (1, m))

    समाधान का वेक्टर आपको पहले मिला (नए डेटा को जोड़ने से पहले)। यहाँ तर्क इस प्रकार है। निरूपित गुणांकों के नए वेक्टर (लोगों को अद्यतन करने के बाद डेटा सेट करने के लिए इसी) और मूल वाले। इसके अलावा ऊपर दिए गए कोड में वेक्टर को (यह आंतरिक बिंदु विधि के लिए सामान्य शुरुआत है)। तब विचार यह है कि यदि:βnewβoldβinitx0

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

उसके बाद, कोई व्यक्ति बजाय से आंतरिक बिंदु प्रारंभ करके बहुत तेज़ी से प्राप्त कर सकता है । डेटा सेट ( और ) के आयाम बड़े होने पर लाभ अधिक महत्वपूर्ण होगा ।βnewβoldβinitnp

जिन परिस्थितियों में असमानता (1) है, वे इस प्रकार हैं:

  • जब की तुलना में बड़ा है (यह आमतौर पर तब होता है जब , की तुलना में डिजाइन चर की संख्या बड़ी है , टिप्पणियों की संख्या)λ|βOLS|1pn
  • जब नई प्रेक्षण पथिक रूप से प्रभावशाली नहीं होते हैं, उदाहरण के लिए जब वे स्टोकेस्टिक प्रक्रिया के अनुरूप होते हैं जिसने मौजूदा डेटा उत्पन्न किया है।
  • जब अपडेट का आकार मौजूदा डेटा के आकार के सापेक्ष छोटा हो।

धन्यवाद, लेकिन मुझे डर है कि मैं पीछा नहीं करता। LARS एक टुकड़ा-रेखीय पथ का निर्माण करता है ( कम से कम कोणों के लिए बिल्कुल अंक और लासो के लिए संभवतः अधिक बिंदुओं के साथ।) प्रत्येक बिंदु का अपना स्वयं का सेट है । जब हम और अधिक टिप्पणियों को जोड़ते हैं, तो सभी चल सकते हैं (सिवाय , जो हमेशा ।) कृपया अपने उत्तर पर विस्तार कर सकते हैं? धन्यवाद। p+1ββ00p
NPE

@ ऐक्स: क्या आप संपूर्ण लस्सो पथ या सिर्फ समाधान का अद्यतन करना चाहते हैं? (यानी विरलता जुर्माना तय है?)।
user603

मैं पूरे रास्ते को अपडेट करना चाह रहा था। हालांकि, अगर एक निश्चित दंड ( नीचे सूत्र में ) के लिए ऐसा करने का एक अच्छा तरीका है, तो यह एक अच्छी शुरुआत हो सकती है। क्या यह आप प्रस्ताव कर रहे हैं? λ
β^lasso=argminβ{12i=1N(yiβ0j=1pxijβj)2+λj=1p|βj|}
एनपीई

@aix। हां, यह सब आपके द्वारा उपयोग किए जाने वाले कार्यान्वयन और आपके लिए उपयोग की जाने वाली सुविधाओं पर निर्भर करता है। उदाहरण के लिए: यदि आपके पास एक अच्छे एलपी सॉल्वर तक पहुंच है, तो आप इसे पिछले के पुराने मानों के साथ खिला सकते हैं और यह 1-2 कदम नए समाधान के लिए बहुत कुशलता से ले जाएगा। आपको अपने विवरण में इन विवरणों को जोड़ना चाहिए। β
16:60 पर user603

1
कोई भी लाइब्रेरी जिसे आप जानते हैं कि स्रोत कोड को संपादित करने की आवश्यकता के बिना ऐसा कर सकते हैं?
user2763361
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.