Coverage for mlos_core/mlos_core/spaces/converters/flaml.py: 100%

23 statements  

« prev     ^ index     » next       coverage.py v7.6.10, created at 2025-01-21 01:50 +0000

1# 

2# Copyright (c) Microsoft Corporation. 

3# Licensed under the MIT License. 

4# 

5"""Contains space converters for 

6:py:class:`~mlos_core.optimizers.flaml_optimizer.FlamlOptimizer` 

7""" 

8 

9from typing import TYPE_CHECKING, TypeAlias 

10 

11import ConfigSpace 

12import flaml.tune 

13import flaml.tune.sample 

14import numpy as np 

15from flaml.tune.sample import Domain 

16 

17if TYPE_CHECKING: 

18 from ConfigSpace.hyperparameters import Hyperparameter 

19 

20FlamlDomain: TypeAlias = Domain 

21"""Flaml domain type alias.""" 

22 

23FlamlSpace: TypeAlias = dict[str, Domain] 

24"""Flaml space type alias - a `dict[str, FlamlDomain]`""" 

25 

26 

27def configspace_to_flaml_space( 

28 config_space: ConfigSpace.ConfigurationSpace, 

29) -> dict[str, FlamlDomain]: 

30 """ 

31 Converts a ConfigSpace.ConfigurationSpace to dict. 

32 

33 Parameters 

34 ---------- 

35 config_space : ConfigSpace.ConfigurationSpace 

36 Input configuration space. 

37 

38 Returns 

39 ------- 

40 flaml_space : dict 

41 A dictionary of flaml.tune.sample.Domain objects keyed by parameter name. 

42 """ 

43 flaml_numeric_type = { 

44 (ConfigSpace.UniformIntegerHyperparameter, False): flaml.tune.randint, 

45 (ConfigSpace.UniformIntegerHyperparameter, True): flaml.tune.lograndint, 

46 (ConfigSpace.UniformFloatHyperparameter, False): flaml.tune.uniform, 

47 (ConfigSpace.UniformFloatHyperparameter, True): flaml.tune.loguniform, 

48 } 

49 

50 def _one_parameter_convert(parameter: "Hyperparameter") -> FlamlDomain: 

51 if isinstance(parameter, ConfigSpace.UniformFloatHyperparameter): 

52 # FIXME: upper isn't included in the range 

53 return flaml_numeric_type[(type(parameter), parameter.log)]( 

54 parameter.lower, 

55 parameter.upper, 

56 ) 

57 elif isinstance(parameter, ConfigSpace.UniformIntegerHyperparameter): 

58 return flaml_numeric_type[(type(parameter), parameter.log)]( 

59 parameter.lower, 

60 parameter.upper + 1, 

61 ) 

62 elif isinstance(parameter, ConfigSpace.CategoricalHyperparameter): 

63 if len(np.unique(parameter.probabilities)) > 1: 

64 raise ValueError( 

65 "FLAML doesn't support categorical parameters with non-uniform probabilities." 

66 ) 

67 return flaml.tune.choice(parameter.choices) # TODO: set order? 

68 raise ValueError(f"Type of parameter {parameter} ({type(parameter)}) not supported.") 

69 

70 return {param.name: _one_parameter_convert(param) for param in config_space.values()}