这是代码(我很抱歉,如果这么久,但这是我的第一个例子);我正在使用A. Wittmann的CreditMetrics
包中的CVaR示例和DEoptim
求解器进行优化:
library(CreditMetrics)
library(DEoptim)
N <- 3
n <- 100000
r <- 0.003
ead <- rep(1/N,N)
rc <- c("AAA", "AA", "A", "BBB", "BB", "B", "CCC", "D")
lgd <- 0.99
rating <- c("BBB", "AA", "B")
firmnames <- c("firm 1", "firm 2", "firm 3")
alpha <- 0.99
# correlation matrix
rho <- matrix(c( 1, 0.4, 0.6,
0.4, 1, 0.5,
0.6, 0.5, 1), 3, 3, dimnames = list(firmnames, firmnames),
byrow = TRUE)
# one year empirical migration matrix from standard&poors website
rc <- c("AAA", "AA", "A", "BBB", "BB", "B", "CCC", "D")
M <- matrix(c(90.81, 8.33, 0.68, 0.06, 0.08, 0.02, 0.01, 0.01,
0.70, 90.65, 7.79, 0.64, 0.06, 0.13, 0.02, 0.01,
0.09, 2.27, 91.05, 5.52, 0.74, 0.26, 0.01, 0.06,
0.02, 0.33, 5.95, 85.93, 5.30, 1.17, 1.12, 0.18,
0.03, 0.14, 0.67, 7.73, 80.53, 8.84, 1.00, 1.06,
0.01, 0.11, 0.24, 0.43, 6.48, 83.46, 4.07, 5.20,
0.21, 0, 0.22, 1.30, 2.38, 11.24, 64.86, 19.79,
0, 0, 0, 0, 0, 0, 0, 100
)/100, 8, 8, dimnames = list(rc, rc), byrow = TRUE)
cm.CVaR(M, lgd, ead, N, n, r, rho, alpha, rating)
y <- cm.cs(M, lgd)[which(names(cm.cs(M, lgd)) == rating)]
现在我写了我的功能......
fun <- function(w) {
# ...
- (t(w) %*% y - r) / cm.CVaR(M, lgd, ead = w, N, n, r,
rho, alpha, rating)
}
...我想优化它:
DEoptim(fn = fun, lower = rep(0, N), upper = rep(1, N),
control = DEoptim.control())
您能否告诉我在优化过程中我需要在# ...
中插入哪些内容才能sum(w) = 1
?
下面我根据flodel的提示向您展示优化结果:
# The first trick is to include B as large number to force the algorithm to put sum(w) = 1
fun <- function(w) {
- (t(w) %*% y - r) / cm.CVaR(M, lgd, ead = w, N, n, r, rho, alpha, rating) +
abs(10000 * (sum(w) - 1))
}
DEoptim(fn = fun, lower = rep(0, N), upper = rep(1, N),
control = DEoptim.control())
$optim$bestval
[1] -0.05326055
$optim$bestmem
par1 par2 par3
0.005046258 0.000201286 0.994752456
parsB <- c(0.005046258, 0.000201286, 0.994752456)
> fun(parsB)
[,1]
[1,] -0.05326089
...和...
正如你所看到的,第一个技巧效果更好,因为他发现的结果小于第二个结果。不幸的是,他似乎需要更长时间。
# The second trick needs you use w <- w / sum(w) in the function itself
fun <- function(w) {
w <- w / sum(w)
- (t(w) %*% y - r) / cm.CVaR(M, lgd, ead = w, N, n, r, rho, alpha, rating) #+
#abs(10000 * (sum(w) - 1))
}
DEoptim(fn = fun, lower = rep(0, N), upper = rep(1, N),
control = DEoptim.control())
$optim$bestval
[1] -0.0532794
$optim$bestmem
par1 par2 par3
1.306302e-15 2.586823e-15 9.307001e-01
parsC <- c(1.306302e-15, 2.586823e-15, 9.307001e-01)
parC <- parsC / sum(parsC)
> fun(parC)
[,1]
[1,] -0.0532794
有任何评论吗?
我是否应该因为“太随机”待优化功能而增加迭代次数?
答案 0 :(得分:6)
尝试:
w <- w / sum(w)
如果DEoptim
为您提供了最佳解决方案w*
,那么sum(w*) != 1
则w*/sum(w*)
应该是您的最佳解决方案。
另一种方法是解决所有变量而不是一个变量。我们知道最后一个变量的值必须是1 - sum(w)
所以在函数体中有:
w <- c(w, 1-sum(w))
并对DEoptim
:w* <- c(w*, 1-sum(w*))
两种解决方案都要求您将问题重新制定为无约束(不计入变量边界)优化,以便可以使用DEoptim
;这迫使你在DEoptim
之外做一些额外的工作来恢复原始问题的解决方案。
在回复您的评论时,如果您希望DEoptim
立即给您正确答案(即无需转换后),您还可以尝试为您的目标函数包含惩罚费用:例如,添加B * abs(sum(w)-1)
,其中B
是一个任意大的数字,因此sum(w)
将被强制为1
。
答案 1 :(得分:0)
我认为你应该为任何一个偏差添加惩罚。
将问题+(sum(weights) - 1)^2 * 1e10
添加到您的最小化问题中。你应该看到这个巨大的惩罚将迫使权重总和为1!