R: Пакеты многовариантной оптимизации FAST?

Я ищу локальный минимум скалярной функции от 4 переменных, и у меня есть ограничения диапазона для переменных ("ограничения блока"). Для производной функции нет замкнутой формы, поэтому о методах, требующих аналитической производной функции, не может быть и речи. Я пробовал несколько вариантов и параметров управления с функцией optim , но все они кажутся очень медленными. В частности, кажется, что они проводят много времени между вызовами моей (определенной R) целевой функции, поэтому я знаю, что узким местом является не моя целевая функция, а «размышления» между вызовами моей целевой функции. Я посмотрел на представление задач CRAN для оптимизации и попробовал несколько из этих вариантов ( DEOptim из RcppDE и т. Д.), Но ни один из них не оказался подходящим. Я бы хотел попробовать пакет nloptr (оболочка R для библиотеки NLOPT), но он, похоже, недоступен для Windows.

Мне интересно, есть ли какие-нибудь хорошие, быстрые пакеты оптимизации, которые люди использовать то, что я могу пропустить? В идеале они должны быть в виде тонких оберток вокруг хороших библиотек C ++ / Fortran, чтобы код на чистом R был минимальным. (Хотя это не должно иметь значения, моя проблема оптимизации возникла при попытке подогнать 4-параметрическое распределение к набору значений путем минимизации определенной меры согласия).

В прошлом я обнаружил, что библиотеки оптимизации R работают довольно медленно, и закончился написанием тонкой оболочки R, вызывающей C ++ API коммерческой библиотеки оптимизации. Так обязательно ли лучшие библиотеки коммерческие?

ОБНОВЛЕНИЕ. Вот упрощенный пример кода, на который я смотрю:

###########
## given a set of values x and a cdf, calculate a measure of "misfit":
## smaller value is better fit
## x is assumed sorted in non-decr order;
Misfit <- function(x, cdf) {
  nevals <<- nevals + 1
  thinkSecs <<- thinkSecs + ( Sys.time() - snapTime)
  cat('S')
  if(nevals %% 20 == 0) cat('\n')
  L <- length(x)
  cdf_x <- pmax(0.0001, pmin(0.9999, cdf(x)))
  measure <- -L - (1/L) * sum( (2 * (1:L)-1 )* ( log( cdf_x ) + log( 1 - rev(cdf_x))))
  snapTime <<- Sys.time()
  cat('E')
  return(measure)  
}
## Given 3 parameters nu (degrees of freedom, or shape), 
## sigma (dispersion), gamma (skewness),
## returns the corresponding 4-parameter student-T cdf parametrized by these params
## (we restrict the location parameter mu to be 0).
skewtGen <- function( p ) {
  require(ghyp)
  pars = student.t( nu = p[1], mu = 0, sigma = p[2], gamma = p[3] )
  function(z) pghyp(z, pars)
}

## Fit using optim() and BFGS method
fit_BFGS <- function(x, init = c()) {
  x <- sort(x)
  nevals <<- 0
  objFun <- function(par) Misfit(x, skewtGen(par))
  snapTime <<- Sys.time() ## global time snap shot
  thinkSecs <<- 0 ## secs spent "thinking" between objFun calls
  tUser <- system.time(
              res <- optim(init, objFun,
                           lower = c(2.1, 0.1, -1), upper = c(15, 2, 1),
                           method = 'L-BFGS-B',
                           control = list(trace=2, factr = 1e12, pgtol = .01 )) )[1]
  cat('Total time = ', tUser, 
      ' secs, ObjFun Time Pct = ', 100*(1 - thinkSecs/tUser), '\n')
  cat('results:\n')
  print(res$par)
}

fit_DE <- function(x) {
  x <- sort(x)
  nevals <<- 0
  objFun <- function(par) Misfit(x, skewtGen(par))
  snapTime <<- Sys.time() ## global time snap shot
  thinkSecs <<- 0 ## secs spent "thinking" between objFun calls
  require(RcppDE)
  tUser <- system.time(
              res <- DEoptim(objFun,
                             lower = c(2.1, 0.1, -1),
                             upper = c(15, 2, 1) )) [1]
  cat('Total time = ',             tUser,
      ' secs, ObjFun Time Pct = ', 100*(1 - thinkSecs/tUser), '\n')
  cat('results:\n')
  print(res$par)
}

Давайте сгенерируем случайную выборку:

set.seed(1)
# generate 1000 standard-student-T points with nu = 4 (degrees of freedom)
x <- rt(1000,4)

Первое соответствие с использованием функции fit.tuv (для «T UniVariate») в ghyp - в нем используется метод максимизации ожидания максимального правдоподобия (EM). Это ужасно быстро!

require(ghyp)
> system.time( print(unlist( pars <- coef( fit.tuv(x, silent = TRUE) ))[c(2,4,5,6)]))
         nu          mu       sigma       gamma 
 3.16658356  0.11008948  1.56794166 -0.04734128 
   user  system elapsed 
   0.27    0.00    0.27 

Теперь я пытаюсь подобрать распределение по-другому: минимизируя показатель несоответствия, определенный выше, с использованием стандартной функции optim () в базе R. Обратите внимание, что в целом результаты не будут такими же. Я сделал это, чтобы сравнить эти два результата для целого класса ситуаций. Я использую приведенную выше оценку максимального правдоподобия в качестве отправной точки для этой оптимизации.

> fit_BFGS( x, init = c(pars$nu, pars$sigma, pars$gamma) )
N = 3, M = 5 machine precision = 2.22045e-16
....................
....................
.........
iterations 5
function evaluations 7
segments explored during Cauchy searches 7
BFGS updates skipped 0
active bounds at final generalized Cauchy point 0
norm of the final projected gradient 0.0492174
final function value 0.368136

final  value 0.368136 
converged
Total time =  41.02  secs, ObjFun Time Pct =  99.77084 
results:
[1] 3.2389296 1.5483393 0.1161706

Я также пытался использовать DEoptim () , но он работал слишком долго, и мне пришлось его убить. Как видно из результатов выше, 99,8% времени приходится на целевую функцию! Итак, Дирк и Майк были правы в своих комментариях ниже. Мне следовало более тщательно оценить время, потраченное на мою целевую функцию, а печатать точки - не лучшая идея! Также я подозреваю, что метод MLE (EM) очень быстр, потому что он использует аналитическую (замкнутую форму) для функции логарифмического правдоподобия.

7
задан Prasad Chalasani 17 February 2011 в 16:36
поделиться