R求解器简单最小化器

时间:2015-01-27 15:47:23

标签: r solver minimize

在Excel中,存在一个解决此问题的简单方法 - >求解。我现在想在R中执行相同的任务。首先我的数据:

library(data.table)

date <- seq(2015, 2024, 1)
t <- seq(1,10,1)
balance <- c(33, 28, 23, 19, 17, 14, 12, 9, 8, 7)

mydata <- data.table(cbind(date, t, balance))

我现在想在“平衡”上只用一个参数(估计线)拟合非线性线。估计的行定义如下:

t[2015;2024]= balance(t=2015)*(1-x)^t的估计输出。因此我们知道平衡,我们知道。我正在寻找一个常数x,它可以最大限度地减少观察到的平衡误差的平方和 - 所有10年的估计平衡。

有一种简单的估算方法吗?一种可与Excel中的Solver相媲美的方法吗?

3 个答案:

答案 0 :(得分:0)

虽然我同意David Arenburg,并使用nloptr进行几乎所有优化,但为了保持简单,我们可以使用base optim和method = Brent(因为这是一个参数问题)

这是您的数据

library(data.table)
date <- seq(2015, 2024, 1)
t <- seq(1,10,1)
balance <- c(33, 28, 23, 19, 17, 14, 12, 9, 8, 7)
mydata <- data.table(cbind(date, t, balance))

现在我们需要创建一个函数,它将返回给定输入的平方误差:

error_f <- function(x, mydata){
  estimated_bal <- mydata$balance[1] * (1 - x) ^ mydata$t
  return(sum((estimated_bal - mydata$balance)^2))
}

现在,只需运行optim(您也可以使用optimize,因为这是一个单变量的问题)

> Z <- optim(par = 2, fn = error_f, lower = -1e6, upper = 1e6, method = 'Brent', mydata = mydata)
> Z
$par
[1] 0.1304993

$value
[1] 36.55443

$counts
function gradient 
      NA       NA 

$convergence
[1] 0

$message
NULL

结果:

mydata$balance[1] * (1 - Z$par) ^ mydata$t
 [1] 28.693524 24.949040 21.693208 18.862261 16.400749 14.260463 12.399483 10.781360  9.374400  8.151048

答案 1 :(得分:0)

func = function(x) 33*((1-x)^t)
costFunc = function(x) sum((func(x)-balance)**2)
res = optim(0, costFunc)

您想要的x存储在res$par

> res$par
[1] 0.1305176

x的某些值进行虚拟化并与balance进行比较:

library(ggplot2)
library(tidyr)

mydata[, c("func1", "func2","func3","func4"):=list(func(0.2), func(0.15),func(0.1), func(0.05))]
dt = gather(mydata, var, value, balance:func4)


ggplot() + 
geom_line(aes(x=t, y=value, color=var),subset(dt, var!="balance")) + 
geom_point(aes(x=t, y=value),subset(dt, var=="balance"))

enter image description here

答案 2 :(得分:0)

只需使用nls

fit <- nls(balance ~ balance[t == 1] * (1-x)^t, data = mydata, start = list(x = 0))
summary(fit)
#Formula: balance ~ balance[t == 1] * (1 - x)^t
#
#Parameters:
#  Estimate Std. Error t value Pr(>|t|)    
#x 0.130499   0.007404   17.63 2.76e-08 ***
#---
#Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#
#Residual standard error: 2.015 on 9 degrees of freedom
#
#Number of iterations to convergence: 6 
#Achieved convergence tolerance: 6.426e-07

plot(balance ~ t, data = mydata)
lines(mydata$t, fitted(fit))

resulting plot