---
primary_layer: layer2
related_layers: []
page_type: concept
---
# EGO(Efficient Global Optimization)
## 概要
EGOは、評価コストの高い目的関数を対象に、Gaussian Process回帰(GP)によるサロゲートモデルと**期待改善量**(Expected Improvement, EI)という獲得関数を組み合わせた逐次最適化の手法です。
GPの予測分散は学習データから離れた領域ほど大きくなります。 EIはこの予測平均と予測分散の両方から計算されるスカラー値であるため、「予測値が良さそうな領域」と「予測の不確実性が高い領域」を自然に両方カバーし、探索と活用のバランスを取ります。
出典は{cite}`jones1998ego`。具体的な手順は次の擬似コードに示します。
## 擬似コード
```{prf:algorithm} EGO
:label: alg-ego
**Inputs** 目的関数 $f$、探索範囲、初期サンプル数 $n_0$、評価予算 $N$
**Output** 最良解 $x^*$
初期個体群を $n_0$ 点サンプリングし、真の関数 $f$ で評価してアーカイブに追加する
アーカイブ全体にGPを当てはめ、任意の点における予測平均 $\mu(x)$ と予測標準偏差 $\sigma(x)$ を得る
期待改善量 $\mathrm{EI}(x) = (f_{\min} - \mu(x) - \xi)\,\Phi(z) + \sigma(x)\,\phi(z)$($z = (f_{\min} - \mu(x) - \xi) / \sigma(x)$)を最大化する点 $x^*$ を求める
$x^*$ を真の関数で評価し、アーカイブに追加する
評価予算 $N$ に達するまで2へ戻る
```
## フローチャート
```{mermaid}
flowchart TD
INIT["初期化器
初期個体群をサンプリング
LHSなどでサンプリング→真の評価
(L1)"] --> ASK
subgraph GEN["1世代 (IndividualBasedStrategy.step)"]
direction TB
ASK["GA.ask()
候補を生成"] --> SCORE["SurrogateManager
GPをフィット (L2)
→ EIでスコア化 (L3)"]
SCORE --> SORT["上位を選択
EIによるevaluation_ratioの割合
(argmax EIを近似)"]
SORT --> EVAL["真の評価 →
アーカイブに追加
(L4)"]
EVAL --> TELL["GA.tell()
個体群を更新"]
end
GEN --> TERM{"評価予算N
に達したか?"}
TERM -- "未達 (L5)" --> ASK
TERM -- "到達" --> RESULT(["最良解x*"])
```
## saealibでの構成
|役割|saealibでの実装|対応ステップ|
|---|---|---|
|探索アルゴリズム本体|`GA`(交叉、突然変異、選択の組み合わせ自体はEGOの定義に含まれない)|L3|
|サロゲートモデル|`SklearnGPRSurrogate`(GP回帰。`sklearn` extraが必要)|L2|
|獲得関数|`ExpectedImprovement`|L3|
|サロゲート管理|`GlobalSurrogateManager`(アーカイブ全体でGPをフィットする)|L2-3|
|評価戦略|`IndividualBasedStrategy`(EI上位の個体だけを真に評価する)|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()
```
## 原法との差分
EGOの原法は獲得関数の最大化点を一度に1点ずつ求めます。一方、saealibは`GA`が生成した候補プールからEIが最大の候補を選び、`argmax EI`を近似します。`IndividualBasedStrategy.evaluation_ratio`により、選択した複数の候補をまとめて真の評価に回すこともできます。例の交叉、突然変異、親選択、環境選択の組み合わせはsaealibの構成上の選択であり、EGOの定義の一部ではありません。
## パラメータと変種
**ξ(探索と活用のトレードオフ)**:`ExpectedImprovement(xi=...)`で調整します。既定値の`0.01`は、EGOの原提案で規定された値ではなく、実用上のヒューリスティックです。Brochu et al. (2010)は、この値が先行実験で使われたことを紹介しています{cite}`brochu2010tutorial`。$\xi=0$では活用寄りになり、大きくすると探索寄りになります。
## 関連
- [文献リファレンス](../references.md):出典の完全な書誌情報と、EI以外の獲得関数の出典一覧
- [SurrogateManager](../concepts/surrogate_modeling/surrogate_manager.md):`GlobalSurrogateManager`の詳しい使い方
- [AcquisitionFunction](../concepts/surrogate_modeling/acquisition_functions.md):`ExpectedImprovement`を含む獲得関数一覧
- [Surrogate](../concepts/surrogate_modeling/surrogate.md):`SklearnGPRSurrogate`を含むサロゲートモデルの一覧と、`sklearn` extraの説明
- [OptimizationStrategy](../concepts/execution_and_evaluation/strategies.md):`IndividualBasedStrategy`の`evaluation_ratio`を含む戦略の一覧