Building GP surrogate models from optimization data#

The ExplorationDiagnostics class provides a simple way of fitting a Gaussian process (GP) model to any of the objectives or analyzed parameters of an optimas Exploration, independently of which generator was used. This is useful to get a better understanding of the underlying function, make predictions, etc.

In this example, we will illustrate how to build GP models by using a basic optimization that runs directly on a Jupyter notebook. This optimization uses an RandomSamplingGenerator and a simple FunctionEvaluator that evaluates an analytical function.

Set up example optimization#

The following cell sets up and runs an optimization with two input parameters x1 and x2, two objectives f1 and f2, and one additional analyzed parameter p1. At each evaluation, the eval_func_sf_moo function is run, which assigns a value to each outcome parameter according to the analytical formulas

\[f_1(x_1, x_2) = -(x_1 + 10 \cos(x_1)) (x_2 + 5\cos(x_2))\]
\[f_2(x_1, x_2) = 2 f_1(x_1, x_2)\]
\[p_1(x_1, x_2) = \sin(x_1) + \cos(x_2)\]
[1]:
import numpy as np
from optimas.explorations import Exploration
from optimas.core import VaryingParameter, Objective, Parameter
from optimas.generators import RandomSamplingGenerator
from optimas.evaluators import FunctionEvaluator


def eval_func_sf_moo(input_params, output_params):
    """Example multi-objective function."""
    x1 = input_params["x1"]
    x2 = input_params["x2"]
    result = -(x1 + 10 * np.cos(x1)) * (x2 + 5 * np.cos(x2))
    output_params["f1"] = result
    output_params["f2"] = result * 2
    output_params["p1"] = np.sin(x1) + np.cos(x2)


var1 = VaryingParameter("x1", 0.0, 5.0)
var2 = VaryingParameter("x2", -5.0, 5.0)
par1 = Parameter("p1")
obj1 = Objective("f1", minimize=True)
obj2 = Objective("f2", minimize=False)

gen = RandomSamplingGenerator(
    varying_parameters=[var1, var2],
    objectives=[obj1, obj2],
    analyzed_parameters=[par1],
)
ev = FunctionEvaluator(function=eval_func_sf_moo)
exploration = Exploration(
    generator=gen,
    evaluator=ev,
    max_evals=50,
    sim_workers=1,
    exploration_dir_path="./exploration",
    libe_comms="threads",  #this is only needed to run on a Jupyter notebook.
)

# Run exploration.
exploration.run()
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 0 with parameters {'x1': np.float64(0.8212964512984888), 'x2': np.float64(-2.477528215628074)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 0 with objective(s) {'f1': np.float64(48.972239326849525), 'f2': np.float64(97.94447865369905)} and analyzed parameter(s) {'p1': np.float64(-0.05546405615994199)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 1 with parameters {'x1': np.float64(1.9582984151281446), 'x2': np.float64(-3.5813881512744663)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 1 with objective(s) {'f1': np.float64(-14.755972636670831), 'f2': np.float64(-29.511945273341663)} and analyzed parameter(s) {'p1': np.float64(0.02101710052763317)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 2 with parameters {'x1': np.float64(0.8160253004006685), 'x2': np.float64(-3.7759000960726885)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 2 with objective(s) {'f1': np.float64(59.829896521459325), 'f2': np.float64(119.65979304291865)} and analyzed parameter(s) {'p1': np.float64(-0.07705387580899459)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 3 with parameters {'x1': np.float64(0.3834213208413251), 'x2': np.float64(-1.9367208789352586)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 3 with objective(s) {'f1': np.float64(35.98110730906116), 'f2': np.float64(71.96221461812232)} and analyzed parameter(s) {'p1': np.float64(0.01628276407880752)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 4 with parameters {'x1': np.float64(3.6548577332096013), 'x2': np.float64(-1.0315589606492903)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 4 with objective(s) {'f1': np.float64(7.766179666568277), 'f2': np.float64(15.532359333136554)} and analyzed parameter(s) {'p1': np.float64(0.022457504564718955)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 5 with parameters {'x1': np.float64(3.2070324410311493), 'x2': np.float64(-1.9757992731932839)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 5 with objective(s) {'f1': np.float64(-26.719956697580958), 'f2': np.float64(-53.439913395161916)} and analyzed parameter(s) {'p1': np.float64(-0.4594145596674733)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 6 with parameters {'x1': np.float64(3.216654678676129), 'x2': np.float64(1.3250347685674626)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 6 with objective(s) {'f1': np.float64(17.168376148664304), 'f2': np.float64(34.33675229732861)} and analyzed parameter(s) {'p1': np.float64(0.1683035125898169)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 7 with parameters {'x1': np.float64(4.6758582790144025), 'x2': np.float64(-0.19971009405264972)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 7 with objective(s) {'f1': np.float64(-20.263897912778308), 'f2': np.float64(-40.527795825556616)} and analyzed parameter(s) {'p1': np.float64(-0.01920869605236697)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 8 with parameters {'x1': np.float64(4.488862801861706), 'x2': np.float64(-1.7880029055968363)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 8 with objective(s) {'f1': np.float64(6.510935408705737), 'f2': np.float64(13.021870817411473)} and analyzed parameter(s) {'p1': np.float64(-1.190624549758666)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 9 with parameters {'x1': np.float64(3.1555511493334425), 'x2': np.float64(0.2674199737725358)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 9 with objective(s) {'f1': np.float64(34.83122811926318), 'f2': np.float64(69.66245623852636)} and analyzed parameter(s) {'p1': np.float64(0.9504978195489251)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 10 with parameters {'x1': np.float64(1.623900467334733), 'x2': np.float64(-0.4092243471160515)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 10 with objective(s) {'f1': np.float64(-4.566925068307046), 'f2': np.float64(-9.133850136614091)} and analyzed parameter(s) {'p1': np.float64(1.9160200358326493)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 11 with parameters {'x1': np.float64(3.5651710701268997), 'x2': np.float64(-4.670954321599132)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 11 with objective(s) {'f1': np.float64(-27.078491680147906), 'f2': np.float64(-54.15698336029581)} and analyzed parameter(s) {'p1': np.float64(-0.4524480517059488)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 12 with parameters {'x1': np.float64(2.713793746716653), 'x2': np.float64(3.3761186552959046)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 12 with objective(s) {'f1': np.float64(-9.494548648151765), 'f2': np.float64(-18.98909729630353)} and analyzed parameter(s) {'p1': np.float64(-0.5577555233059994)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 13 with parameters {'x1': np.float64(1.1349445525217117), 'x2': np.float64(1.4864879513660059)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 13 with objective(s) {'f1': np.float64(-10.218205736374179), 'f2': np.float64(-20.436411472748357)} and analyzed parameter(s) {'p1': np.float64(0.9907193017994133)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 14 with parameters {'x1': np.float64(0.6298598945547462), 'x2': np.float64(-4.414051941531786)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 14 with objective(s) {'f1': np.float64(51.252742563458796), 'f2': np.float64(102.50548512691759)} and analyzed parameter(s) {'p1': np.float64(0.2951004317983071)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 15 with parameters {'x1': np.float64(3.4335429133366464), 'x2': np.float64(4.422944257252869)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 15 with objective(s) {'f1': np.float64(18.404369677924684), 'f2': np.float64(36.80873935584937)} and analyzed parameter(s) {'p1': np.float64(-0.5732405949567575)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 16 with parameters {'x1': np.float64(4.49869437054682), 'x2': np.float64(-3.202690678505201)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 16 with objective(s) {'f1': np.float64(19.483610096384147), 'f2': np.float64(38.967220192768295)} and analyzed parameter(s) {'p1': np.float64(-1.9753881595875415)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 17 with parameters {'x1': np.float64(2.5614751492387615), 'x2': np.float64(1.352179491221789)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 17 with objective(s) {'f1': np.float64(14.13825843318657), 'f2': np.float64(28.27651686637314)} and analyzed parameter(s) {'p1': np.float64(0.7650018091318969)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 18 with parameters {'x1': np.float64(1.9094230952400388), 'x2': np.float64(2.0639457724313335)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 18 with objective(s) {'f1': np.float64(-0.4280806488849481), 'f2': np.float64(-0.8561612977698962)} and analyzed parameter(s) {'p1': np.float64(0.46980932259611746)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 19 with parameters {'x1': np.float64(1.3350598983875595), 'x2': np.float64(1.313380861016677)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 19 with objective(s) {'f1': np.float64(-9.493371633411233), 'f2': np.float64(-18.986743266822465)} and analyzed parameter(s) {'p1': np.float64(1.2269246335265582)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 20 with parameters {'x1': np.float64(4.621752481768424), 'x2': np.float64(3.0419610045054526)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 20 with objective(s) {'f1': np.float64(7.185146274026251), 'f2': np.float64(14.370292548052502)} and analyzed parameter(s) {'p1': np.float64(-1.9909361952036138)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 21 with parameters {'x1': np.float64(0.07328345972671346), 'x2': np.float64(-2.822865040406519)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 21 with objective(s) {'f1': np.float64(76.06201830797453), 'f2': np.float64(152.12403661594905)} and analyzed parameter(s) {'p1': np.float64(-0.8764170169718518)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 22 with parameters {'x1': np.float64(4.575086584924012), 'x2': np.float64(-0.33263114844183317)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 22 with objective(s) {'f1': np.float64(-14.086560486490624), 'f2': np.float64(-28.17312097298125)} and analyzed parameter(s) {'p1': np.float64(-0.045402360455491064)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 23 with parameters {'x1': np.float64(2.9373475457245526), 'x2': np.float64(-1.242234280764115)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 23 with objective(s) {'f1': np.float64(2.544345177217861), 'f2': np.float64(5.088690354435722)} and analyzed parameter(s) {'p1': np.float64(0.525510345042746)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 24 with parameters {'x1': np.float64(3.1451740612653394), 'x2': np.float64(-0.07234994835847974)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 24 with objective(s) {'f1': np.float64(33.68820310772583), 'f2': np.float64(67.37640621545167)} and analyzed parameter(s) {'p1': np.float64(0.9938024839404852)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 25 with parameters {'x1': np.float64(4.96480569839699), 'x2': np.float64(-4.2006666964424975)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 25 with objective(s) {'f1': np.float64(49.61701046584393), 'f2': np.float64(99.23402093168787)} and analyzed parameter(s) {'p1': np.float64(-1.457991323170653)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 26 with parameters {'x1': np.float64(2.1048240605124144), 'x2': np.float64(3.5209330785949113)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 26 with objective(s) {'f1': np.float64(-3.354229826879184), 'f2': np.float64(-6.708459653758368)} and analyzed parameter(s) {'p1': np.float64(-0.06814515958070277)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 27 with parameters {'x1': np.float64(1.3207535858702746), 'x2': np.float64(-0.8304359484793249)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 27 with objective(s) {'f1': np.float64(-9.64868466905111), 'f2': np.float64(-19.29736933810222)} and analyzed parameter(s) {'p1': np.float64(1.6434558424436203)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 28 with parameters {'x1': np.float64(2.564301920494793), 'x2': np.float64(3.761472450220772)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 28 with objective(s) {'f1': np.float64(-1.792627882017907), 'f2': np.float64(-3.585255764035814)} and analyzed parameter(s) {'p1': np.float64(-0.2681925654582845)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 29 with parameters {'x1': np.float64(0.06918188391156821), 'x2': np.float64(0.055117016594472545)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 29 with objective(s) {'f1': np.float64(-50.70369704370224), 'f2': np.float64(-101.40739408740448)} and analyzed parameter(s) {'p1': np.float64(1.0676081532324837)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 30 with parameters {'x1': np.float64(1.0991846049835874), 'x2': np.float64(-0.21568955881103058)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 30 with objective(s) {'f1': np.float64(-26.34134643988706), 'f2': np.float64(-52.68269287977412)} and analyzed parameter(s) {'p1': np.float64(1.8676662501650947)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 31 with parameters {'x1': np.float64(1.2075096898910798), 'x2': np.float64(-3.911058431824154)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 31 with objective(s) {'f1': np.float64(35.71920661724276), 'f2': np.float64(71.43841323448552)} and analyzed parameter(s) {'p1': np.float64(0.2164515157549124)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 32 with parameters {'x1': np.float64(3.3904594996000075), 'x2': np.float64(1.8762239569172046)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 32 with objective(s) {'f1': np.float64(2.348673025015217), 'f2': np.float64(4.697346050030434)} and analyzed parameter(s) {'p1': np.float64(-0.5470069151039361)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 33 with parameters {'x1': np.float64(1.0245678681240966), 'x2': np.float64(-4.160076880028553)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 33 with objective(s) {'f1': np.float64(42.18742015442817), 'f2': np.float64(84.37484030885634)} and analyzed parameter(s) {'p1': np.float64(0.32983283816819386)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 34 with parameters {'x1': np.float64(3.5657026898154642), 'x2': np.float64(-2.7891615308463424)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 34 with objective(s) {'f1': np.float64(-41.51188810270417), 'f2': np.float64(-83.02377620540834)} and analyzed parameter(s) {'p1': np.float64(-1.350046138091889)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 35 with parameters {'x1': np.float64(3.1938806824473454), 'x2': np.float64(4.880352709480887)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 35 with objective(s) {'f1': np.float64(38.82720651022608), 'f2': np.float64(77.65441302045215)} and analyzed parameter(s) {'p1': np.float64(0.11491087624937116)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 36 with parameters {'x1': np.float64(4.0466686353081975), 'x2': np.float64(0.5637856105862706)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 36 with objective(s) {'f1': np.float64(10.200684202383433), 'f2': np.float64(20.401368404766867)} and analyzed parameter(s) {'p1': np.float64(0.05876609529320864)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 37 with parameters {'x1': np.float64(4.842311235369349), 'x2': np.float64(-1.0463190872675767)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 37 with objective(s) {'f1': np.float64(-8.945863291930534), 'f2': np.float64(-17.891726583861068)} and analyzed parameter(s) {'p1': np.float64(-0.49081139007025554)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 38 with parameters {'x1': np.float64(2.592621213457465), 'x2': np.float64(0.5062853485322725)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 38 with objective(s) {'f1': np.float64(28.971746792396356), 'f2': np.float64(57.94349358479271)} and analyzed parameter(s) {'p1': np.float64(1.3963619705582495)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 39 with parameters {'x1': np.float64(2.200647732283183), 'x2': np.float64(4.745268663410636)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 39 with objective(s) {'f1': np.float64(18.114593938169396), 'f2': np.float64(36.22918787633879)} and analyzed parameter(s) {'p1': np.float64(0.840988802188898)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 40 with parameters {'x1': np.float64(4.011585242263125), 'x2': np.float64(-3.722344259720496)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 40 with objective(s) {'f1': np.float64(-19.256549136805493), 'f2': np.float64(-38.513098273610986)} and analyzed parameter(s) {'p1': np.float64(-1.600374673523842)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 41 with parameters {'x1': np.float64(3.4162435843265104), 'x2': np.float64(1.5200348176171588)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 41 with objective(s) {'f1': np.float64(11.01303195795313), 'f2': np.float64(22.02606391590626)} and analyzed parameter(s) {'p1': np.float64(-0.22047125516896116)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 42 with parameters {'x1': np.float64(1.0152542742235409), 'x2': np.float64(0.4224347326280462)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 42 with objective(s) {'f1': np.float64(-31.338932511131897), 'f2': np.float64(-62.677865022263795)} and analyzed parameter(s) {'p1': np.float64(1.7617081317082575)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 43 with parameters {'x1': np.float64(4.043309499818845), 'x2': np.float64(3.621200792748658)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 43 with objective(s) {'f1': np.float64(-1.7591612227100395), 'f2': np.float64(-3.518322445420079)} and analyzed parameter(s) {'p1': np.float64(-1.6715687712311258)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 44 with parameters {'x1': np.float64(0.7691423332905112), 'x2': np.float64(-3.676511247369001)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 44 with objective(s) {'f1': np.float64(63.459234866545266), 'f2': np.float64(126.91846973309053)} and analyzed parameter(s) {'p1': np.float64(-0.16479087607111886)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 45 with parameters {'x1': np.float64(3.3012111411982565), 'x2': np.float64(2.266144040076022)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 45 with objective(s) {'f1': np.float64(-6.158430931851315), 'f2': np.float64(-12.31686186370263)} and analyzed parameter(s) {'p1': np.float64(-0.7995940188727413)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 46 with parameters {'x1': np.float64(1.1787974031842385), 'x2': np.float64(0.6306444599322845)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 46 with objective(s) {'f1': np.float64(-23.34050208812699), 'f2': np.float64(-46.68100417625398)} and analyzed parameter(s) {'p1': np.float64(1.7317949052861705)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 47 with parameters {'x1': np.float64(0.3332102578838775), 'x2': np.float64(-1.3800913190447686)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 47 with objective(s) {'f1': np.float64(4.229616797648498), 'f2': np.float64(8.459233595296997)} and analyzed parameter(s) {'p1': np.float64(0.5166295618981994)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 48 with parameters {'x1': np.float64(1.6850905318395137), 'x2': np.float64(2.124446528064623)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 48 with objective(s) {'f1': np.float64(0.2747857018659259), 'f2': np.float64(0.5495714037318518)} and analyzed parameter(s) {'p1': np.float64(0.46767989853056)}
[INFO 07-10 23:32:36] optimas.generators.base: Generated trial 49 with parameters {'x1': np.float64(2.7991960455772573), 'x2': np.float64(1.0972469811291452)}
[INFO 07-10 23:32:36] optimas.generators.base: Completed trial 49 with objective(s) {'f1': np.float64(22.36007934186243), 'f2': np.float64(44.72015868372486)} and analyzed parameter(s) {'p1': np.float64(0.7917934557131326)}

Initialize diagnostics#

The diagnostics class only requires the path to the exploration directory as input parameter, or directly the exploration instance.

[2]:
from optimas.diagnostics import ExplorationDiagnostics

diags = ExplorationDiagnostics(exploration)

Building a GP model of each objective and analyzed parameter#

To build a GP model, simply call build_gp_model() on the diagnostics, indicating the name of the variable to which the model should be fitted. This variable can be any objective or analyzed_parameter of the optimization.

Note that when building a surrogate model of an analyzed parameter, it is required to provide a value to the minimize argument. This parameter should therefore be True if lower values of the analyzed parameter are better than higher values. This information is necessary, e.g., for determining the best point in the model.

[3]:
# Build one model for each objective and analyzed parameter.
f1_model = diags.build_gp_model("f1")
f2_model = diags.build_gp_model("f2")
p1_model = diags.build_gp_model("p1", minimize=False)

Visualizing the surrogate models#

The models provide some basic plotting methods for easy visualization, like plot_contour() and plot_slice().

[4]:
# plot model for `f1`.
fig, ax1 = f1_model.plot_contour(mode="both", figsize=(6, 3), dpi=300)
../../_images/user_guide_advanced_usage_build_gp_surrogates_7_0.png
[5]:
# plot 1D slice of `f1`.
fig, ax1 = f1_model.plot_slice("x1", figsize=(6, 3), dpi=300)
../../_images/user_guide_advanced_usage_build_gp_surrogates_8_0.png

These methods also allow more complex plot compositions to be created, such as in the example below, by providing a subplot_spec where the plot should be drawn.

[6]:
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec

fig = plt.figure(figsize=(10, 3), dpi=300)
gs = GridSpec(1, 3, wspace=0.4)

# plot model for `f1`.
fig, ax1 = f1_model.plot_contour(
    pcolormesh_kw={"cmap": "GnBu"},
    subplot_spec=gs[0, 0],
)

# Get and draw top 3 evaluations for `f`
df_top = diags.get_best_evaluations(top=3, objective="f1")
ax1.scatter(df_top["x1"], df_top["x2"], c="red", marker="x")

# plot model for `f2`
fig, ax2 = f2_model.plot_contour(
    pcolormesh_kw={"cmap": "OrRd"},
    subplot_spec=gs[0, 1],
)

# plot model for `p1`
fig, ax3 = p1_model.plot_contour(
    pcolormesh_kw={"cmap": "PuBu"},
    subplot_spec=gs[0, 2],
)
../../_images/user_guide_advanced_usage_build_gp_surrogates_10_0.png

Evaluating the surrogate model#

In addition to plotting, it is also possible to evaluate the model at any point by using the evaluate_model() method.

In the example below, this method is used to evaluate the model in all the history points to create a cross-validation plot.

[7]:
# Evaluate model for each point in the history
mean, sem = f1_model.evaluate_model(diags.history)
min_f, max_f = np.min(diags.history["f1"]), np.max(diags.history["f1"])

# Make plot
fig, ax = plt.subplots(figsize=(5, 4), dpi=300)
ax.errorbar(diags.history["f1"], mean, yerr=sem, fmt="o", ms=4, label="Data")
ax.plot([min_f, max_f], [min_f, max_f], color="k", ls="--", label="Ideal correlation")
ax.set_xlabel("Observations")
ax.set_ylabel("Model predictions")
ax.legend(frameon=False)
[7]:
<matplotlib.legend.Legend at 0x77ced511f010>
../../_images/user_guide_advanced_usage_build_gp_surrogates_12_1.png