我用R写了下面的代码,使用了"mlrMBO"库来优化(我定义的多输入,多输出函数):
#load libraries : https://cran.r-project.org/web/packages/mlrMBO/index.html
library(dplyr)
library(mlrMBO)
#create data for this example
a1 = rnorm(1000,100,10)
b1 = rnorm(1000,100,9)
c1 = sample.int(1000, 1000, replace = TRUE)
train_data = data.frame(a1,b1,c1)
接下来,我设置了优化过程来优化这个函数(函数有4个输入&;x1, x2, x3, x4&;并返回4个输出"f1, f2, f3, f4":
#references:
https://cran.r-project.org/web/packages/smoof/index.html
https://cran.r-project.org/web/packages/ParamHelpers/index.html
#optimization
obj.fun = makeMultiObjectiveFunction(
name = "My function",
fn = function(x1,x2,x3,x4) {
#bin data according to random criteria
train_data <- train_data %>%
mutate(cat = ifelse(a1 <= x1 & b1 <= x3, "a",
ifelse(a1 <= x2 & b1 <= x4, "b", "c")))
train_data$cat = as.factor(train_data$cat)
#new splits
a_table = train_data %>%
filter(cat == "a") %>%
select(a1, b1, c1, cat)
b_table = train_data %>%
filter(cat == "b") %>%
select(a1, b1, c1, cat)
c_table = train_data %>%
filter(cat == "c") %>%
select(a1, b1, c1, cat)
#calculate quantile ("quant") for each bin
table_a = data.frame(a_table%>% group_by(cat) %>%
mutate(quant = ifelse(c1 > 150,1,0 )))
table_b = data.frame(b_table%>% group_by(cat) %>%
mutate(quant = ifelse(c1 > 300,1,0 )))
table_c = data.frame(c_table%>% group_by(cat) %>%
mutate(quant = ifelse(c1 > 400,1,0 )))
f1 = mean(table_a$quant)
f2 = mean(table_b$quant)
f3 = mean(table_c$quant)
#group all tables
final_table = rbind(table_a, table_b, table_c)
# calculate the total mean : this is what needs to be optimized
f4 = mean(final_table$quant)
return (c(f1,f2,f3,f4))
},
n.objectives = 4L,
# define parameter acceptable ranges
par.set = makeParamSet(
makeNumericParam("x1", lower = 80, upper = 95),
makeNumericParam("x2", lower = 100, upper = 120),
makeNumericParam("x3", lower = 80, upper = 95),
makeNumericParam("x4", lower = 100, upper = 120)
forbidden = expression(x1 > x2 | x3 > x4) #define constraints
),
minimize = rep(TRUE,4)
has.simple.signature = FALSE #added
)
#set controls
ctrl = makeMBOControl()
ctrl = setMBOControlTermination(ctrl, iters = 20L)
ctrl = setMBOControlInfill(ctrl, crit = makeMBOInfillCritEI())
# opt.restarts = 1L, opt.focussearch.points = 3L, opt.focussearch.maxit = 1L)
#design = generateDesign(20L, getParamSet(obj.fun), fun = lhs::maximinLHS)
lrn = makeMBOLearner(ctrl, obj.fun)
最后,我运行优化:
#run results
res = mbo(obj.fun, design = NULL, learner = lrn, control = ctrl, show.info = TRUE)
以上代码成功运行:
#view results
head(res)
res
Recommended parameters:
x[1]=82; x[2]=95; x[3]=80; x[4]=95
Objective: y = 0.596
Optimization path
16 + 20 entries in total, displaying last 10 (or less):
x.1. x.2. x.3. x.4. y dob eol error.message exec.time ei error.model train.time prop.type propose.time se mean
27 80.00952 95.01454 87.04891 95.00106 0.596 11 NA <NA> 0.01 -2.003089e-04 <NA> 0.09 infill_ei 0.28 0.0002983176 0.5958623
28 86.88470 95.02414 80.01132 95.00033 0.596 12 NA <NA> 0.01 -4.172457e-04 <NA> 0.10 infill_ei 0.28 0.0007558354 0.5957914
29 80.28991 95.00087 84.20295 95.00028 0.596 13 NA <NA> 0.02 -1.139749e-04 <NA> 0.08 infill_ei 0.29 0.0004338408 0.5961348
问题:但我原以为会有4个"你"。列,例如"y"。, y.2。, y.3。, y.4。";(对应"f1、f2、f3、f4";从函数"fn") -因为有4个"输出"(即"目标")有待优化。只返回一列。
有人知道为什么会这样吗?为什么只有一个"你"?返回列而不是四列?
感谢我想我能够弄清楚这一点-但我不确定我是否正确?我把代码贴在下面:
library(mlrMBO)
library(dplyr)
set.seed(1)
configureMlr(show.learner.output = FALSE)
a1 = rnorm(1000,100,10)
b1 = rnorm(1000,100,9)
c1 = sample.int(1000, 1000, replace = TRUE)
train_data = data.frame(a1,b1,c1)
obj.fun = makeMultiObjectiveFunction(
name = "Some function",
fn = function(x) {
#bin data according to random criteria
train_data <- train_data %>%
mutate(cat = ifelse(a1 <= x[1] & b1 <= x[3], "a",
ifelse(a1 <= x[2] & b1 <= x[4], "b", "c")))
train_data$cat = as.factor(train_data$cat)
#new splits
a_table = train_data %>%
filter(cat == "a") %>%
select(a1, b1, c1, cat)
b_table = train_data %>%
filter(cat == "b") %>%
select(a1, b1, c1, cat)
c_table = train_data %>%
filter(cat == "c") %>%
select(a1, b1, c1, cat)
#calculate quantile ("quant") for each bin
table_a = data.frame(a_table%>% group_by(cat) %>%
mutate(quant = ifelse(c1 > 150,1,0 )))
table_b = data.frame(b_table%>% group_by(cat) %>%
mutate(quant = ifelse(c1 > 300,1,0 )))
table_c = data.frame(c_table%>% group_by(cat) %>%
mutate(quant = ifelse(c1 > 400,1,0 )))
f1 = mean(table_a$quant)
f2 = mean(table_b$quant)
f3 = mean(table_c$quant)
#group all tables
final_table = rbind(table_a, table_b, table_c)
# calculate the total mean : this is what needs to be optimized
f4 = mean(final_table$quant)
return (c(f1,f2,f3));
},
n.objectives = 3L,
par.set = makeParamSet(
makeNumericParam("x[1]", lower = 80, upper = 95),
makeNumericParam("x[2]", lower = 90, upper = 120),
makeNumericParam("x[3]", lower = 80, upper = 95),
makeNumericParam("x[4]", lower = 90, upper = 120)
),
minimize = c(TRUE,TRUE,TRUE)
)
ctrl = makeMBOControl(n.objectives = 3L, propose.points = 3L,)
ctrl = setMBOControlTermination(ctrl, iters = 15L)
# we can basically do an exhaustive search in 3 values
ctrl = setMBOControlInfill(ctrl, crit = makeMBOInfillCritEI())
# opt.restarts = 1L, opt.focussearch.points = 3L, opt.focussearch.maxit = 1L)
ctrl = setMBOControlMultiObj(ctrl, method = "parego")
#design = generateDesign(10L, getParamSet(obj.fun), fun = lhs::maximinLHS)
lrn = makeMBOLearner(ctrl, obj.fun)
res = mbo(obj.fun, design = NULL, learner = lrn, control = ctrl, show.info = TRUE)
如您所见,输出现在有3列:
res
y_1 y_2 y_3
2 0.9622642 0.7101266 0.5732484
12 1.0000000 0.6953642 0.5973716
21 0.9425287 0.6666667 0.5986770
25 0.9325843 0.7103695 0.5416667
31 0.9350649 0.4893617 0.6107306
33 1.0000000 0.7092652 0.5116279
34 0.9466667 0.4782609 0.6097838
36 0.9358974 0.4791667 0.6121281
37 0.9340659 0.5294118 0.6045714
40 0.9305556 0.4791667 0.6125000
42 0.9324324 0.7141074 0.5680000
44 0.9200000 0.5294118 0.6069869
47 0.9272727 0.5000000 0.6063947
48 1.0000000 0.7108307 0.5000000
49 0.9493671 0.7127533 0.5365854
51 0.9325843 0.7109005 0.5373134
Optimization path
16 + 45 entries in total, displaying last 10 (or less):
x.1. x.2. x.3. x.4. y_1 y_2 y_3 dob eol error.message exec.time ei error.model parego.weight.1 parego.weight.2 parego.weight.3
52 94.33683 100.7321 94.99962 91.37012 0.9431818 0.5681818 0.6048387 12 NA <NA> 0.02 -4.005640e-03 <NA> 0.03555556 0.700000000 0.26444444
53 94.99492 119.1423 93.73171 90.01557 0.9342105 0.6400000 0.6092233 13 NA <NA> 0.01 -1.989663e-02 <NA> 0.78222222 0.028888889 0.18888889
54 94.99999 101.4437 91.66617 90.15968 0.9285714 0.5128205 0.6077348 13 NA <NA> 0.02 -2.262719e-02 <NA> 0.61777778 0.342222222 0.04000000
55 91.50198 104.9947 94.99154 90.67498 0.9545455 0.5492958 0.6129780 13 NA <NA> 0.01 -7.663698e-05 <NA> 0.28444444 0.433333333 0.28222222
56 94.97888 119.5606 94.99947 113.30367 0.9340659 0.7133995 0.5631068 14 NA <NA> 0.01 -2.042355e-02 <NA> 0.63333333 0.162222222 0.20444444
57 84.87547 119.7105 90.95901 119.98932 1.0000000 0.7115589 0.5238095 14 NA <NA> 0.02 -9.210598e-03 <NA> 0.20888889 0.004444444 0.78666667
58 80.01872 103.9226 94.99121 90.66585 1.0000000 0.6021505 0.6118568 14 NA <NA> 0.01 -8.465880e-05 <NA> 0.19111111 0.508888889 0.30000000
59 92.07052 114.9004 93.96324 119.99836 0.9642857 0.7117853 0.5402299 15 NA <NA> 0.02 -4.013597e-03 <NA> 0.25777778 0.077777778 0.66444444
60 94.99777 102.6057 93.45827 90.59632 0.9315068 0.4897959 0.6127563 15 NA <NA> 0.01 -2.856281e-02 <NA> 0.23555556 0.713333333 0.05111111
61 94.85198 116.3001 94.77291 114.99281 0.9397590 0.7132262 0.5555556 15 NA <NA> 0.02 -1.050656e-02 <NA> 0.35111111 0.275555556 0.37333333
train.time prop.type propose.time
52 NA infill_ei 0.31
53 0.44 infill_ei 0.33
54 NA infill_ei 0.31
55 NA infill_ei 0.33
56 0.40 infill_ei 0.33
57 NA infill_ei 0.34
58 NA infill_ei 0.33
59 0.58 infill_ei 0.34
60 NA infill_ei 0.35
61 NA infill_ei 0.34
有人可以确认我所做的是否有意义吗?
谢谢!