01
02
03
04
我们已经有了数据,因此让我们看看该函数对违反约束的解决方案有何作用。假设我们有三个解的总体mP。
> param1 <- c( 6, 3, 8, -1)
> param2 <- c( 6, 3, 8, 1)
> param3 <- c(-1, 3, 8, 1)
> mP <- cbind(param1,param2,param3)
> rownames(mP) <- c("b1","b2","b3","lambda")
> mP
param1 param2 param3
b1 6 6 -1
b2 3 3 3
b3 8 8 8
lambda -1 1 1
第一个和第三个解决方案违反了约束。在第一个解决方案中,λ为负。在第三个解中,β1为负。
> penalty(mP,data)
param1 param2 param3
0.2 0.0 0.2
参数ww控制了我们的惩罚程度。
> data$ww <- 0.5
> penalty(mP,data)
param1 param2 param3
1 0 1
对于有效的解决方案,惩罚应为零。
> penalty(mP, data)
param1 param2 param3
0 0 0
请注意,惩罚会立即生效;无需遍历解决方案。
这样我们就可以进行测试了。我们首先定义DE的参数。请特别注意,我们传递了惩罚函数,并将设置为FALSE。
然后使用目标函数OF,列表数据和列表算法调用DEopt。
> sol <- DEopt(OF = OF, algo = algo, data = data)
差异演化。
最佳解的目标函数值为0;
最终人群中OF的标准偏差为3.0455e-16。
为了检查目标函数是否正常工作,我们将最大误差与返回的目标函数值进行比较–它们应该相同。
> max( abs(data$model(sol$xbest, tm) - data$model(betaTRUE, tm)) )
[1] 0
> sol$OFvalue
[1] 0
作为基准,我们从stats包运行函数。
如果发现它的性能优于DE,我们将有力地表明我们的DE实现存在问题。
我们使用一个随机起始值s0。
> s0 <- algo$min + (algo$max - algo$min) * runif(length(algo$min))
> sol2 <- nlminb(s0, OF, data = data,
lower = data$min,
upper = data$max,
control = list(eval.max = 50000L,
iter.max = 50000L))
同样,我们比较返回的目标函数值和最大误差。
> max( abs(data$model(sol2$par, tm) - data$model(betaTRUE,tm)) )
[1] 1.5787e-07
> sol2$objective
[1] 1.5787e-07
为了比较我们的两个解(DE和),我们可以将它们与真实的收益率曲线一起绘制。但是必须强调的是,这两种算法的结果都是随机的:对于DE,因为它故意使用随机性;在的情况下,因为我们随机设置了起始值。为了获得更有意义的结果,我们应该多次运行这两种算法。为了降低插图的构建时间,我们只运行两种方法一次。
> plot(tm, yM, xlab = "maturities in years",
ylab = "yields in %")
> algo$printDetail <- FALSE
> for (i in seq_len(nRuns)) {
sol <- DEopt(OF = OF, algo = algo, data = data)
lines(tm, data$model(sol$xbest,tm), col = "blue")
s0 <- algo$min + (algo$max-algo$min) * runif(length(algo$min))
sol2 <- nlminb(s0, OF, data = data,
lower = data$min,
upper = data$max,
control = list(eval.max = 50000L,
iter.max = 50000L))
lines(tm,data$model(sol2$par,tm), col = "darkgreen", lty = 2)
}
> legend(x = "topright", legend = c("true yields", "DE", "nlminb"),
col = c("black","blue","darkgreen"),
pch = c(1, NA, NA), lty = c(0, 1, 2))
毫无疑问,DE似乎通常只有一条曲线:实际上有nRuns 条线,但是它们是相互叠加的。
其他约束
NS(和NSS)模型的参数约束是要确保所得的零利率为非负数。但实际上,它们不能保证正利率。
> plot(tm, yM, xlab = "maturities in years", ylab = "yields in %")
> abline(h = 0)
这确实是一个虚构的示例,但尽管如此,我们仍可能希望包括针对此类参数向量的约束措施:我们可以仅包含一个所有速率均大于零的约束条件。
同样,这可以通过惩罚函数来完成。
校验:
> penalty2(c(3, -2, -8, 1.5),data)
[1] 0.86343
此惩罚函数仅适用于单个解决方案,因此实际上将其直接写入目标函数最简单。
因此,就像一个数值测试:假设上述参数为真,而利率为负。
> algo$pen <- NULL; data$yM <- yM; data$tm <- tm
> par(ps = 11, bty = "n", las = 1, tck = 0.01,
mgp = c(3, 0.2, 0), mar = c(4, 4, 1, 1))
> plot(tm, yM, xlab = "maturities in years", ylab = "yields in %")
> abline(h = 0)
> sol <- DEopt(OF = OFa, algo = algo, data = data)
> lines(tm,data$model(sol$xbest,tm), col = "blue")
> legend(x = "topleft", legend = c("true yields", "DE (constrained)"),
col = c("black", "blue"),
pch = c(1, NA, NA), lty = c(0, 1, 2))
3将NSS模型拟合到给定的零利率
如果要改用NSS模型,则几乎不需要更改。我们只需要向目标函数传递一个不同的模型。下面是一个示例。同样,我们修复了真实参数并尝试恢复它们。
列表数据和算法与以前几乎相同;目标函数保持完全相同。
仍然需要运行算法。(同样,我们检查返回的目标函数值。)
> sol <- DEopt(OF = OF, algo = algo, data = data)
> max( abs(data$model(sol$xbest, tm) - data$model(betaTRUE, tm)) )
[1] 7.9936e-15
> sol$OFvalue
[1] 7.9936e-15
我们将结果与进行比较。
最后,我们比较了几次运行所得的收益率曲线。
> par(ps = 11, bty = "n", las = 1, tck = 0.01,
mgp = c(3, 0.2, 0), mar = c(4, 4, 1, 1))
> plot(tm, yM, xlab = "maturities in years", ylab = "yields in %")
> for (i in seq_len(nRuns)) {
sol <- DEopt(OF = OF, algo = algo, data = data)
lines(tm, data$model(sol$xbest,tm), col = "blue")
s0 <- algo$min + (algo$max - algo$min) * runif(length(algo$min))
sol2 <- nlminb(s0, OF, data = data,
lower = data$min,
upper = data$max,
control = list(eval.max = 50000L,
iter.max = 50000L))
lines(tm, data$model(sol2$par,tm), col = "darkgreen", lty = 2)
}
> legend(x = "topright", legend = c("true yields", "DE", "nlminb"),
col = c("black","blue","darkgreen"),
pch = c(1,NA,NA), lty = c(0,1,2), bg = "white")
参考文献
关于数值优化中“良好起始值”的注释,2010年。 =
1、本站发布的内容部分购买于网络,仅供读者学习与参考,如有侵权,请联系站长进行删除处理。
2、本站一切资源不代表本站立场,不代表本站赞同其观点和对其真实性负责。
3、本站仅分享资源,以极低的价格降低大家被割韭菜的损失。本站无法保证资源质量,所以介意的小伙伴请勿下单!
4、资源大多存储在云盘,如发现链接失效,请联系站长第一时间更新。