r语言 - 最小化具有两个变量的函数



我想最小化一个有两个变量的函数。

首先,我做了一个函数(rba),在函数(kvasum)中需要它,我需要最小化。要最小化的值是 rba 的一部分。

# Data
vpk = data.frame(V1 =c(3650000000, 19233, 2211.2, 479.47, 168.46, 83.447, 52.349, 38.738,
                     32.34, 29.588), V2 = 1:10)
n = nrow(vpk)
# functions to minimize 
# This function returns a vector with 10 values
rba = function(par){
  v <- matrix(ncol = 1, nrow = 10)
  for (p in 1:10){
    k<- ifelse (par[1] < 1-1/p && par[1]>0 && p > par[2] && 
par[2]>0 && par[2]<2, par[2]*p,
                    ifelse(par[1] < 1-1/par[2] && par[1] > 0 && 
p < par[2] && par[2]>0 && par[2]<2, -1+(par[1]+1/par[2]),
                           ifelse(par[1] > (1 - 1 / max(p,par[2])) && 
par[2]>0 && par[2]<2, -1+p, "error")))
    v[p] <- k 
  }
  return(v)
}
# This function uses the function rba, and returns a value
kvasum = function(par){
  sum( (log(vpk$V1)/log(1/n) - rba(par) )^2)
}
# what I would I to do is to find par[1] and par[2] such that kvasum is minimized
m1 = optim(par=c(0.1,0.4),kvasum, lower=0)

我尝试使用optim函数,但无法使其工作。我得到了一个非数字参数,并尝试了我能想到的一切。任何帮助,不胜感激。

您的整个过程存在一些问题,会导致麻烦。

首先,正如@user227710评论中提到的,您应该&&替换为 & .这些有不同的含义。

现在是优化器

看起来您想对参数设置限制(即所谓的框约束)。为了执行此操作并因此使用 lower 参数,您需要使用 L-BFGS-B 方法。当你使用它时,你还需要指定upper参数。

收到的错误,您会收到它,因为您的 ifelse 语句仅在值大致介于 0 和 1 之间时才有效。否则,k 变量获取值 error(如果 ifelse 语句中的所有条件均为 FALSE,则返回的值),这就是您获得

Error in log(vpk$V1)/log(1/n) - rba(par) : 
  non-numeric argument to binary operator

错误。

因此,如果您相应地指定您的框约束(或者查看您的 ifelse 语句,因为您可能编码错误),这似乎可以完美地工作:

# Data
vpk = data.frame(V1 =c(3650000000, 19233, 2211.2, 479.47, 168.46, 83.447, 52.349, 38.738,
                       32.34, 29.588), V2 = 1:10)
n = nrow(vpk)
# functions to minimize 
# This function returns a vector with 10 values
rba = function(par){
  v <- matrix(ncol = 1, nrow = 10)
  for (p in 1:10){
    k<- ifelse (par[1] < 1-1/p & par[1]>0 & p > par[2] & 
                  par[2]>0 & par[2]<2, par[2]*p,
                ifelse(par[1] < 1-1/par[2] & par[1] > 0 & 
                         p < par[2] & par[2]>0 & par[2]<2, -1+(par[1]+1/par[2]),
                       ifelse(par[1] > (1 - 1 / max(p,par[2])) & 
                                par[2]>0 & par[2]<2, -1+p, "error")))
    #I am adding a line here so that you know why the optim failed
    if(k=='error') stop('your ifelse function returned an error')
    v[p] <- k 
  }
  return(v)
}
# This function uses the function rba, and returns a value
kvasum = function(par){
  sum( (log(vpk$V1)/log(1/n) - rba(par) )^2)
}
# what I would I to do is to find par[1] and par[2] such that kvasum is minimized
m1 = optim(par=c(0.1,0.4),kvasum, method='L-BFGS-B', lower= c(0.1,0.1), upper=c(0.9,0.9))

输出:

> m1
$par
[1] 0.1 0.1
$value
[1] 171.5774
$counts
function gradient 
       2        2 
$convergence
[1] 0
$message
[1] "CONVERGENCE: NORM OF PROJECTED GRADIENT <= PGTOL"

最新更新