【问题标题】:R Optimization Returning Incorrect ValuesR优化返回不正确的值
【发布时间】:2013-07-08 05:20:20
【问题描述】:

我的目标函数:

helper.post<-function(monthly.mean.return,
                  start.capital,  #initial nest egg
                  target.legacy,
                  monthly.inflation.post,
                  monthly.withdrawals,
                  n.obs){ 

  req = matrix(start.capital, n.obs+1, 1) #matrix for storing target weight

  for (a in 1:n.obs) {
    #cat("a: ",a,"\n")
    req[a + 1, ] = req[a, ] * (1 + monthly.mean.return - monthly.inflation.post) -     monthly.withdrawals[a,]
  }
  ending.value=req[nrow(req),]
  #ending.value
  value=target.legacy - ending.value

  return(abs(value))
}

使用以下优化结构,更改两个值之间的 n.obs 会得到相同的输出:

即如果 n.obs = 288 或 n.obs = 336,它会给出相同的值。

optimize(f=helper.post,
     start.capital = 1000000,
     target.legacy = 1000000,
     monthly.inflation.post=0.002083333,
     monthly.withdrawals = matrix(rep(10000,n.obs)),
     n.obs = n.obs, 
     lower = 0,
     upper = 1,
     tol = 0.00000000000000000000000000000000001)$minimum

值正确似乎是与正确值相反的估计。知道我可能做错了什么吗?对于这种精确的优化工作,不同的优化工具会更好吗?我尝试了 uni-root,但它似乎不起作用,因为端点不是相反的符号..

uniroot( helper.post, 
     c(0, 1),
     start.capital = start.capital,
     target.legacy = target.legacy,
     monthly.inflation.post=monthly.inflation.post,
     monthly.withdrawals = monthly.withdrawals,
     n.obs = n.obs)$root

【问题讨论】:

    标签: r optimization


    【解决方案1】:

    让我们从稍微重写您的代码开始。我用向量替换了单列矩阵。我还添加了一个选项来返回错误本身或其绝对值。在尝试使用 optim 最小化错误时,您需要使用绝对值,而在尝试使用 uniroot 查找其根时,您需要使用值本身。

    helper.post <- function(monthly.mean.return,
                            start.capital,
                            target.legacy,
                            monthly.inflation.post,
                            monthly.withdrawals,
                            n.obs,
                            return.abs = TRUE) { 
    
      req <- numeric(n.obs + 1)
      req[1] <- start.capital
    
      for (month in 1:n.obs) {
        req[month + 1] <- req[month] *
                          (1 + monthly.mean.return - monthly.inflation.post) -
                          monthly.withdrawals[month]
      }
      ending.value <- req[n.obs + 1]
      error <- target.legacy - ending.value
    
      return(ifelse(return.abs, abs(error), error))
    }
    

    现在让我们对其进行优化:

    n.obs <- 288
    
    optimize(f = helper.post,
             start.capital = 1000000,
             target.legacy = 1000000,
             monthly.inflation.post = 0.002083333,
             monthly.withdrawals = matrix(rep(10000,n.obs)),
             n.obs = n.obs, 
             lower = 0,
             upper = 1,
             tol = 1e-20)$minimum
    # [1] 0.01208333
    

    让我们用uni.root检查解决方案:

    uniroot(helper.post, 
            c(0, 1),
            start.capital = 1000000,
            target.legacy = 1000000,
            monthly.inflation.post = 0.002083333,
            monthly.withdrawals = matrix(rep(10000,n.obs)),
            n.obs = n.obs,
            return.abs = FALSE,
            tol = 1e-20)$root
    # [1] 0.01208333
    

    他们匹配。一个或另一个工具没有任何问题......

    如果您使用不同的 n.obs 值再次运行,您将得到完全相同的结果。为什么?因为您已经为起始和目标资本选择了恒定的提款和相同的值:您获得的输出是从一个月到下个月保持该余额不变所需的速率,无论总月数如何。

    事实上,这是您希望在单元测试中加入的内容。因为这是一个预期且易于解释的结果。我想到的另一个问题是,如果您在所有地方都使取款为零。然后你会期望你的答案与通货膨胀率相匹配。试试看,确实如此。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-08
      • 2017-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-30
      相关资源
      最近更新 更多