我想最小化带有两个变量的函数。
首先,我创建了一个函数(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"