optim 位于 stats 包(package)。 说明
基于Nelder-Mead、quasi-Newton和共轭梯度算法的通用优化。它包括用于盒约束优化和模拟退火的选项。
用法
optim(par, fn, gr = NULL, ...,
      method = c("Nelder-Mead", "BFGS", "CG", "L-BFGS-B", "SANN",
                 "Brent"),
      lower = -Inf, upper = Inf,
      control = list(), hessian = FALSE)
optimHess(par, fn, gr = NULL, ..., control = list())
参数
| par | 要优化的参数的初始值。 | 
| fn | 要最小化(或最大化)的函数,第一个参数是要进行最小化的参数向量。它应该返回一个标量结果。 | 
| gr | 返回  对于 | 
| ... | 要传递给  | 
| method | 要使用的方法。查看具体信息'。可以缩写。 | 
| lower, upper | 
 | 
| control | 控制参数 | 
| hessian | 逻辑性强。是否应该返回数值微分的 Hessian 矩阵? | 
细节
请注意,... 之后的参数必须完全匹配。
默认情况下,optim 执行最小化,但如果 control$fnscale 为负数,则会最大化。 optimHess 是一个辅助函数,用于在忘记hessian = TRUE 的情况下在后期计算 Hessian 矩阵。
默认方法是 Nelder 和 Mead (1965) 方法的实现,它仅使用函数值,并且很健壮,但相对较慢。它对于不可微函数来说效果相当好。
方法 "BFGS" 是 quasi-Newton 方法(也称为可变度量算法),具体由 Broyden、Fletcher、Goldfarb 和 Shanno 于 1970 年同时发布。它使用函数值和梯度来构建要优化的表面的图片。
方法 "CG" 是基于 Fletcher 和 Reeves (1964) 的共轭梯度方法(但可以选择 Polak-Ribiere 或 Beale-Sorenson 更新)。共轭梯度方法通常比 BFGS 方法更脆弱,但由于它们不存储矩阵,因此它们可能在更大的优化问题中取得成功。
方法"L-BFGS-B" 是 Byrd 等人的方法。等人。 (1995) 允许框约束,即每个变量都可以给出一个下限和/或上限。初始值必须满足约束条件。这使用 BFGS quasi-Newton 方法的有限内存修改。如果提供了非平凡边界,则将选择此方法,并带有警告。
Nocedal and Wright (1999)是对前三种方法的综合参考。
默认情况下,方法 "SANN" 是 Belisle (1992) 中给出的模拟退火的变体。模拟退火属于随机全局优化方法类。它仅使用函数值,但速度相对较慢。它也适用于不可微函数。此实现使用 Metropolis 函数来计算接受概率。默认情况下,下一个候选点是从高斯马尔可夫核生成的,其比例与实际温度成比例。如果给出生成新候选点的函数,方法"SANN"也可以用于解决组合优化问题。温度根据 Belisle (1992, p. 890) 中给出的对数冷却时间表降低;具体来说,温度设置为 temp / log(((t-1) %/% tmax)*tmax + exp(1)) ,其中 t 是当前迭代步骤,temp 和 tmax 可通过 control 指定,请参见下文。请注意,"SANN" 方法很大程度上取决于控制参数的设置。它不是通用方法,但对于在非常粗糙的表面上获得良好的值非常有用。
方法 "Brent" 仅适用于一维问题,使用 optimize() 。当 optim() 在只能指定 method 的其他函数中使用时,它会很有用,例如在 stats4 包中的 mle 中。
如果函数 fn 无法按提供的值进行计算,则该函数可以返回 NA 或 Inf ,但初始值必须具有可计算的有限值 fn 。 (除了方法 "L-BFGS-B" 之外,该方法的值应始终是有限的。)
optim 可以递归使用,并且可以用于单个参数,也可以用于多个参数。它还接受零长度 par ,并仅使用该参数计算函数。
control 参数是一个可以提供以下任何组件的列表:
- trace
- 
非负整数。如果是肯定的,则会生成有关优化进度的跟踪信息。较高的值可能会产生更多的跟踪信息:对于方法 "L-BFGS-B",有六个跟踪级别。 (要准确理解这些内容,请参阅源代码:更高级别提供更多详细信息。)
- fnscale
- 
优化期间应用于 fn和gr值的整体缩放。如果为负,则将问题转化为最大化问题。对fn(par)/fnscale进行优化。
- parscale
- 
参数缩放值的向量。优化是在 par/parscale上执行的,从任何元素中的单位变化都会产生缩放值的单位变化的意义上来说,这些应该具有可比性。method = "Brent"不使用(也不需要)。
- ndeps
- 
梯度有限差分近似的步长向量,采用 par/parscale尺度。默认为1e-3。
- maxit
- 
最大迭代次数。对于基于导数的方法,默认为 100;对于"Nelder-Mead",默认为500。对于 "SANN"maxit给出函数评估的总数:没有其他停止标准。默认为10000。
- abstol
- 
绝对收敛容差。仅对非负函数有用,作为达到零的容差。 
- reltol
- 
相对收敛容差。如果无法将值一步减少 reltol * (abs(val) + reltol)倍,算法就会停止。默认为sqrt(.Machine$double.eps),通常约为1e-8。
- alpha,- beta,- gamma
- 
"Nelder-Mead"方法的缩放参数。alpha是反射系数(默认 1.0),beta是收缩系数(0.5),gamma是膨胀系数(2.0)。
- REPORT
- 
如果 control$trace为正,则"BFGS"、"L-BFGS-B"和"SANN"方法的报告频率。对于"BFGS"和"L-BFGS-B"默认为每 10 次迭代,对于"SANN"默认为每 100 个温度。
- warn.1d.NelderMead
- 
logical指示(默认)"Nelder-Mead"方法在用于一维最小化时是否应发出警告信号。由于警告有时是不适当的,您可以通过将此选项设置为 false 来抑制它。
- type
- 
对于共轭梯度法。对于 Fletcher-Reeves 更新,采用值 1;对于 Polak-Ribiere,采用值2;对于 Beale-Sorenson,采用值3。
- lmm
- 
是一个整数,给出 "L-BFGS-B"方法中保留的 BFGS 更新数量,默认为5。
- factr
- 
控制 "L-BFGS-B"方法的收敛。当目标的减少量在机器公差的这个因子内时,就会发生收敛。默认值为1e7,即大约1e-8的容差。
- pgtol
- 
有助于控制 "L-BFGS-B"方法的收敛。它是当前搜索方向上投影梯度的容差。当检查被抑制时,该值默认为零。
- temp
- 
控制 "SANN"方法。它是冷却计划的起始温度。默认为10。
- tmax
- 
是 "SANN"方法在每个温度下的函数评估次数。默认为10。
赋予 par 的任何名称都将复制到传递给 fn 和 gr 的向量。请注意,par 的其他属性不会被复制。
传递给 fn 的参数向量具有特殊语义,并且可以在调用之间共享:函数不应更改或复制它。
值
对于 optim ,包含组件的列表:
| par | 找到的最佳参数集。 | 
| value | 
 | 
| counts | 一个二元素整数向量,分别给出对  | 
| convergence | 整数代码。  
 | 
| message | 给出优化器返回的任何附加信息的字符串,或  | 
| hessian | 仅当参数  | 
对于 optimHess ,适用 hessian 组件的说明。
注意
optim 将与一维 par 一起使用,但默认方法不能很好地工作(并且会发出警告)。方法 "Brent" 使用 optimize 并且需要边界可用;如果不是的话,"BFGS" 通常也能正常工作。
例子
require(graphics)
fr <- function(x) {   ## Rosenbrock Banana function
    x1 <- x[1]
    x2 <- x[2]
    100 * (x2 - x1 * x1)^2 + (1 - x1)^2
}
grr <- function(x) { ## Gradient of 'fr'
    x1 <- x[1]
    x2 <- x[2]
    c(-400 * x1 * (x2 - x1 * x1) - 2 * (1 - x1),
       200 *      (x2 - x1 * x1))
}
optim(c(-1.2,1), fr)
(res <- optim(c(-1.2,1), fr, grr, method = "BFGS"))
optimHess(res$par, fr, grr)
optim(c(-1.2,1), fr, NULL, method = "BFGS", hessian = TRUE)
## These do not converge in the default number of steps
optim(c(-1.2,1), fr, grr, method = "CG")
optim(c(-1.2,1), fr, grr, method = "CG", control = list(type = 2))
optim(c(-1.2,1), fr, grr, method = "L-BFGS-B")
flb <- function(x)
    { p <- length(x); sum(c(1, rep(4, p-1)) * (x - c(1, x[-p])^2)^2) }
## 25-dimensional box constrained
optim(rep(3, 25), flb, NULL, method = "L-BFGS-B",
      lower = rep(2, 25), upper = rep(4, 25)) # par[24] is *not* at boundary
## "wild" function , global minimum at about -15.81515
fw <- function (x)
    10*sin(0.3*x)*sin(1.3*x^2) + 0.00001*x^4 + 0.2*x+80
plot(fw, -50, 50, n = 1000, main = "optim() minimising 'wild function'")
res <- optim(50, fw, method = "SANN",
             control = list(maxit = 20000, temp = 20, parscale = 20))
res
## Now improve locally {typically only by a small bit}:
(r2 <- optim(res$par, fw, method = "BFGS"))
points(r2$par,  r2$value,  pch = 8, col = "red", cex = 2)
## Combinatorial optimization: Traveling salesman problem
library(stats) # normally loaded
eurodistmat <- as.matrix(eurodist)
distance <- function(sq) {  # Target function
    sq2 <- embed(sq, 2)
    sum(eurodistmat[cbind(sq2[,2], sq2[,1])])
}
genseq <- function(sq) {  # Generate new candidate sequence
    idx <- seq(2, NROW(eurodistmat)-1)
    changepoints <- sample(idx, size = 2, replace = FALSE)
    tmp <- sq[changepoints[1]]
    sq[changepoints[1]] <- sq[changepoints[2]]
    sq[changepoints[2]] <- tmp
    sq
}
sq <- c(1:nrow(eurodistmat), 1)  # Initial sequence: alphabetic
distance(sq)
# rotate for conventional orientation
loc <- -cmdscale(eurodist, add = TRUE)$points
x <- loc[,1]; y <- loc[,2]
s <- seq_len(nrow(eurodistmat))
tspinit <- loc[sq,]
plot(x, y, type = "n", asp = 1, xlab = "", ylab = "",
     main = "initial solution of traveling salesman problem", axes = FALSE)
arrows(tspinit[s,1], tspinit[s,2], tspinit[s+1,1], tspinit[s+1,2],
       angle = 10, col = "green")
text(x, y, labels(eurodist), cex = 0.8)
set.seed(123) # chosen to get a good soln relatively quickly
res <- optim(sq, distance, genseq, method = "SANN",
             control = list(maxit = 30000, temp = 2000, trace = TRUE,
                            REPORT = 500))
res  # Near optimum distance around 12842
tspres <- loc[res$par,]
plot(x, y, type = "n", asp = 1, xlab = "", ylab = "",
     main = "optim() 'solving' traveling salesman problem", axes = FALSE)
arrows(tspres[s,1], tspres[s,2], tspres[s+1,1], tspres[s+1,2],
       angle = 10, col = "red")
text(x, y, labels(eurodist), cex = 0.8)
## 1-D minimization: "Brent" or optimize() being preferred.. but NM may be ok and "unavoidable",
## ----------------   so we can suppress the check+warning :
system.time(rO <- optimize(function(x) (x-pi)^2, c(0, 10)))
system.time(ro <- optim(1, function(x) (x-pi)^2, control=list(warn.1d.NelderMead = FALSE)))
rO$minimum - pi # 0 (perfect), on one platform
ro$par - pi     # ~= 1.9e-4    on one platform
utils::str(ro)
来源
方法 "Nelder-Mead" 、 "BFGS" 和 "CG" 的代码最初基于 Nash (1990) 中的 Pascal 代码,由 p2c 翻译,然后进行手工优化。纳什博士同意可以免费提供该代码。
方法的代码"L-BFGS-B"基于 Zhu、Byrd、Lu-Chen 和从 Netlib 获得的 Nocedal 的 Fortran 代码(文件‘选择/lbfgs_bcm.shar’:另一个版本在‘汤姆斯/778’)。
方法 "SANN" 的代码由 A. Trapletti 贡献。
参考
Belisle, C. J. P. (1992). Convergence theorems for a class of simulated annealing algorithms on . Journal of Applied Probability, 29, 885-895. doi:10.2307/3214721.
Byrd, R. H., Lu, P., Nocedal, J. and Zhu, C. (1995). A limited memory algorithm for bound constrained optimization. SIAM Journal on Scientific Computing, 16, 1190-1208. doi:10.1137/0916069.
Fletcher, R. and Reeves, C. M. (1964). Function minimization by conjugate gradients. Computer Journal 7, 148-154. doi:10.1093/comjnl/7.2.149.
Nash, J. C. (1990). Compact Numerical Methods for Computers. Linear Algebra and Function Minimisation. Adam Hilger.
Nelder, J. A. and Mead, R. (1965). A simplex algorithm for function minimization. Computer Journal, 7, 308-313. doi:10.1093/comjnl/7.4.308.
Nocedal, J. and Wright, S. J. (1999). Numerical Optimization. Springer.
也可以看看
optimize 用于一维最小化,constrOptim 用于约束优化。
相关用法
- R optimize 一维优化
- R order.dendrogram 树状图中叶子的排序或标签
- R oneway.test 测试单向布局中的均值相等
- R offset 在模型公式中包含偏移量
- R stlmethods STL 对象的方法
- R medpolish 矩阵的中值波兰(稳健双向分解)
- R naprint 调整缺失值
- R summary.nls 总结非线性最小二乘模型拟合
- R summary.manova 多元方差分析的汇总方法
- R formula 模型公式
- R nls.control 控制 nls 中的迭代
- R aggregate 计算数据子集的汇总统计
- R deriv 简单表达式的符号和算法导数
- R kruskal.test Kruskal-Wallis 秩和检验
- R quade.test 四方测试
- R decompose 移动平均线的经典季节性分解
- R plot.stepfun 绘制阶跃函数
- R alias 查找模型中的别名(依赖项)
- R qqnorm 分位数-分位数图
- R eff.aovlist 多层方差分析的计算效率
- R pairwise.t.test 成对 t 检验
- R loglin 拟合对数线性模型
- R predict.smooth.spline 通过平滑样条拟合进行预测
- R bartlett.test 方差齐性的 Bartlett 检验
- R influence.measures 回归删除诊断
注:本文由纯净天空筛选整理自R-devel大神的英文原创作品 General-purpose Optimization。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。
