當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


R optim 通用優化


R語言 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

返回 "BFGS""CG""L-BFGS-B" 方法的梯度的函數。如果是NULL,將使用有限差分近似。

對於"SANN" 方法,它指定一個函數來生成新的候選點。如果是NULL,則使用默認的高斯馬爾可夫內核。

...

要傳遞給 fngr 的更多參數。

method

要使用的方法。查看具體信息'。可以縮寫。

lower, upper

"L-BFGS-B" 方法的變量界限,或搜索方法 "Brent" 的界限。

control

控製參數list。查看具體信息'。

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 是當前迭代步驟,temptmax 可通過 control 指定,請參見下文。請注意,"SANN" 方法很大程度上取決於控製參數的設置。它不是通用方法,但對於在非常粗糙的表麵上獲得良好的值非常有用。

方法 "Brent" 僅適用於一維問題,使用 optimize() 。當 optim() 在隻能指定 method 的其他函數中使用時,它會很有用,例如在 stats4 包中的 mle 中。

如果函數 fn 無法按提供的值進行計算,則該函數可以返回 NAInf ,但初始值必須具有可計算的有限值 fn 。 (除了方法 "L-BFGS-B" 之外,該方法的值應始終是有限的。)

optim 可以遞歸使用,並且可以用於單個參數,也可以用於多個參數。它還接受零長度 par ,並僅使用該參數計算函數。

control 參數是一個可以提供以下任何組件的列表:

trace

非負整數。如果是肯定的,則會生成有關優化進度的跟蹤信息。較高的值可能會產生更多的跟蹤信息:對於方法"L-BFGS-B",有六個跟蹤級別。 (要準確理解這些內容,請參閱源代碼:更高級別提供更多詳細信息。)

fnscale

優化期間應用於 fngr 值的整體縮放。如果為負,則將問題轉化為最大化問題。對 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 的任何名稱都將複製到傳遞給 fngr 的向量。請注意,par 的其他屬性不會被複製。

傳遞給 fn 的參數向量具有特殊語義,並且可以在調用之間共享:函數不應更改或複製它。

對於 optim ,包含組件的列表:

par

找到的最佳參數集。

value

fn 對應於 par 的值。

counts

一個二元素整數向量,分別給出對 fngr 的調用次數。這不包括計算 Hessian 矩陣(如果需要)所需的調用,以及對 fn 計算梯度有限差分近似值的任何調用。

convergence

整數代碼。 0 表示成功完成("SANN""Brent" 始終是這種情況)。可能的錯誤代碼有

1

表示已達到迭代限製maxit

10

表示 Nelder-Mead 單純形的簡並性。

51

表示來自 "L-BFGS-B" 方法的警告;有關更多詳細信息,請參閱組件message

52

指示 "L-BFGS-B" 方法中的錯誤;有關更多詳細信息,請參閱組件message

message

給出優化器返回的任何附加信息的字符串,或 NULL

hessian

僅當參數 hessian 為 true 時。對稱矩陣給出所找到解的 Hessian 矩陣估計。請注意,即使框約束處於活動狀態,這也是無約束問題的 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.

也可以看看

nlmnlminb

optimize 用於一維最小化,constrOptim 用於約束優化。

相關用法


注:本文由純淨天空篩選整理自R-devel大神的英文原創作品 General-purpose Optimization。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。