【问题标题】:optimize has weird behavior when I change the interval当我更改间隔时优化有奇怪的行为
【发布时间】:2014-05-22 14:18:36
【问题描述】:

我对 R 中的 optimize() 有疑问。

当我只改变optimize()中的区间时,出乎意料的是,最优参数值会有很大的变化。我之前发现过类似问题的帖子,但没有答案。

我从不同的时间间隔得到了非常不同的值:

c(-1,1): -0.819 

c(-1,2): -0.729 
c(0.3,0.99):0.818 
c(0.2,0.99):0.803 
c(0.1,0.99):0.23 
c(0,0.99):0.243 

我真的需要这个问题的帮助,如果你能帮助或给我任何信息,谢谢你们!

编辑:这是目标函数的图片:

我的代码如下:

dis<-data[,5]
vel<-data[,3]
condition<-data[,2]
nrow<-nrow(data)
number<-500
status<-0
counter<-rep(0,nrow)
firstvel<-rep(0,nrow)
secondvel<-rep(0,nrow)
j=1
n=1
l=0
secondpoint<-rep(0,nrow)
f<-function(a,b,p){ 
  for (i in 5:p){
    diss<-dis[1:(i-1)] 
    stddis<-sd(diss)    
    lowerdis<- a*stddis
    upperdis<- b*stddis
    if (status==0&&dis[i]>=upperdis){
      status<-1
      firstvel[j]<-vel[i]
      j=j+1    
    }
    else if (status==1&&condition[i]<=condition[i-1]&&dis[i]<lowerdis){
      status<-0
      secondvel[n]<-vel[i]
      n=n+1
    }
  }
  secondvel<- subset(secondvel, secondvel>0)
  firstvel<- subset(firstvel, firstvel>0)
  if (j==n&&j>1){
    for (k in 1:(j-1)){
      unit<-number/firstvel[k]
      number<-unit*secondvel[k]
    }
  }   else if(j>1) {
    for (k in 1:(j-2)){
      unit<-number/firstvel[k]
      number<-unit*secondvel[k]
    }
    unit<-number/firstvel[k+1]
    number<-unit*vel[p]
  }
  return(-number)
}
for (point in 300:nrow){
  diss<-dis[1:(point-1)]
  stddis<-sd(diss)
  upperdis<- stddis
  if (status==0&&dis[point]>=upperdis){
    status<-1
    firstvel[j]<-vel[point]
    j=j+1
    last<-optimize(f,c(0.2,0.99),b=1.0,p=point)
    secondpoint[n]<-last$minimum      ## This is the optimal value I need, which changes a lot 
    lowerdis<- secondpoint[n]*stddis
  }
  else if (status==1&&condition[point]<=condition[point-1]&&dis[point]<lowerdis){
    status=0
    secondvel[n]<-vel[point]
    n=n+1
  }
}
secondvel<-subset(secondvel,secondvel>0)
firstvel<-subset(firstvel,firstvel>0)
secondpoint<-as.numeric(secondpoint[1:(j-1)])
diff<-rep(0,(j-1))
if (j==n&&j>1){
  for (k in 1:(j-1)){
    unit<-number/firstvel[k]
    number<-unit*secondvel[k]
    diff[k]<-unit*(secondvel[k]-firstvel[k])
  }
}  else if(j>1) {
  for (k in 1:(j-2)){
    unit<-number/firstvel[k]
    number<-unit*secondvel[k]
    diff[k]<-unit*(secondvel[k]-firstvel[k])
  }
  unit<-number/firstvel[k+1]
  number<-unit*vel[nrow]
  diff[k+1]<-unit*(vel[nrow]-firstvel[k+1])
}

【问题讨论】:

  • 这是不可重现的。 diss 是什么?我会先画一张你的曲线图,例如mvec &lt;- seq(-4,4,length=201); qvec &lt;- sapply(mvec,fun,n=2,p=50); plot(mvec,qvec,type="l")
  • Ben 的观点是,所有此类优化算法都会移动到最近的局部最小值。如果你的起点在那边,你就不会收敛到这里。
  • 实际上,甚至不一定是最近的局部最小值——所有可以保证的是a局部最小值...
  • @BenBolker 我用你的代码制作了图片,由于我不能在这里上传图片:(,我会尝试向你描述它。图片有很多平面部分,所以我可以理解它在0.2左右变化,因为这是最小目标函数的真正最优值。然后函数在之后上升。我不知道为什么它会是0.803 for (0.2,0.99)。
  • 实际上(0.8,0.81)有一个突然的下降,但是目标函数值比其他的要大。

标签: r loops intervals mathematical-optimization maximize


【解决方案1】:

对于任何假设目标函数是平滑且具有单个最小值的优化器(例如optimize())来说,这个优化问题基本上是不可能的。你没有给出一个可重复的例子,但这里有一个目标函数的例子,它和你的一样丑:

set.seed(101)
r <- runif(11)
f <- function(x) r[pmin(11,pmax(1,floor(x)+1))]

有很多随机全局优化算法——你可以在CRAN Optimization Task View搜索“global”来找到更多——但是它们都会慢得多,并且需要更多地调整优化控制参数,才能获得任何特定问题的可靠结果。在这种情况下,optim() 中的"SANN"(模拟退火)方法与默认选项配合得相当好——它在 25 次中得到了 20 次正确答案。您可以调整控制参数(例如增加maxit:参见?optim),也许会做得更好。

pvals <- replicate(25,optim(f,par=5,method="SANN")$par)

curve(f,from=-1,to=11)
points(pvals,f(pvals),col=2)
sum(pvals>1 & pvals<2) ## 20

另外,对于一维问题,蛮力网格搜索始终是一种选择...

【讨论】:

  • 我尝试了将 m 和 n 组合为向量的 optim(),但它不起作用。所以我稍后会为你重现它,非常感谢你的帮助,这真的很好!:)
  • 顺便说一句,你有电子邮件或者我可以给你发我的可重现代码吗?谢谢!
  • 您应该尝试弄清楚如何将您的示例精简到可以在此处发布可重现的版本。
  • 很抱歉我是新来的,我在上面发布了我的可重现代码。抱歉,我有这么多问题...
  • 很抱歉,由于我们没有您的数据,因此仍然无法重现。您能否澄清一下我的回答以何种方式为您解决问题提供了足够的起点?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-16
  • 2012-08-17
  • 2017-11-25
  • 2019-04-08
  • 2018-12-16
  • 1970-01-01
  • 2020-01-30
相关资源
最近更新 更多