জেনেরিক অপ্টিমাইজার ব্যবহার করে গ্ল্যামনেট লিনিয়ার রিগ্রেশনের ফলাফলগুলি প্রতিরূপ করা


10

শিরোনাম অনুসারে, আমি লাইব্রেরি থেকে LBFGS অপ্টিমাইজার ব্যবহার করে গ্ল্যামনেট লিনিয়ার থেকে ফলাফলগুলি প্রতিলিপি করার চেষ্টা করছি lbfgs। এই অপটিমাইজারটি ততক্ষণ আমাদের বিচ্ছিন্নতা সম্পর্কে চিন্তা না করে একটি এল 1 নিয়ন্ত্রক পদ যুক্ত করতে দেয়, যতক্ষণ না আমাদের উদ্দেশ্যমূলক ফাংশন (এল 1 নিয়ন্ত্রক শব্দটি ব্যতীত) উত্তল থাকে।

মধ্যে ইলাস্টিক নেট রৈখিক রিগ্রেশনের সমস্যা glmnet কাগজ দেওয়া হয় যেখানে এক্স \ {আর} ^ {n \ বার p the হ'ল নকশা ম্যাট্রিক্স, y \ in th mathbb {R ^ ^ p পর্যবেক্ষণের ভেক্টর, [0,1] এর মধ্যে the আলফা the ইলাস্টিক নেট প্যারামিটার এবং \ ল্যাম্বদা> 0 হ'ল নিয়মিতকরণ প্যারামিটার। অপারেটর \ ভার্ট এক্স \ ভার্ট_পি সাধারণ এলপি আদর্শকে বোঝায়।

minβRp12nβ0+Xβy22+αλβ1+12(1α)λβ22
XRn×pyRpα[0,1]λ>0xp

নীচের কোডটি ফাংশনটি সংজ্ঞায়িত করে এবং তারপরে ফলাফলগুলি তুলনা করার জন্য একটি পরীক্ষা অন্তর্ভুক্ত করে। যেমন আপনি দেখতে পাচ্ছেন, ফলাফলগুলি গ্রহণযোগ্য হয় alpha = 1তবে এর মানগুলি যখন বন্ধ হয় ততই নিম্নরূপ প্লট দেখায় alpha < 1.ত্রুটি আরও খারাপ হয় ("তুলনা মেট্রিক" গ্ল্যামনেটের প্যারামিটার অনুমানগুলির মধ্যে গড় ইউক্লিডিয়ান দূরত্ব এবং প্রদত্ত নিয়মিতকরণের পথে lbfgs)।alpha = 1alpha = 0

এখানে চিত্র বর্ণনা লিখুন

ঠিক আছে, তাই এখানে কোড। আমি যেখানেই সম্ভব মন্তব্যগুলি যুক্ত করেছি। আমার প্রশ্ন হ'ল কেন আমার ফলাফলগুলির glmnetমানগুলির চেয়ে আলাদা alpha < 1? এটি স্পষ্টভাবে এল 2 নিয়মিতকরণ শব্দটির সাথে করতে হবে, তবে যতদূর আমি বলতে পারি, আমি এই শব্দটি কাগজ অনুসারে কার্যকর করেছি। কোন সাহায্যের অনেক প্রশংসা হবে!

library(lbfgs)
linreg_lbfgs <- function(X, y, alpha = 1, scale = TRUE, lambda) {
  p <- ncol(X) + 1; n <- nrow(X); nlambda <- length(lambda)

  # Scale design matrix
  if (scale) {
    means <- colMeans(X)
    sds <- apply(X, 2, sd)
    sX <- (X - tcrossprod(rep(1,n), means) ) / tcrossprod(rep(1,n), sds)
  } else {
    means <- rep(0,p-1)
    sds <- rep(1,p-1)
    sX <- X
  }
  X_ <- cbind(1, sX)

  # loss function for ridge regression (Sum of squared errors plus l2 penalty)
  SSE <- function(Beta, X, y, lambda0, alpha) {
    1/2 * (sum((X%*%Beta - y)^2) / length(y)) +
      1/2 * (1 - alpha) * lambda0 * sum(Beta[2:length(Beta)]^2) 
                    # l2 regularization (note intercept is excluded)
  }

  # loss function gradient
  SSE_gr <- function(Beta, X, y, lambda0, alpha) {
    colSums(tcrossprod(X%*%Beta - y, rep(1,ncol(X))) *X) / length(y) + # SSE grad
  (1-alpha) * lambda0 * c(0, Beta[2:length(Beta)]) # l2 reg grad
  }

  # matrix of parameters
  Betamat_scaled <- matrix(nrow=p, ncol = nlambda)

  # initial value for Beta
  Beta_init <- c(mean(y), rep(0,p-1)) 

  # parameter estimate for max lambda
  Betamat_scaled[,1] <- lbfgs(call_eval = SSE, call_grad = SSE_gr, vars = Beta_init, 
                              X = X_, y = y, lambda0 = lambda[2], alpha = alpha,
                              orthantwise_c = alpha*lambda[2], orthantwise_start = 1, 
                              invisible = TRUE)$par

  # parameter estimates for rest of lambdas (using warm starts)
  if (nlambda > 1) {
    for (j in 2:nlambda) {
      Betamat_scaled[,j] <- lbfgs(call_eval = SSE, call_grad = SSE_gr, vars = Betamat_scaled[,j-1], 
                                  X = X_, y = y, lambda0 = lambda[j], alpha = alpha,
                                  orthantwise_c = alpha*lambda[j], orthantwise_start = 1, 
                                  invisible = TRUE)$par
    }
  }

  # rescale Betas if required
  if (scale) {
    Betamat <- rbind(Betamat_scaled[1,] -
colSums(Betamat_scaled[-1,]*tcrossprod(means, rep(1,nlambda)) / tcrossprod(sds, rep(1,nlambda)) ), Betamat_scaled[-1,] / tcrossprod(sds, rep(1,nlambda)) )
  } else {
    Betamat <- Betamat_scaled
  }
  colnames(Betamat) <- lambda
  return (Betamat)
}

# CODE FOR TESTING
# simulate some linear regression data
n <- 100
p <- 5
X <- matrix(rnorm(n*p),n,p)
true_Beta <- sample(seq(0,9),p+1,replace = TRUE)
y <- drop(cbind(1,X) %*% true_Beta)

library(glmnet)

# function to compare glmnet vs lbfgs for a given alpha
glmnet_compare <- function(X, y, alpha) {
  m_glmnet <- glmnet(X, y, nlambda = 5, lambda.min.ratio = 1e-4, alpha = alpha)
  Beta1 <- coef(m_glmnet)
  Beta2 <- linreg_lbfgs(X, y, alpha = alpha, scale = TRUE, lambda = m_glmnet$lambda)
  # mean Euclidean distance between glmnet and lbfgs results
  mean(apply (Beta1 - Beta2, 2, function(x) sqrt(sum(x^2))) ) 
}

# compare results
alpha_seq <- seq(0,1,0.2)
plot(alpha_seq, sapply(alpha_seq, function(alpha) glmnet_compare(X,y,alpha)), type = "l", ylab = "Comparison metric")

@ hxd1011 আমি আপনার কোডটি চেষ্টা করেছিলাম, এখানে কয়েকটি পরীক্ষা রয়েছে (গ্ল্যামনেটের কাঠামোর সাথে মেলে আমি কিছু ছোটখাটো টুইট করেছি - দ্রষ্টব্য যে আমরা বিরতি শর্তটি নিয়মিত করি না, এবং ক্ষতির ফাংশনগুলি অবশ্যই মাপা উচিত)। এটি এর জন্য alpha = 0, তবে আপনি যে কোনও চেষ্টা করতে পারেন alpha- ফলাফলের সাথে মেলে না।

rm(list=ls())
set.seed(0)
# simulate some linear regression data
n <- 1e3
p <- 20
x <- matrix(rnorm(n*p),n,p)
true_Beta <- sample(seq(0,9),p+1,replace = TRUE)
y <- drop(cbind(1,x) %*% true_Beta)

library(glmnet)
alpha = 0

m_glmnet = glmnet(x, y, alpha = alpha, nlambda = 5)

# linear regression loss and gradient
lr_loss<-function(w,lambda1,lambda2){
  e=cbind(1,x) %*% w -y
  v= 1/(2*n) * (t(e) %*% e) + lambda1 * sum(abs(w[2:(p+1)])) + lambda2/2 * crossprod(w[2:(p+1)])
  return(as.numeric(v))
}

lr_loss_gr<-function(w,lambda1,lambda2){
  e=cbind(1,x) %*% w -y
  v= 1/n * (t(cbind(1,x)) %*% e) + c(0, lambda1*sign(w[2:(p+1)]) + lambda2*w[2:(p+1)])
  return(as.numeric(v))
}

outmat <- do.call(cbind, lapply(m_glmnet$lambda, function(lambda) 
  optim(rnorm(p+1),lr_loss,lr_loss_gr,lambda1=alpha*lambda,lambda2=(1-alpha)*lambda,method="L-BFGS")$par
))

glmnet_coef <- coef(m_glmnet)
apply(outmat - glmnet_coef, 2, function(x) sqrt(sum(x^2)))

আমি নিশ্চিত না যে আপনার প্রশ্নটি বিষয়টিতে রয়েছে (আমি মনে করি এটি হতে পারে যেমন এটি অন্তর্নিহিত অপ্টিমাইজেশান কৌশল সম্পর্কে) এবং আমি এখন আপনার কোডটি সত্যিই পরীক্ষা করতে পারি না, তবে সমতা সম্পর্কিত যুক্তি lbfgsসম্পর্কে একটি বিষয় উত্থাপন করি । orthantwise_cglmnet
ফায়ারব্যাগ

সমস্যাটি আসলেই নয় lbfgsএবং orthantwise_cযেমনটি alpha = 1সমাধানটি ঠিক ঠিক তেমনটি একই সাথে ঘটে glmnet। এটি জিনিসগুলির এল 2 নিয়মিতকরণের সাথে সম্পর্কিত হয় যখন কখন alpha < 1। আমি সংজ্ঞা পরিবর্তনের কোন ধরণের উপার্জন মনে SSEএবং SSE_grএটা ঠিক করা উচিত, কিন্তু আমি নিশ্চিত কি পরিবর্তন হওয়া উচিত নই - যতদূর আমি জানি, যারা ফাংশন ঠিক glmnet কাগজ বর্ণনা অনুযায়ী সংজ্ঞায়িত করা হয়।
ব্যবহারকারী3294195

এটি স্ট্যাকওভারফ্লো, প্রোগ্রামিং প্রশ্ন আরও বেশি হতে পারে।
ম্যাথু গুন

3
আমি ভেবেছিলাম কোডটি না হয়ে বরং অপ্টিমাইজেশন এবং নিয়মিতকরণের সাথে এর আরও অনেক কিছু আছে, তাই আমি এখানে এটি পোস্ট করেছি posted
ব্যবহারকারী3294195

1
খাঁটি অপ্টিমাইজেশান প্রশ্নের জন্য, scicomp.stackexchange.com এছাড়াও একটি বিকল্প। আমি নিশ্চিত নই যে ভাষা নির্দিষ্ট প্রশ্ন সেখানে আছে কিনা? (যেমন "
আরে এটি করুন

উত্তর:


11

tl; ডাঃ সংস্করণ:

উদ্দেশ্যটিতে স্পষ্টত একটি স্কেলিং ফ্যাক্টর রয়েছে , যেখানে হল নমুনা স্ট্যান্ডার্ড বিচ্যুতি।s^=sd(y)sd(y)

দীর্ঘ সংস্করণ

আপনি যদি গ্ল্যামনেট ডকুমেন্টেশনের সূক্ষ্ম মুদ্রণটি পড়েন তবে আপনি দেখতে পাবেন:

লক্ষ্য করুন যে '"গাউসিয়ান" "এর জন্য উদ্দেশ্যগত কার্যটি

               1/2  RSS/nobs + lambda*penalty,                  

এবং অন্যান্য মডেলের জন্য এটি

               -loglik/nobs + lambda*penalty.                   

এও নোট করুন যে '' গাউসিয়ান '' এর জন্য, 'গ্ল্যামনেট' y এর ল্যাম্বদা ক্রম গণনা করার আগে ইউনিট বৈকল্পিককরণের মান নির্ধারণ করে (এবং তারপরে ফলাফলটি সহগকে অস্তিত্বহীন করে); আপনি যদি অন্য সফ্টওয়্যারগুলির সাথে ফলাফলগুলি পুনরুত্পাদন / তুলনা করতে চান তবে সেরা মানের একটি সরবরাহ করুন।

এখন এর অর্থ হ'ল উদ্দেশ্যটি হ'ল এবং সেই গ্ল্যামনেট রিপোর্ট করে টিলডে ।

12ny/s^Xβ22+λαβ1+λ(1α)β22,
β~=s^β

এখন, যখন আপনি একটি খাঁটি লাসো ব্যবহার করছেন ( ), তখন গ্ল্যামনেটের un আনস্ট্যান্ডার্ডাইজেশন মানে উত্তরগুলি সমান। অন্যদিকে, খাঁটি রিজের সাহায্যে পাথের সাথে একমত হওয়ার জন্য আপনাকে by দ্বারা factor পেনাল্টিটি স্কেল করতে হবে , কারণ factor অতিরিক্ত ফ্যাক্টরটি বর্গ থেকে বেরিয়ে যায় মধ্যে শাস্তি। মধ্যবর্তী , আউটপুট পুনরুত্পাদন করার জন্য সহগের দণ্ডের স্কেল করার সহজ উপায় নেই ।α=1β~1/s^glmnets^2αglmnets

আমি যখন একক ইউনিটের বৈকল্পিকতাটি অর্জন করতে স্কেল করব, তখন আমি এটি সন্ধান করব yএখানে চিত্র বর্ণনা লিখুন

যা এখনও ঠিক মেলে না। এটি দুটি জিনিসের কারণে বলে মনে হচ্ছে:

  1. উষ্ণ-প্রারম্ভিক চক্রীয় স্থানাঙ্ক বংশোদ্ভূত বংশদ্ভুত অ্যালগরিদম পুরোপুরি অভিযোজিত হওয়ার জন্য ল্যাম্বদা ক্রমটি খুব সংক্ষিপ্ত হতে পারে।
  2. আপনার ডেটাতে কোনও ত্রুটি শর্ত নেই ( রিগ্রেশনটির হ'ল)।R2
  3. নোটটিতে কোডের মধ্যে একটি বাগ রয়েছে যাতে এটি lambda[2]প্রাথমিক ফিটের জন্য গ্রহণ করে তবে এটি হওয়া উচিত lambda[1]

আমি একবার আইটেমগুলি ৩-৩টি সংশোধন করে নিলে আমি নিম্নলিখিত ফলাফলটি পাই (যদিও এলোমেলো বীজের উপর নির্ভরশীল ওয়াইএমএমভি):

এখানে চিত্র বর্ণনা লিখুন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.