การอัพเดตเชือกให้พอดีกับข้อสังเกตใหม่


12

ฉันเหมาะสมกับการถดถอยเชิงเส้น L1-normalized กับชุดข้อมูลที่มีขนาดใหญ่มาก (ที่มี n >> p.) ตัวแปรเป็นที่รู้จักล่วงหน้า แต่การสังเกตการณ์มาถึงกลุ่มเล็ก ๆ ฉันต้องการที่จะรักษาเชือกที่พอดีหลังจากแต่ละก้อน

เห็นได้ชัดว่าฉันสามารถปรับโมเดลทั้งหมดได้อีกครั้งหลังจากเห็นการสังเกตชุดใหม่แต่ละชุด อย่างไรก็ตามสิ่งนี้จะไม่มีประสิทธิภาพพอสมควรเนื่องจากมีข้อมูลจำนวนมาก จำนวนข้อมูลใหม่ที่มาถึงในแต่ละขั้นตอนมีขนาดเล็กมากและความพอดีไม่น่าจะเปลี่ยนแปลงระหว่างขั้นตอนมากนัก

มีอะไรที่ฉันสามารถทำได้เพื่อลดภาระการคำนวณโดยรวมหรือไม่?

ฉันกำลังดูอัลกอริทึม LARS ของ Efron et al. แต่ยินดีที่จะพิจารณาวิธีการติดตั้งแบบอื่น ๆ ถ้ามันสามารถทำให้ "warm-start" ตามที่อธิบายไว้ข้างต้น

หมายเหตุ:

  1. ฉันกำลังมองหาอัลกอริทึมเป็นหลัก แต่ตัวชี้ไปยังชุดซอฟต์แวร์ที่มีอยู่ซึ่งสามารถทำได้สิ่งนี้อาจพิสูจน์ได้ด้วย
  2. นอกเหนือจากวิถีบ่วงบาศปัจจุบันอัลกอริธึมก็แน่นอนยินดีที่จะรักษาสถานะอื่น

แบรดลีย์เอฟรอน, เทรเวอร์ Hastie เลน Johnstone และโรเบิร์ตทิบชิรา นี , น้อยมุมถดถอย , พงศาวดารของสถิติ (ด้วยการอภิปราย) (2004) 32 (2), 407--499

คำตอบ:


7

Lasso ติดตั้งผ่าน LARS (กระบวนการวนซ้ำที่เริ่มต้นที่การประมาณค่าเริ่มต้น ) โดยค่าเริ่มต้นแต่คุณสามารถเปลี่ยนแปลงสิ่งนี้ได้ในการนำไปใช้งานส่วนใหญ่ (และแทนที่ด้วยดีที่สุดคุณมีอยู่แล้ว) ที่อยู่ใกล้คือการที่มีขนาดเล็กจำนวน LARS ซ้ำคุณจะต้องขั้นตอนที่จะได้รับ *β0β0=0pβoldβoldβnewβnew

แก้ไข:

เนื่องจากความคิดเห็นจาก user2763361ฉันเพิ่มรายละเอียดเพิ่มเติมในคำตอบเดิมของฉัน

จากความคิดเห็นด้านล่างฉันรวบรวมว่าผู้ใช้ 2763361 แนะนำให้เติมคำตอบเดิมของฉันให้กลายเป็นคำตอบที่สามารถใช้โดยตรง (นอกชั้นวาง) ในขณะที่ยังมีประสิทธิภาพมาก

ในการทำส่วนแรกฉันจะอธิบายวิธีแก้ปัญหาที่ฉันเสนอเป็นขั้นเป็นตอนในตัวอย่างของเล่น เพื่อให้เป็นไปตามส่วนที่สองฉันจะใช้ตัวแก้จุดภายในที่มีคุณภาพสูง นี่เป็นเพราะมันง่ายกว่าที่จะได้รับการใช้งานที่มีประสิทธิภาพสูงของโซลูชันที่ฉันเสนอโดยใช้ไลบรารีที่สามารถแก้ปัญหา lasso โดยวิธีจุดภายในแทนที่จะพยายามแฮ็ค LARS หรืออัลกอริธึมเริมเพื่อเริ่มการปรับให้เหมาะสม จุดเริ่มต้นมาตรฐาน (แม้ว่าสถานที่ที่สองนั้นเป็นไปได้เช่นกัน)

โปรดทราบว่าบางครั้งมีการอ้างสิทธิ์ (ในหนังสือเล่มเก่า) ว่าแนวทางการตกแต่งภายในเพื่อแก้ปัญหาโปรแกรมเชิงเส้นช้ากว่าวิธีแบบง่าย ๆ และอาจเป็นจริงมานานแล้ว แต่โดยทั่วไปแล้วมันไม่เป็นความจริงในปัจจุบัน (นี่คือสาเหตุที่ห้องสมุดมืออาชีพส่วนใหญ่ชอบcplexใช้อัลกอริธึมภายในจุด) และคำถามก็เป็นอย่างน้อยโดยปริยายเกี่ยวกับปัญหาขนาดใหญ่ โปรดทราบว่าตัวแก้จุดภายในที่ฉันใช้จัดการเมทริกซ์กระจัดกระจายอย่างสมบูรณ์ดังนั้นฉันจึงไม่คิดว่าจะมีช่องว่างประสิทธิภาพขนาดใหญ่กับ LARS (แรงจูงใจดั้งเดิมสำหรับการใช้ LARS คือตัวแก้ LP ยอดนิยมจำนวนมากในเวลานั้น สิ่งเหล่านี้เป็นคุณลักษณะเฉพาะของปัญหา LASSO)

การใช้โอเพ่นซอร์สอัลกอริธึมที่ดีมาก (ภายในipopt) ในCOIN-ORห้องสมุด เหตุผลที่ผมจะใช้อีกipoptคือว่ามันมีมีอินเตอร์เฟซ ipoptrR, คุณจะพบคู่มือการติดตั้งครบถ้วนสมบูรณ์มากขึ้นที่นี่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 (ฉันถือว่าsvnได้คัดลอกไฟล์ subversion ไป~/แล้วตามค่าเริ่มต้น)

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 (ตัวแทน (0, m), rep (1, m))

    ไปยังเวกเตอร์ของโซลูชันที่คุณพบก่อนหน้านี้ (ก่อนเพิ่มข้อมูลใหม่) ตรรกะที่นี่มีดังนี้ แสดงเวกเตอร์ใหม่ของค่าสัมประสิทธิ์ (ค่าที่สอดคล้องกับชุดข้อมูลหลังการอัปเดต) และค่าเดิม นอกจากนี้ยังระบุว่าเวกเตอร์ในรหัสด้านบน (นี่เป็นการเริ่มต้นตามปกติสำหรับวิธีการจุดภายใน) ถ้าอย่างนั้นความคิดก็คือถ้า:βnewβoldβinitx0

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

แล้วหนึ่งจะได้รับได้เร็วขึ้นมากโดยเริ่มจากจุดภายใน มากกว่าไร้เดียงสา{} อัตราขยายจะมีความสำคัญยิ่งขึ้นเมื่อขนาดของชุดข้อมูล (และ ) มีขนาดใหญ่ขึ้นβnewβoldβinitnp

สำหรับเงื่อนไขภายใต้ความไม่เสมอภาค (1) ถือเป็น:

  • เมื่อมีขนาดใหญ่เมื่อเทียบกับ (นี่คือกรณีปกติเมื่อจำนวนตัวแปรการออกแบบมีขนาดใหญ่เมื่อเทียบกับจำนวนการสังเกต)λ|βOLS|1pn
  • เมื่อการสังเกตใหม่ไม่ได้มีอิทธิพลต่อพยาธิวิทยาเช่นตัวอย่างเมื่อสิ่งเหล่านั้นสอดคล้องกับกระบวนการสุ่มที่สร้างข้อมูลที่มีอยู่
  • เมื่อขนาดของการอัพเดทมีขนาดเล็กเมื่อเทียบกับขนาดของข้อมูลที่มีอยู่

ขอบคุณ แต่ฉันเกรงว่าฉันจะไม่ทำตาม LARS ผลิตเส้นทางค่เชิงเส้น (ตรงกับคะแนนสำหรับมุมที่น้อยและจุดอาจจะมากขึ้นสำหรับเชือก.) แต่ละจุดมีชุดของตัวเองของ\เมื่อเราเพิ่มการสังเกตเพิ่มเติม betas ทั้งหมดสามารถย้าย (ยกเว้นซึ่งเป็นเสมอ) โปรดขยายคำตอบของคุณได้ไหม? ขอบคุณ p+1ββ00p
NPE

@aix: คุณต้องการอัปเดตเส้นทางบ่วงบาศทั้งหมดหรือเพียงแค่แก้ปัญหาหรือไม่ (เช่นการลงโทษ sparsity คงที่?)
user603

ฉันต้องการปรับปรุงเส้นทางทั้งหมด อย่างไรก็ตามหากมีวิธีที่ดีที่จะทำเช่นนั้นสำหรับโทษที่แน่นอน (ในสูตรด้านล่าง) นี่อาจเป็นการเริ่มต้นที่ดี นี่คือสิ่งที่คุณเสนอหรือไม่ λ
β^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.