--- primary_layer: layer2 related_layers: [] page_type: concept --- # EGO (Efficient Global Optimization) ## Overview EGO is a sequential optimization method for expensive-to-evaluate objective functions, combining a surrogate model built from Gaussian Process (GP) regression with the **Expected Improvement** (EI) acquisition function. A GP's predictive variance grows larger in regions farther from the training data. Because EI is a scalar value computed from both this predictive mean and predictive variance, it naturally covers both "regions that look promising" and "regions with high predictive uncertainty," balancing exploration and exploitation. The source is {cite}`jones1998ego`. The concrete procedure is shown in the pseudocode below. ## Pseudocode ```{prf:algorithm} EGO :label: alg-ego **Inputs** objective function $f$, search domain, initial sample count $n_0$, evaluation budget $N$ **Output** best solution $x^*$ 1. Sample an initial population of $n_0$ points, evaluate them with the true function $f$, and add them to the archive 2. Fit a GP to the entire archive, obtaining the predictive mean $\mu(x)$ and predictive standard deviation $\sigma(x)$ at any point 3. Find the point $x^*$ that maximizes the Expected Improvement $\mathrm{EI}(x) = (f_{\min} - \mu(x) - \xi)\,\Phi(z) + \sigma(x)\,\phi(z)$ (where $z = (f_{\min} - \mu(x) - \xi) / \sigma(x)$) 4. Evaluate $x^*$ with the true function and add it to the archive 5. Return to step 2 until the evaluation budget $N$ is reached ``` ## Flowchart ```{mermaid} flowchart TD INIT["Initializer
Sample initial population
via LHS etc. → true evaluation
(L1)"] --> ASK subgraph GEN["One generation (IndividualBasedStrategy.step)"] direction TB ASK["GA.ask()
Generate candidates"] --> SCORE["SurrogateManager
Fit GP (L2)
→ Score with EI (L3)"] SCORE --> SORT["Select top
evaluation_ratio fraction by EI
(approximates argmax EI)"] SORT --> EVAL["True evaluation →
add to archive
(L4)"] EVAL --> TELL["GA.tell()
Update population"] end GEN --> TERM{"Evaluation budget N
reached?"} TERM -- "Not yet (L5)" --> ASK TERM -- "Reached" --> RESULT(["Best solution x*"]) ``` ## Configuration in saealib | Role | saealib implementation | Corresponding step | |---|---|---| | Search algorithm | `GA` (the specific combination of crossover, mutation, and selection is not part of EGO's definition) | L3 | | Surrogate model | `SklearnGPRSurrogate` (GP regression; requires the `sklearn` extra) | L2 | | Acquisition function | `ExpectedImprovement` | L3 | | Surrogate management | `GlobalSurrogateManager` (fits the GP over the entire archive) | L2-3 | | Evaluation strategy | `IndividualBasedStrategy` (truly evaluates only the individuals with the top EI scores) | L3-4 | ```python import numpy as np from saealib import ( GA, Optimizer, Problem, IndividualBasedStrategy, SklearnGPRSurrogate, ExpectedImprovement, ) from saealib.operators.crossover import CrossoverBLXAlpha from saealib.operators.mutation import MutationUniform from saealib.operators.selection import SequentialSelection, TruncationSelection from saealib.surrogate import GlobalSurrogateManager from saealib.termination import Termination, max_fe def sphere(x: np.ndarray) -> float: return np.sum(x**2) problem = Problem(sphere, dim=5, lb=[-5] * 5, ub=[5] * 5, n_obj=1, direction=[-1]) algorithm = GA( CrossoverBLXAlpha(prob=0.7, alpha=0.4), MutationUniform(prob_var=0.3), SequentialSelection(), TruncationSelection(), ) surrogate_manager = GlobalSurrogateManager(SklearnGPRSurrogate()) strategy = IndividualBasedStrategy(evaluation_ratio=0.2) opt = ( Optimizer(problem) .set_algorithm(algorithm) .set_surrogate_manager(surrogate_manager) .set_acquisition(ExpectedImprovement()) .set_strategy(strategy) .set_termination(Termination(max_fe(200))) ) ctx = opt.run() ``` ## Differences from the source The original EGO finds the acquisition-function maximizer one point at a time, whereas saealib approximates `argmax EI` by selecting the highest-EI candidates from the pool generated by `GA`. `IndividualBasedStrategy.evaluation_ratio` also allows several selected candidates to receive true evaluations together. The crossover, mutation, parent-selection, and environmental-selection combination in the example is an saealib configuration choice, not part of the EGO definition. ## Parameters and variants **ξ (exploration–exploitation trade-off)**: Adjusted via `ExpectedImprovement(xi=...)`. The default is `0.01`, a practical heuristic rather than a value prescribed by the original EGO formulation. Brochu et al. (2010) discuss prior experimental use of this value {cite}`brochu2010tutorial`. $\xi=0$ leans toward exploitation, and larger values lean toward exploration. ## Related - [References](../references.md): Full bibliographic details for the source, and a list of sources for acquisition functions other than EI - [SurrogateManager](../concepts/surrogate_modeling/surrogate_manager.md): Detailed usage of `GlobalSurrogateManager` - [AcquisitionFunction](../concepts/surrogate_modeling/acquisition_functions.md): List of acquisition functions including `ExpectedImprovement` - [Surrogate](../concepts/surrogate_modeling/surrogate.md): List of surrogate models including `SklearnGPRSurrogate`, and an explanation of the `sklearn` extra - [OptimizationStrategy](../concepts/execution_and_evaluation/strategies.md): List of strategies including `IndividualBasedStrategy`'s `evaluation_ratio`