Skip to content

Commit cab68c4

Browse files
committed
Fix calibrate module init and add first controller tests
1 parent a0bada5 commit cab68c4

File tree

3 files changed

+56
-26
lines changed

3 files changed

+56
-26
lines changed

climada/util/calibrate/__init__.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,9 @@
1919
"""
2020

2121
from .base import Input, OutputEvaluator
22-
from .bayesian_optimizer import BayesianOptimizer, BayesianOptimizerOutputEvaluator
22+
from .bayesian_optimizer import (
23+
BayesianOptimizer,
24+
BayesianOptimizerController,
25+
BayesianOptimizerOutputEvaluator,
26+
)
2327
from .scipy_optimizer import ScipyMinimizeOptimizer

climada/util/calibrate/test/test_bayesian_optimizer.py

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,51 @@
2424
import numpy.testing as npt
2525
import pandas as pd
2626

27-
from climada.util.calibrate import Input, BayesianOptimizer
27+
from climada.util.calibrate import Input, BayesianOptimizer, BayesianOptimizerController
2828

2929
from .test_base import hazard, exposure
3030

3131

32+
def input():
33+
"""Return a mocked input"""
34+
return Input(
35+
hazard=hazard(),
36+
exposure=exposure(),
37+
data=pd.DataFrame(data={"col1": [1, 2], "col2": [2, 3]}, index=[0, 1]),
38+
cost_func=MagicMock(),
39+
impact_func_creator=MagicMock(),
40+
impact_to_dataframe=MagicMock(),
41+
)
42+
43+
44+
class TestBayesianOptimizerController(unittest.TestCase):
45+
"""Tests for the controller of the BayesianOptimizer"""
46+
47+
def test_kappa_decay(self):
48+
"""Check correct values for kappa_decay"""
49+
contr = BayesianOptimizerController(kappa=3, kappa_min=3, n_iter=10)
50+
self.assertAlmostEqual(contr.kappa_decay, 1.0)
51+
52+
contr = BayesianOptimizerController(kappa=3, kappa_min=1, n_iter=10)
53+
self.assertAlmostEqual(contr.kappa * (contr.kappa_decay**10), 1.0)
54+
55+
def test_from_input(self):
56+
"""Check if input data is used correctly to set up controller"""
57+
inp = input()
58+
inp.bounds = {"a": (0, 1), "b": (1, 2)}
59+
60+
contr = BayesianOptimizerController.from_input(inp, sampling_base=3, kappa=3)
61+
self.assertEqual(contr.kappa, 3)
62+
self.assertEqual(contr.init_points, 3**2)
63+
self.assertEqual(contr.n_iter, 3**2)
64+
65+
3266
class TestBayesianOptimizer(unittest.TestCase):
3367
"""Tests for the optimizer based on bayes_opt.BayesianOptimization"""
3468

3569
def setUp(self):
3670
"""Mock the input"""
37-
self.input = Input(
38-
hazard=hazard(),
39-
exposure=exposure(),
40-
data=pd.DataFrame(data={"col1": [1, 2], "col2": [2, 3]}, index=[0, 1]),
41-
cost_func=MagicMock(),
42-
impact_func_creator=MagicMock(),
43-
impact_to_dataframe=MagicMock(),
44-
)
71+
self.input = input()
4572

4673
@patch("climada.util.calibrate.base.ImpactCalc", autospec=True)
4774
def test_kwargs_to_impact_func_creator(self, _):
@@ -54,11 +81,14 @@ def test_kwargs_to_impact_func_creator(self, _):
5481
self.input.bounds = {"x_2": (0, 1), "x 1": (1, 2)}
5582
self.input.cost_func.return_value = 1.0
5683
self.optimizer = BayesianOptimizer(self.input)
84+
self.controller = BayesianOptimizerController(
85+
init_points=2, n_iter=1, max_iterations=1
86+
)
5787

5888
# Call 'run'
5989
with patch.object(self.input, "impact_to_aligned_df") as align:
6090
align.return_value = (None, None)
61-
self.optimizer.run(init_points=2, n_iter=1)
91+
self.optimizer.run(self.controller)
6292

6393
# Check call to '_kwargs_to_impact_func_gen'
6494
call_args = self.input.impact_func_creator.call_args_list
@@ -75,11 +105,14 @@ def test_target_func(self, _):
75105
self.input.bounds = {"x_2": (0, 1), "x 1": (1, 2)}
76106
self.input.cost_func.side_effect = [1.0, -1.0]
77107
self.optimizer = BayesianOptimizer(self.input)
108+
self.controller = BayesianOptimizerController(
109+
init_points=1, n_iter=1, max_iterations=1
110+
)
78111

79112
# Call 'run'
80113
with patch.object(self.input, "impact_to_aligned_df") as align:
81114
align.return_value = (None, None)
82-
output = self.optimizer.run(init_points=1, n_iter=1)
115+
output = self.optimizer.run(self.controller)
83116

84117
# Check target space
85118
npt.assert_array_equal(output.p_space.target, [-1.0, 1.0])

doc/tutorial/climada_util_calibrate.ipynb

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2103,8 +2103,7 @@
21032103
}
21042104
],
21052105
"source": [
2106-
"from climada.util.calibrate import Input, BayesianOptimizer\n",
2107-
"from climada.util.calibrate.bayesian_optimizer import BayesianOptimizerController\n",
2106+
"from climada.util.calibrate import Input, BayesianOptimizer, BayesianOptimizerController\n",
21082107
"from sklearn.metrics import mean_squared_error, mean_squared_log_error\n",
21092108
"\n",
21102109
"from climada.util import log_level\n",
@@ -2123,18 +2122,7 @@
21232122
"\n",
21242123
" # Create and run the optimizer\n",
21252124
" opt = BayesianOptimizer(input)\n",
2126-
" # Best\n",
2127-
" # controller = BayesianOptimizerController.from_input(\n",
2128-
" # inp=input,\n",
2129-
" # sampling_base=5,\n",
2130-
" # min_improvement=1e-3,\n",
2131-
" # min_improvement_count=2,\n",
2132-
" # # kappa=3,\n",
2133-
" # kappa_min=0.1,\n",
2134-
" # )\n",
2135-
"\n",
21362125
" controller = BayesianOptimizerController.from_input(inp=input)\n",
2137-
"\n",
21382126
" bayes_output = opt.run(controller)\n",
21392127
" bayes_output.params # The optimal parameters"
21402128
]
@@ -3645,7 +3633,12 @@
36453633
"metadata": {},
36463634
"outputs": [],
36473635
"source": [
3648-
"from climada.util.calibrate import Input, BayesianOptimizer, OutputEvaluator\n",
3636+
"from climada.util.calibrate import (\n",
3637+
" Input,\n",
3638+
" BayesianOptimizer,\n",
3639+
" OutputEvaluator,\n",
3640+
" BayesianOptimizerOutputEvaluator,\n",
3641+
")\n",
36493642
"from sklearn.metrics import mean_squared_log_error\n",
36503643
"import matplotlib.pyplot as plt\n",
36513644
"\n",

0 commit comments

Comments
 (0)