我正在尝试找到噪声多元函数的最小值。为了清楚起见,让我们举一个简单的例子。
set.seed(5)
s <- sin(0.5 * seq(0,10,0.1) + 5)/-1
ln <- as.numeric(length(s))
sn <- s + rnorm(ln,sd = 0.3)
plot(sn,t="l", col=8,lty=2)
lines(s, col=4)
points(which.min(s), min(s), lwd=5 , col=4)
蓝点是我想要获得的值。
我的目标函数是找到对应于非噪声函数最小值的点的索引。
fit <- function(i) sn[ round(i,0) ]
这是我从this示例中复制的代码
library(mlrMBO)
obj.fun = makeSingleObjectiveFunction(name = "noisy_fu",
fn = fit,
has.simple.signature = TRUE,
par.set = makeNumericParamSet("i",
len = 1,
lower = 1,
upper = length(sn)),
noisy = TRUE)
ctrl = makeMBOControl(final.method = "best.predicted", final.evals = 10)
ctrl = setMBOControlInfill(ctrl, crit = crit.eqi)
ctrl = setMBOControlTermination(ctrl, iters = 10)
configureMlr(on.learner.warning = "quiet", show.learner.output = FALSE)
res = mbo(obj.fun, control = ctrl, show.info = T)
points(res$x, res$y, lwd=5 , col=3)
我可以更改代码中的某些内容,以使价差变小并且点更接近真实最小值(由蓝点表示)吗?
您在评论中提到找到移动平均值的最小值,那么简单地优化数据的平滑版本怎么样?
set.seed(13)
x <- seq(0, 10, 0.1)
s <- sin(0.5 * x + 5) / -1
sn <- s + rnorm(length(s), sd = 0.3)
plot(sn, t="l", col=8,lty=2)
lines(s, col=4)
points(which.min(s), min(s), lwd=5 , col=4)
smoothed <- lowess(x, sn, f = 0.3)
lines(smoothed$y, col = "blue")
library(mlrMBO)
fit <- function(i) smoothed$y[ round(i,0) ]
obj.fun = makeSingleObjectiveFunction(
name = "noisy_fu",
fn = fit,
has.simple.signature = TRUE,
par.set = makeNumericParamSet(
"i",
len = 1,
lower = 1,
upper = length(sn)
),
noisy = TRUE
)
ctrl = makeMBOControl(final.method = "best.predicted", final.evals = 10)
ctrl = setMBOControlInfill(ctrl, crit = crit.eqi)
ctrl = setMBOControlTermination(ctrl, iters = 10)
configureMlr(on.learner.warning = "quiet", show.learner.output = FALSE)
res = mbo(obj.fun, control = ctrl, show.info = T)
points(res$x, res$y, lwd=5 , col=3)
计算出的最小值接近预期位置,并且考虑到您正在优化噪声数据,恕我直言,这是相当合理的。
平滑数据的方法有多种,但
lowess()
是一个好的开始。您可以调整更平滑的跨度以使其更平滑/更不平滑。
通过这种方法,您可能也可以使用比
mlrMBO
更简单的优化器。