【问题标题】:R Error: Code Returns 1 Column Instead of 4 ColumnsR 错误:代码返回 1 列而不是 4 列
【发布时间】:2021-08-06 23:57:08
【问题描述】:

我在 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.1., y.2., y.3., y.4.”(对应于函数“fn”中的“f1, f2, f3, f4”) - 因为有 4 个“输出”(即“目标”)进行优化。而是只返回一列。

有人知道为什么会这样吗?为什么只返回一个“Y”列而不是四个?

谢谢

【问题讨论】:

    标签: r algorithm optimization bayesian


    【解决方案1】:

    我想我能够弄清楚这一点 - 但我不确定我是否正确?我发布了以下代码:

         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
    

    有人可以确认我所做的是否有意义吗?

    谢谢!

    【讨论】:

      猜你喜欢
      • 2016-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 2016-10-17
      相关资源
      最近更新 更多