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

首先,我创建了一个函数(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)


我试图使用优化函数,但无法使其正常工作。我得到了一个非数字参数,并且尝试了所有我能想到的。任何帮助表示赞赏。

最佳答案

您的整个过程中有一些问题会引起麻烦。

首先,如@ 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"

08-24 12:53
查看更多