From 694835ad32b174f25cb2a842443f3070cbf6cf00 Mon Sep 17 00:00:00 2001 From: smohsinali Date: Fri, 13 Jan 2017 14:32:32 +0100 Subject: [PATCH 01/13] type annotate conditions.py --- ConfigSpace/conditions.py | 102 ++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 55 deletions(-) diff --git a/ConfigSpace/conditions.py b/ConfigSpace/conditions.py index 7a7b9860..e25a127a 100644 --- a/ConfigSpace/conditions.py +++ b/ConfigSpace/conditions.py @@ -28,6 +28,7 @@ from abc import ABCMeta, abstractmethod from itertools import combinations +from typing import Any, List import operator import io @@ -64,19 +65,19 @@ def evaluate(self, instantiated_parent_hyperparameter): pass # http://stackoverflow.com/a/25176504/4636294 - def __eq__(self, other): + def __eq__(self, other: Any) -> bool: """Override the default Equals behavior""" if isinstance(other, self.__class__): return self.__dict__ == other.__dict__ return NotImplemented - def __ne__(self, other): + def __ne__(self, other: Any) -> bool: """Define a non-equality test""" if isinstance(other, self.__class__): return not self.__eq__(other) return NotImplemented - def __hash__(self): + def __hash__(self) -> int: """Override the default hash behavior (that returns the id or the object)""" return hash(tuple(sorted(self.__dict__.items()))) @@ -85,7 +86,7 @@ class AbstractCondition(ConditionComponent): # TODO create a condition evaluator! @abstractmethod - def __init__(self, child, parent): + def __init__(self, child: Hyperparameter, parent: Hyperparameter) -> None: if not isinstance(child, Hyperparameter): raise ValueError("Argument 'child' is not an instance of " "HPOlibConfigSpace.hyperparameter.Hyperparameter.") @@ -98,15 +99,16 @@ def __init__(self, child, parent): self.child = child self.parent = parent - def get_children(self): + def get_children(self) -> List[Hyperparameter]: return [self.child] - def get_parents(self): + def get_parents(self) -> List[Hyperparameter]: return [self.parent] - def get_descendant_literal_conditions(self): + def get_descendant_literal_conditions(self) -> List['AbstractCondition']: return [self] + # TODO: find typeof _evaluate? def evaluate(self, instantiated_parent_hyperparameter): hp_name = self.parent.name return self._evaluate(instantiated_parent_hyperparameter[hp_name]) @@ -117,7 +119,7 @@ def _evaluate(self, instantiated_parent_hyperparameter): class AbstractConjunction(ConditionComponent): - def __init__(self, *args): + def __init__(self, *args: ConditionComponent) -> None: self.components = args # Test the classes @@ -134,8 +136,8 @@ def __init__(self, *args): raise ValueError("All Conjunctions and Conditions must have " "the same child.") - def get_descendant_literal_conditions(self): - children = [] + def get_descendant_literal_conditions(self) -> List[ConditionComponent]: + children = [] # type: List[ConditionComponent] for component in self.components: if isinstance(component, AbstractConjunction): children.extend(component.get_descendant_literal_conditions()) @@ -143,18 +145,18 @@ def get_descendant_literal_conditions(self): children.append(component) return children - def get_children(self): - children = [] + def get_children(self) -> List[ConditionComponent]: + children = [] # type: List[ConditionComponent] for component in self.components: children.extend(component.get_children()) return children - def get_parents(self): - parents = [] + def get_parents(self) -> List[ConditionComponent]: + parents = [] # type: List[ConditionComponent] for component in self.components: parents.extend(component.get_parents()) return parents - + # TODO: find typeof _evaluate? def evaluate(self, instantiated_hyperparameters): # Then, check if all parents were passed conditions = self.get_descendant_literal_conditions() @@ -180,7 +182,8 @@ def _evaluate(self, evaluations): class EqualsCondition(AbstractCondition): - def __init__(self, child, parent, value): + # ToDo: typeof value? + def __init__(self, child: Hyperparameter, parent: Hyperparameter, value: Any) -> None: super(EqualsCondition, self).__init__(child, parent) if not parent.is_legal(value): raise ValueError("Hyperparameter '%s' is " @@ -189,11 +192,11 @@ def __init__(self, child, parent, value): (child.name, value, parent.name)) self.value = value - def __repr__(self): + def __repr__(self) -> str: return "%s | %s == %s" % (self.child.name, self.parent.name, repr(self.value)) - def _evaluate(self, value): + def _evaluate(self, value: Any) -> bool: return value == self.value @@ -207,20 +210,15 @@ def __init__(self, child, parent, value): (child.name, value, parent.name)) self.value = value - def __repr__(self): + def __repr__(self) -> str: return "%s | %s != %s" % (self.child.name, self.parent.name, repr(self.value)) - def _evaluate(self, value): + def _evaluate(self, value: Any) -> bool: return value != self.value class LessThanCondition(AbstractCondition): - def __init__(self, child, parent, value): - if not isinstance(parent, (NumericalHyperparameter, - OrdinalHyperparameter)): - raise ValueError("Parent hyperparameter in a < condition must " - "be a subclass of NumericalHyperparameter or " - "OrdinalHyperparameter, but is %s" % type(parent)) + def __init__(self, child: Hyperparameter, parent: Hyperparameter, value: Any) -> None: super(LessThanCondition, self).__init__(child, parent) if not parent.is_legal(value): raise ValueError("Hyperparameter '%s' is " @@ -229,22 +227,16 @@ def __init__(self, child, parent, value): (child.name, value, parent.name)) self.value = value - def __repr__(self): + def __repr__(self) -> str: return "%s | %s < %s" % (self.child.name, self.parent.name, repr(self.value)) - def _evaluate(self, value): - if value is None: - return False - else: - return value < self.value - + + def _evaluate(self, value: Any) -> bool: + return value < self.value + + class GreaterThanCondition(AbstractCondition): - def __init__(self, child, parent, value): - if not isinstance(parent, (NumericalHyperparameter, - OrdinalHyperparameter)): - raise ValueError("Parent hyperparameter in a > condition must " - "be a subclass of NumericalHyperparameter or " - "OrdinalHyperparameter, but is %s" % type(parent)) + def __init__(self, child: Hyperparameter, parent: Hyperparameter, value: Any) -> None: super(GreaterThanCondition, self).__init__(child, parent) if not parent.is_legal(value): raise ValueError("Hyperparameter '%s' is " @@ -253,17 +245,16 @@ def __init__(self, child, parent, value): (child.name, value, parent.name)) self.value = value - def __repr__(self): + def __repr__(self) -> str: return "%s | %s > %s" % (self.child.name, self.parent.name, repr(self.value)) - def _evaluate(self, value): - if value is None: - return False - else: - return value > self.value + + def _evaluate(self, value: Any) -> bool: + return value > self.value + class InCondition(AbstractCondition): - def __init__(self, child, parent, values): + def __init__(self, child: Hyperparameter, parent: Hyperparameter, values: Any) -> None: super(InCondition, self).__init__(child, parent) for value in values: if not parent.is_legal(value): @@ -273,25 +264,25 @@ def __init__(self, child, parent, values): (child.name, value, parent.name)) self.values = values - def __repr__(self): + def __repr__(self) -> str: return "%s | %s in {%s}" % (self.child.name, self.parent.name, ", ".join( [repr(value) for value in self.values])) - def _evaluate(self, value): + def _evaluate(self, value: Any) -> bool: return value in self.values class AndConjunction(AbstractConjunction): # TODO: test if an AndConjunction results in an illegal state or a # Tautology! -> SAT solver - def __init__(self, *args): + def __init__(self, *args: ConditionComponent) -> None: if len(args) < 2: raise ValueError("AndConjunction must at least have two " "Conditions.") super(AndConjunction, self).__init__(*args) - def __repr__(self): + def __repr__(self) -> str: retval = io.StringIO() retval.write("(") for idx, component in enumerate(self.components): @@ -301,18 +292,19 @@ def __repr__(self): retval.write(")") return retval.getvalue() - def _evaluate(self, evaluations): - return io.reduce(operator.and_, evaluations) + # TODO: type of evaluations? + def _evaluate(self, evaluations: Any) -> bool: + return reduce(operator.and_, evaluations) class OrConjunction(AbstractConjunction): - def __init__(self, *args): + def __init__(self, *args: ConditionComponent) -> None: if len(args) < 2: raise ValueError("OrConjunction must at least have two " "Conditions.") super(OrConjunction, self).__init__(*args) - def __repr__(self): + def __repr__(self) -> str: retval = io.StringIO() retval.write("(") for idx, component in enumerate(self.components): @@ -322,5 +314,5 @@ def __repr__(self): retval.write(")") return retval.getvalue() - def _evaluate(self, evaluations): + def _evaluate(self, evaluations: Any) -> bool: return reduce(operator.or_, evaluations) From 1fe9222b33f712c7e0a01b53d2087a184a478a39 Mon Sep 17 00:00:00 2001 From: smohsinali Date: Sun, 15 Jan 2017 16:06:25 +0100 Subject: [PATCH 02/13] fix --- ConfigSpace/hyperparameters.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ConfigSpace/hyperparameters.py b/ConfigSpace/hyperparameters.py index 4c049fa6..87e231d7 100644 --- a/ConfigSpace/hyperparameters.py +++ b/ConfigSpace/hyperparameters.py @@ -103,12 +103,12 @@ def get_num_neighbors(self): class Constant(Hyperparameter): def __init__(self, name, value): super(Constant, self).__init__(name) - allowed_types = [] - allowed_types.extend(int) - allowed_types.append(float) - allowed_types.extend(str) - allowed_types.append(str) - allowed_types = tuple(allowed_types) + allowed_types_list = [] # type: List[type] + allowed_types_list.append(int) + allowed_types_list.append(float) + allowed_types_list.append(str) + + allowed_types = tuple(allowed_types_list) if not isinstance(value, allowed_types) or \ isinstance(value, bool): From 32cdb10bded43bb10415f3c9f3e34f2ad572bf96 Mon Sep 17 00:00:00 2001 From: smohsinali Date: Wed, 25 Jan 2017 10:54:00 +0100 Subject: [PATCH 03/13] is_legal --- ConfigSpace/conditions.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/ConfigSpace/conditions.py b/ConfigSpace/conditions.py index e25a127a..8324b305 100644 --- a/ConfigSpace/conditions.py +++ b/ConfigSpace/conditions.py @@ -232,7 +232,10 @@ def __repr__(self) -> str: repr(self.value)) def _evaluate(self, value: Any) -> bool: - return value < self.value + if not self.parent.is_legal(value): + return False + else: + return value < self.value class GreaterThanCondition(AbstractCondition): @@ -250,7 +253,11 @@ def __repr__(self) -> str: repr(self.value)) def _evaluate(self, value: Any) -> bool: - return value > self.value + if not self.parent.is_legal(value): + return False + # if type(self.parent).__name_ == 'UniformFloatHyperparameter': + else: + return value > self.value class InCondition(AbstractCondition): From a2279ff55df68d725773839edb94711cd57732b2 Mon Sep 17 00:00:00 2001 From: smohsinali Date: Fri, 27 Jan 2017 06:44:38 +0100 Subject: [PATCH 04/13] add support for ordinal in greaterthan and lessthan comparisons --- ConfigSpace/conditions.py | 35 +++++++++++++++++++----- test/test_conditions.py | 57 ++++++++++++++++++++++----------------- 2 files changed, 61 insertions(+), 31 deletions(-) diff --git a/ConfigSpace/conditions.py b/ConfigSpace/conditions.py index 8324b305..66014c1d 100644 --- a/ConfigSpace/conditions.py +++ b/ConfigSpace/conditions.py @@ -127,7 +127,7 @@ def __init__(self, *args: ConditionComponent) -> None: if not isinstance(component, ConditionComponent): raise TypeError("Argument #%d is not an instance of %s, " "but %s" % ( - idx, ConditionComponent, type(component))) + idx, ConditionComponent, type(component))) # Test that all conjunctions and conditions have the same child! children = self.get_children() @@ -156,6 +156,7 @@ def get_parents(self) -> List[ConditionComponent]: for component in self.components: parents.extend(component.get_parents()) return parents + # TODO: find typeof _evaluate? def evaluate(self, instantiated_hyperparameters): # Then, check if all parents were passed @@ -216,24 +217,35 @@ def __repr__(self) -> str: def _evaluate(self, value: Any) -> bool: return value != self.value - + + class LessThanCondition(AbstractCondition): def __init__(self, child: Hyperparameter, parent: Hyperparameter, value: Any) -> None: super(LessThanCondition, self).__init__(child, parent) + if type(self.parent).__name__ == 'CategoricalHyperparameter': + raise ValueError("Parent hyperparameter in a < " + "condition must be a subclass of " + "NumericalHyperparameter or " + "OrdinalHyperparameter, but is " + "") + if not parent.is_legal(value): raise ValueError("Hyperparameter '%s' is " "conditional on the illegal value '%s' of " "its parent hyperparameter '%s'" % (child.name, value, parent.name)) self.value = value - + def __repr__(self) -> str: return "%s | %s < %s" % (self.child.name, self.parent.name, - repr(self.value)) + repr(self.value)) def _evaluate(self, value: Any) -> bool: if not self.parent.is_legal(value): return False + + if type(self.parent).__name__ == 'OrdinalHyperparameter': + return self.parent.value_dict[value] < self.parent.value_dict[self.value] else: return value < self.value @@ -241,21 +253,30 @@ def _evaluate(self, value: Any) -> bool: class GreaterThanCondition(AbstractCondition): def __init__(self, child: Hyperparameter, parent: Hyperparameter, value: Any) -> None: super(GreaterThanCondition, self).__init__(child, parent) + if type(self.parent).__name__ == 'CategoricalHyperparameter': + raise ValueError("Parent hyperparameter in a > " + "condition must be a subclass of " + "NumericalHyperparameter or " + "OrdinalHyperparameter, but is " + "") + if not parent.is_legal(value): raise ValueError("Hyperparameter '%s' is " "conditional on the illegal value '%s' of " "its parent hyperparameter '%s'" % (child.name, value, parent.name)) self.value = value - + def __repr__(self) -> str: return "%s | %s > %s" % (self.child.name, self.parent.name, - repr(self.value)) + repr(self.value)) def _evaluate(self, value: Any) -> bool: if not self.parent.is_legal(value): return False - # if type(self.parent).__name_ == 'UniformFloatHyperparameter': + + if type(self.parent).__name__ == 'OrdinalHyperparameter': + return self.parent.value_dict[value] > self.parent.value_dict[self.value] else: return value > self.value diff --git a/test/test_conditions.py b/test/test_conditions.py index 8b75b66e..e592f2b5 100644 --- a/test/test_conditions.py +++ b/test/test_conditions.py @@ -33,10 +33,11 @@ UniformFloatHyperparameter, NormalFloatHyperparameter, \ UniformIntegerHyperparameter, NormalIntegerHyperparameter, \ CategoricalHyperparameter, OrdinalHyperparameter -from ConfigSpace.conditions import EqualsCondition, NotEqualsCondition,\ - InCondition, AndConjunction, OrConjunction, LessThanCondition,\ +from ConfigSpace.conditions import EqualsCondition, NotEqualsCondition, \ + InCondition, AndConjunction, OrConjunction, LessThanCondition, \ GreaterThanCondition + class TestConditions(unittest.TestCase): # TODO: return only copies of the objects! def test_equals_condition(self): @@ -47,15 +48,15 @@ def test_equals_condition(self): # Test invalid conditions: self.assertRaisesRegexp(ValueError, "Argument 'parent' is not an " - "instance of HPOlibConfigSpace.hyperparameter." - "Hyperparameter.", EqualsCondition, hp2, + "instance of HPOlibConfigSpace.hyperparameter." + "Hyperparameter.", EqualsCondition, hp2, "parent", 0) self.assertRaisesRegexp(ValueError, "Argument 'child' is not an " - "instance of HPOlibConfigSpace.hyperparameter." - "Hyperparameter.", EqualsCondition, "child", + "instance of HPOlibConfigSpace.hyperparameter." + "Hyperparameter.", EqualsCondition, "child", hp1, 0) self.assertRaisesRegexp(ValueError, "The child and parent hyperparameter " - "must be different hyperparameters.", + "must be different hyperparameters.", EqualsCondition, hp1, hp1, 0) self.assertEqual(cond, cond_) @@ -71,12 +72,12 @@ def test_equals_condition_illegal_value(self): epsilon = UniformFloatHyperparameter("epsilon", 1e-5, 1e-1, default=1e-4, log=True) loss = CategoricalHyperparameter("loss", - ["hinge", "log", "modified_huber", "squared_hinge", "perceptron"], - default="hinge") + ["hinge", "log", "modified_huber", "squared_hinge", "perceptron"], + default="hinge") self.assertRaisesRegexp(ValueError, "Hyperparameter 'epsilon' is " - "conditional on the illegal value 'huber' of " - "its parent hyperparameter 'loss'", - EqualsCondition, epsilon, loss, "huber") + "conditional on the illegal value 'huber' of " + "its parent hyperparameter 'loss'", + EqualsCondition, epsilon, loss, "huber") def test_not_equals_condition(self): hp1 = CategoricalHyperparameter("parent", [0, 1]) @@ -137,17 +138,27 @@ def test_greater_and_less_condition(self): hp4 = CategoricalHyperparameter("cat", list(range(6))) self.assertRaisesRegexp(ValueError, "Parent hyperparameter in a > " - "condition must be a subclass of " - "NumericalHyperparameter or " - "OrdinalHyperparameter, but is " - "", - GreaterThanCondition, child, hp4, 1) + "condition must be a subclass of " + "NumericalHyperparameter or " + "OrdinalHyperparameter, but is " + "", + GreaterThanCondition, child, hp4, 1) self.assertRaisesRegexp(ValueError, "Parent hyperparameter in a < " - "condition must be a subclass of " - "NumericalHyperparameter or " - "OrdinalHyperparameter, but is " - "", - LessThanCondition, child, hp4, 1) + "condition must be a subclass of " + "NumericalHyperparameter or " + "OrdinalHyperparameter, but is " + "", + LessThanCondition, child, hp4, 1) + + hp5 = OrdinalHyperparameter("ord", ['cold', 'luke warm', 'warm', 'hot']) + + gt = GreaterThanCondition(child, hp5, 'warm') + self.assertTrue(gt.evaluate({hp5.name: 'hot'})) + self.assertFalse(gt.evaluate({hp5.name: 'cold'})) + + lt = LessThanCondition(child, hp5, 'warm') + self.assertTrue(lt.evaluate({hp5.name: 'luke warm'})) + self.assertFalse(lt.evaluate({hp5.name: 'warm'})) def test_in_condition_illegal_value(self): epsilon = UniformFloatHyperparameter("epsilon", 1e-5, 1e-1, @@ -191,7 +202,6 @@ def test_and_conjunction(self): self.assertNotEqual(andconj1, andconj3) self.assertNotEqual(andconj1, "String") - def test_or_conjunction(self): self.assertRaises(TypeError, AndConjunction, "String1", "String2") @@ -285,4 +295,3 @@ def test_get_parents(self): # All conjunctions inherit get_parents from abstractconjunction conjunction = AndConjunction(condition, condition2) self.assertEqual([_1_S_countercond, _1_0_restarts], conjunction.get_parents()) - \ No newline at end of file From 3b3d4f5f177ca96f21ed045fc8bee33a3f7a1f30 Mon Sep 17 00:00:00 2001 From: smohsinali Date: Fri, 3 Feb 2017 02:39:44 +0100 Subject: [PATCH 05/13] make inequality checks more general --- ConfigSpace/conditions.py | 35 ++++++++++++---------------------- ConfigSpace/hyperparameters.py | 24 ++++++++++++++++++++++- test/test_conditions.py | 4 ++-- 3 files changed, 37 insertions(+), 26 deletions(-) diff --git a/ConfigSpace/conditions.py b/ConfigSpace/conditions.py index 66014c1d..1986f357 100644 --- a/ConfigSpace/conditions.py +++ b/ConfigSpace/conditions.py @@ -198,7 +198,10 @@ def __repr__(self) -> str: repr(self.value)) def _evaluate(self, value: Any) -> bool: - return value == self.value + if not self.parent.is_legal(value): + return False + + return self.parent.get_order(value) == self.parent.get_order(self.value) class NotEqualsCondition(AbstractCondition): @@ -216,18 +219,16 @@ def __repr__(self) -> str: repr(self.value)) def _evaluate(self, value: Any) -> bool: - return value != self.value + if not self.parent.is_legal(value): + return False + + return self.parent.get_order(value) != self.parent.get_order(self.value) class LessThanCondition(AbstractCondition): def __init__(self, child: Hyperparameter, parent: Hyperparameter, value: Any) -> None: super(LessThanCondition, self).__init__(child, parent) - if type(self.parent).__name__ == 'CategoricalHyperparameter': - raise ValueError("Parent hyperparameter in a < " - "condition must be a subclass of " - "NumericalHyperparameter or " - "OrdinalHyperparameter, but is " - "") + self.parent.allow_inequality_checks() if not parent.is_legal(value): raise ValueError("Hyperparameter '%s' is " @@ -244,22 +245,13 @@ def _evaluate(self, value: Any) -> bool: if not self.parent.is_legal(value): return False - if type(self.parent).__name__ == 'OrdinalHyperparameter': - return self.parent.value_dict[value] < self.parent.value_dict[self.value] - else: - return value < self.value + return self.parent.get_order(value) < self.parent.get_order(self.value) class GreaterThanCondition(AbstractCondition): def __init__(self, child: Hyperparameter, parent: Hyperparameter, value: Any) -> None: super(GreaterThanCondition, self).__init__(child, parent) - if type(self.parent).__name__ == 'CategoricalHyperparameter': - raise ValueError("Parent hyperparameter in a > " - "condition must be a subclass of " - "NumericalHyperparameter or " - "OrdinalHyperparameter, but is " - "") - + self.parent.allow_inequality_checks() if not parent.is_legal(value): raise ValueError("Hyperparameter '%s' is " "conditional on the illegal value '%s' of " @@ -275,10 +267,7 @@ def _evaluate(self, value: Any) -> bool: if not self.parent.is_legal(value): return False - if type(self.parent).__name__ == 'OrdinalHyperparameter': - return self.parent.value_dict[value] > self.parent.value_dict[self.value] - else: - return value > self.value + return self.parent.get_order(value) > self.parent.get_order(self.value) class InCondition(AbstractCondition): diff --git a/ConfigSpace/hyperparameters.py b/ConfigSpace/hyperparameters.py index 75ab831f..56069af8 100644 --- a/ConfigSpace/hyperparameters.py +++ b/ConfigSpace/hyperparameters.py @@ -157,9 +157,15 @@ def __init__(self, name: str, default: Any) -> None: def has_neighbors(self) -> bool: return True - def get_num_neighbors(self, value= None) -> np.inf: + def get_num_neighbors(self, value=None) -> np.inf: return np.inf + def allow_inequality_checks(self) -> bool: + return True + + def get_order(self, value: Union[int, float]) -> Union[int, float]: + return value + class FloatHyperparameter(NumericalHyperparameter): def __init__(self, name: str, default: Union[int, float]) -> None: @@ -767,6 +773,19 @@ def get_neighbors(self, value: int, rs: np.random.RandomState, number: Union[int return neighbors + def get_order(self, value: Union[None, int, str, float]) -> Union[None, int, str, float]: + """ + returns the seuence position/order of a certain value from the sequence + """ + return value + + def allow_inequality_checks(self) -> bool: + raise ValueError("Parent hyperparameter in a > or < " + "condition must be a subclass of " + "NumericalHyperparameter or " + "OrdinalHyperparameter, but is " + "") + class OrdinalHyperparameter(Hyperparameter): def __init__(self, name: str, sequence: List[Union[float, int, str]], @@ -915,3 +934,6 @@ def get_neighbors(self, value: Union[int, str, float], rs: None, number: int = 2 neighbors.append(neighbor_idx2) return neighbors + + def allow_inequality_checks(self) -> bool: + return True diff --git a/test/test_conditions.py b/test/test_conditions.py index e592f2b5..46ff9b64 100644 --- a/test/test_conditions.py +++ b/test/test_conditions.py @@ -137,13 +137,13 @@ def test_greater_and_less_condition(self): self.assertFalse(lt.evaluate({hp.name: None})) hp4 = CategoricalHyperparameter("cat", list(range(6))) - self.assertRaisesRegexp(ValueError, "Parent hyperparameter in a > " + self.assertRaisesRegexp(ValueError, "Parent hyperparameter in a > or < " "condition must be a subclass of " "NumericalHyperparameter or " "OrdinalHyperparameter, but is " "", GreaterThanCondition, child, hp4, 1) - self.assertRaisesRegexp(ValueError, "Parent hyperparameter in a < " + self.assertRaisesRegexp(ValueError, "Parent hyperparameter in a > or < " "condition must be a subclass of " "NumericalHyperparameter or " "OrdinalHyperparameter, but is " From 3303c027a65fb80c43921df69607f49b81474fab Mon Sep 17 00:00:00 2001 From: smohsinali Date: Fri, 3 Feb 2017 14:07:47 +0100 Subject: [PATCH 06/13] fix --- ConfigSpace/conditions.py | 53 ++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/ConfigSpace/conditions.py b/ConfigSpace/conditions.py index 1986f357..0eeace77 100644 --- a/ConfigSpace/conditions.py +++ b/ConfigSpace/conditions.py @@ -28,7 +28,7 @@ from abc import ABCMeta, abstractmethod from itertools import combinations -from typing import Any, List +from typing import Any, List, Union import operator import io @@ -41,27 +41,27 @@ class ConditionComponent(object): __metaclass__ = ABCMeta @abstractmethod - def __init__(self): + def __init__(self) -> None: pass @abstractmethod - def __repr__(self): + def __repr__(self) -> str: pass @abstractmethod - def get_children(self): + def get_children(self) -> List['ConditionComponent']: pass @abstractmethod - def get_parents(self): + def get_parents(self) -> List['ConditionComponent']: pass @abstractmethod - def get_descendant_literal_conditions(self): + def get_descendant_literal_conditions(self) ->List['ConditionComponent']: pass @abstractmethod - def evaluate(self, instantiated_parent_hyperparameter): + def evaluate(self, instantiated_parent_hyperparameter: Hyperparameter) -> bool: pass # http://stackoverflow.com/a/25176504/4636294 @@ -105,21 +105,21 @@ def get_children(self) -> List[Hyperparameter]: def get_parents(self) -> List[Hyperparameter]: return [self.parent] - def get_descendant_literal_conditions(self) -> List['AbstractCondition']: + def get_descendant_literal_conditions(self) -> List['ConditionComponent']: return [self] - # TODO: find typeof _evaluate? - def evaluate(self, instantiated_parent_hyperparameter): + def evaluate(self, instantiated_parent_hyperparameter: Hyperparameter) -> bool: hp_name = self.parent.name return self._evaluate(instantiated_parent_hyperparameter[hp_name]) @abstractmethod - def _evaluate(self, instantiated_parent_hyperparameter): + def _evaluate(self, instantiated_parent_hyperparameter: Hyperparameter) -> bool: pass class AbstractConjunction(ConditionComponent): def __init__(self, *args: ConditionComponent) -> None: + super(AbstractConjunction, self).__init__() self.components = args # Test the classes @@ -136,8 +136,8 @@ def __init__(self, *args: ConditionComponent) -> None: raise ValueError("All Conjunctions and Conditions must have " "the same child.") - def get_descendant_literal_conditions(self) -> List[ConditionComponent]: - children = [] # type: List[ConditionComponent] + def get_descendant_literal_conditions(self) -> List['AbstractCondition']: + children = [] # type: List['AbstractCondition'] for component in self.components: if isinstance(component, AbstractConjunction): children.extend(component.get_descendant_literal_conditions()) @@ -157,8 +157,7 @@ def get_parents(self) -> List[ConditionComponent]: parents.extend(component.get_parents()) return parents - # TODO: find typeof _evaluate? - def evaluate(self, instantiated_hyperparameters): + def evaluate(self, instantiated_hyperparameters: Hyperparameter) -> bool: # Then, check if all parents were passed conditions = self.get_descendant_literal_conditions() for condition in conditions: @@ -178,13 +177,12 @@ def evaluate(self, instantiated_hyperparameters): return self._evaluate(evaluations) @abstractmethod - def _evaluate(self, evaluations): + def _evaluate(self, evaluations: List[bool]) -> bool: pass class EqualsCondition(AbstractCondition): - # ToDo: typeof value? - def __init__(self, child: Hyperparameter, parent: Hyperparameter, value: Any) -> None: + def __init__(self, child: Hyperparameter, parent: Hyperparameter, value: Union[str, float, int]) -> None: super(EqualsCondition, self).__init__(child, parent) if not parent.is_legal(value): raise ValueError("Hyperparameter '%s' is " @@ -197,7 +195,7 @@ def __repr__(self) -> str: return "%s | %s == %s" % (self.child.name, self.parent.name, repr(self.value)) - def _evaluate(self, value: Any) -> bool: + def _evaluate(self, value: Union[str, float, int]) -> bool: if not self.parent.is_legal(value): return False @@ -205,7 +203,7 @@ def _evaluate(self, value: Any) -> bool: class NotEqualsCondition(AbstractCondition): - def __init__(self, child, parent, value): + def __init__(self, child: Hyperparameter, parent: Hyperparameter, value: Union[str, float, int]): super(NotEqualsCondition, self).__init__(child, parent) if not parent.is_legal(value): raise ValueError("Hyperparameter '%s' is " @@ -218,7 +216,7 @@ def __repr__(self) -> str: return "%s | %s != %s" % (self.child.name, self.parent.name, repr(self.value)) - def _evaluate(self, value: Any) -> bool: + def _evaluate(self, value: Union[str, float, int]) -> bool: if not self.parent.is_legal(value): return False @@ -226,7 +224,7 @@ def _evaluate(self, value: Any) -> bool: class LessThanCondition(AbstractCondition): - def __init__(self, child: Hyperparameter, parent: Hyperparameter, value: Any) -> None: + def __init__(self, child: Hyperparameter, parent: Hyperparameter, value: Union[str, float, int]) -> None: super(LessThanCondition, self).__init__(child, parent) self.parent.allow_inequality_checks() @@ -241,7 +239,7 @@ def __repr__(self) -> str: return "%s | %s < %s" % (self.child.name, self.parent.name, repr(self.value)) - def _evaluate(self, value: Any) -> bool: + def _evaluate(self, value: Union[str, float, int]) -> bool: if not self.parent.is_legal(value): return False @@ -249,7 +247,7 @@ def _evaluate(self, value: Any) -> bool: class GreaterThanCondition(AbstractCondition): - def __init__(self, child: Hyperparameter, parent: Hyperparameter, value: Any) -> None: + def __init__(self, child: Hyperparameter, parent: Hyperparameter, value: Union[str, float, int]) -> None: super(GreaterThanCondition, self).__init__(child, parent) self.parent.allow_inequality_checks() if not parent.is_legal(value): @@ -263,7 +261,7 @@ def __repr__(self) -> str: return "%s | %s > %s" % (self.child.name, self.parent.name, repr(self.value)) - def _evaluate(self, value: Any) -> bool: + def _evaluate(self, value: Union[str, float, int]) -> bool: if not self.parent.is_legal(value): return False @@ -271,7 +269,7 @@ def _evaluate(self, value: Any) -> bool: class InCondition(AbstractCondition): - def __init__(self, child: Hyperparameter, parent: Hyperparameter, values: Any) -> None: + def __init__(self, child: Hyperparameter, parent: Hyperparameter, values: List[Union[str, float, int]]) -> None: super(InCondition, self).__init__(child, parent) for value in values: if not parent.is_legal(value): @@ -286,7 +284,7 @@ def __repr__(self) -> str: ", ".join( [repr(value) for value in self.values])) - def _evaluate(self, value: Any) -> bool: + def _evaluate(self, value: Union[str, float, int]) -> bool: return value in self.values @@ -309,7 +307,6 @@ def __repr__(self) -> str: retval.write(")") return retval.getvalue() - # TODO: type of evaluations? def _evaluate(self, evaluations: Any) -> bool: return reduce(operator.and_, evaluations) From 0f3310536a79bd4fd42c3deb281ee5628a17562f Mon Sep 17 00:00:00 2001 From: smohsinali Date: Fri, 3 Feb 2017 14:11:52 +0100 Subject: [PATCH 07/13] fix --- ConfigSpace/hyperparameters.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ConfigSpace/hyperparameters.py b/ConfigSpace/hyperparameters.py index 56069af8..cbf4122c 100644 --- a/ConfigSpace/hyperparameters.py +++ b/ConfigSpace/hyperparameters.py @@ -141,7 +141,7 @@ def has_neighbors(self) -> bool: def get_num_neighbors(self, value=None) -> int: return 0 - def get_neighbors(self, value: Any, rs: Any, number: int, transform: bool = False) -> List: + def get_neighbors(self, value: Any, rs: np.random.RandomState, number: int, transform: bool = False) -> List: return [] @@ -157,7 +157,7 @@ def __init__(self, name: str, default: Any) -> None: def has_neighbors(self) -> bool: return True - def get_num_neighbors(self, value=None) -> np.inf: + def get_num_neighbors(self, value=None) -> np.float: return np.inf def allow_inequality_checks(self) -> bool: @@ -775,7 +775,7 @@ def get_neighbors(self, value: int, rs: np.random.RandomState, number: Union[int def get_order(self, value: Union[None, int, str, float]) -> Union[None, int, str, float]: """ - returns the seuence position/order of a certain value from the sequence + returns input. this function is used for > and < comparisions """ return value From 043c687118cc4caac810b8fadc6fd799cefc8fb9 Mon Sep 17 00:00:00 2001 From: smohsinali Date: Wed, 8 Feb 2017 09:33:05 +0100 Subject: [PATCH 08/13] fix hp --- ConfigSpace/hyperparameters.py | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/ConfigSpace/hyperparameters.py b/ConfigSpace/hyperparameters.py index cbf4122c..8b0c226e 100644 --- a/ConfigSpace/hyperparameters.py +++ b/ConfigSpace/hyperparameters.py @@ -157,15 +157,9 @@ def __init__(self, name: str, default: Any) -> None: def has_neighbors(self) -> bool: return True - def get_num_neighbors(self, value=None) -> np.float: + def get_num_neighbors(self, value=None) -> float: return np.inf - def allow_inequality_checks(self) -> bool: - return True - - def get_order(self, value: Union[int, float]) -> Union[int, float]: - return value - class FloatHyperparameter(NumericalHyperparameter): def __init__(self, name: str, default: Union[int, float]) -> None: @@ -314,7 +308,7 @@ def _inverse_transform(self, vector: Union[np.ndarray, None]) -> Union[float, np vector = np.log(vector) return (vector - self._lower) / (self._upper - self._lower) - def get_neighbors(self, value: Any, rs: np.random, number: int = 4, transform: bool = False) -> List[float]: + def get_neighbors(self, value: Any, rs: np.random.RandomState, number: int = 4, transform: bool = False) -> List[float]: neighbors = [] # type: List[float] while len(neighbors) < number: neighbor = rs.normal(value, 0.2) @@ -391,7 +385,7 @@ def to_integer(self) -> 'NormalIntegerHyperparameter': def is_legal(self, value: Union[float]) -> bool: return isinstance(value, float) or isinstance(value, int) - def _sample(self, rs: np.random, size: Union[None, int] = None) -> np.ndarray: + def _sample(self, rs: np.random.RandomState, size: Union[None, int] = None) -> np.ndarray: mu = self.mu sigma = self.sigma return rs.normal(mu, sigma, size=size) @@ -773,19 +767,6 @@ def get_neighbors(self, value: int, rs: np.random.RandomState, number: Union[int return neighbors - def get_order(self, value: Union[None, int, str, float]) -> Union[None, int, str, float]: - """ - returns input. this function is used for > and < comparisions - """ - return value - - def allow_inequality_checks(self) -> bool: - raise ValueError("Parent hyperparameter in a > or < " - "condition must be a subclass of " - "NumericalHyperparameter or " - "OrdinalHyperparameter, but is " - "") - class OrdinalHyperparameter(Hyperparameter): def __init__(self, name: str, sequence: List[Union[float, int, str]], @@ -934,6 +915,3 @@ def get_neighbors(self, value: Union[int, str, float], rs: None, number: int = 2 neighbors.append(neighbor_idx2) return neighbors - - def allow_inequality_checks(self) -> bool: - return True From 5560274185ede85bae3a385845d8987b87b3de7b Mon Sep 17 00:00:00 2001 From: smohsinali Date: Wed, 8 Feb 2017 09:54:48 +0100 Subject: [PATCH 09/13] conditioncomponent->abstractcondition --- ConfigSpace/conditions.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ConfigSpace/conditions.py b/ConfigSpace/conditions.py index 0eeace77..044fd207 100644 --- a/ConfigSpace/conditions.py +++ b/ConfigSpace/conditions.py @@ -57,7 +57,7 @@ def get_parents(self) -> List['ConditionComponent']: pass @abstractmethod - def get_descendant_literal_conditions(self) ->List['ConditionComponent']: + def get_descendant_literal_conditions(self) ->List['AbstractCondition']: pass @abstractmethod @@ -105,7 +105,7 @@ def get_children(self) -> List[Hyperparameter]: def get_parents(self) -> List[Hyperparameter]: return [self.parent] - def get_descendant_literal_conditions(self) -> List['ConditionComponent']: + def get_descendant_literal_conditions(self) -> List['AbstractCondition']: return [self] def evaluate(self, instantiated_parent_hyperparameter: Hyperparameter) -> bool: @@ -118,7 +118,7 @@ def _evaluate(self, instantiated_parent_hyperparameter: Hyperparameter) -> bool: class AbstractConjunction(ConditionComponent): - def __init__(self, *args: ConditionComponent) -> None: + def __init__(self, *args: AbstractCondition) -> None: super(AbstractConjunction, self).__init__() self.components = args @@ -136,8 +136,8 @@ def __init__(self, *args: ConditionComponent) -> None: raise ValueError("All Conjunctions and Conditions must have " "the same child.") - def get_descendant_literal_conditions(self) -> List['AbstractCondition']: - children = [] # type: List['AbstractCondition'] + def get_descendant_literal_conditions(self) -> List[AbstractCondition]: + children = [] # type: List[AbstractCondition] for component in self.components: if isinstance(component, AbstractConjunction): children.extend(component.get_descendant_literal_conditions()) @@ -203,7 +203,7 @@ def _evaluate(self, value: Union[str, float, int]) -> bool: class NotEqualsCondition(AbstractCondition): - def __init__(self, child: Hyperparameter, parent: Hyperparameter, value: Union[str, float, int]): + def __init__(self, child: Hyperparameter, parent: Hyperparameter, value: Union[str, float, int]) -> None: super(NotEqualsCondition, self).__init__(child, parent) if not parent.is_legal(value): raise ValueError("Hyperparameter '%s' is " @@ -291,7 +291,7 @@ def _evaluate(self, value: Union[str, float, int]) -> bool: class AndConjunction(AbstractConjunction): # TODO: test if an AndConjunction results in an illegal state or a # Tautology! -> SAT solver - def __init__(self, *args: ConditionComponent) -> None: + def __init__(self, *args: AbstractCondition) -> None: if len(args) < 2: raise ValueError("AndConjunction must at least have two " "Conditions.") @@ -312,7 +312,7 @@ def _evaluate(self, evaluations: Any) -> bool: class OrConjunction(AbstractConjunction): - def __init__(self, *args: ConditionComponent) -> None: + def __init__(self, *args: AbstractCondition) -> None: if len(args) < 2: raise ValueError("OrConjunction must at least have two " "Conditions.") From fa51b6d4bea188d8136e42d79532406c16df3ab8 Mon Sep 17 00:00:00 2001 From: smohsinali Date: Thu, 9 Feb 2017 10:51:33 +0100 Subject: [PATCH 10/13] conditioncomponent->abstractcondition --- ConfigSpace/conditions.py | 16 ++++++++-------- ConfigSpace/hyperparameters.py | 6 ++++++ test/test_conditions.py | 24 ++++++++++++------------ 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/ConfigSpace/conditions.py b/ConfigSpace/conditions.py index 044fd207..a52d4436 100644 --- a/ConfigSpace/conditions.py +++ b/ConfigSpace/conditions.py @@ -113,7 +113,7 @@ def evaluate(self, instantiated_parent_hyperparameter: Hyperparameter) -> bool: return self._evaluate(instantiated_parent_hyperparameter[hp_name]) @abstractmethod - def _evaluate(self, instantiated_parent_hyperparameter: Hyperparameter) -> bool: + def _evaluate(self, instantiated_parent_hyperparameter: Union[str, int, float]) -> bool: pass @@ -199,7 +199,7 @@ def _evaluate(self, value: Union[str, float, int]) -> bool: if not self.parent.is_legal(value): return False - return self.parent.get_order(value) == self.parent.get_order(self.value) + return value == self.value class NotEqualsCondition(AbstractCondition): @@ -220,13 +220,13 @@ def _evaluate(self, value: Union[str, float, int]) -> bool: if not self.parent.is_legal(value): return False - return self.parent.get_order(value) != self.parent.get_order(self.value) + return value != self.value class LessThanCondition(AbstractCondition): def __init__(self, child: Hyperparameter, parent: Hyperparameter, value: Union[str, float, int]) -> None: super(LessThanCondition, self).__init__(child, parent) - self.parent.allow_inequality_checks() + # self.parent.allow_inequality_checks() if not parent.is_legal(value): raise ValueError("Hyperparameter '%s' is " @@ -243,13 +243,13 @@ def _evaluate(self, value: Union[str, float, int]) -> bool: if not self.parent.is_legal(value): return False - return self.parent.get_order(value) < self.parent.get_order(self.value) + return value < self.value class GreaterThanCondition(AbstractCondition): def __init__(self, child: Hyperparameter, parent: Hyperparameter, value: Union[str, float, int]) -> None: super(GreaterThanCondition, self).__init__(child, parent) - self.parent.allow_inequality_checks() + # self.parent.allow_inequality_checks() if not parent.is_legal(value): raise ValueError("Hyperparameter '%s' is " "conditional on the illegal value '%s' of " @@ -265,8 +265,8 @@ def _evaluate(self, value: Union[str, float, int]) -> bool: if not self.parent.is_legal(value): return False - return self.parent.get_order(value) > self.parent.get_order(self.value) - + # return self.parent.get_order(value) > self.parent.get_order(self.value) + return self.parent(value) > self.parent(self.value) class InCondition(AbstractCondition): def __init__(self, child: Hyperparameter, parent: Hyperparameter, values: List[Union[str, float, int]]) -> None: diff --git a/ConfigSpace/hyperparameters.py b/ConfigSpace/hyperparameters.py index 8b0c226e..0c23f7b7 100644 --- a/ConfigSpace/hyperparameters.py +++ b/ConfigSpace/hyperparameters.py @@ -802,6 +802,12 @@ def __repr__(self) -> str: repr_str.seek(0) return repr_str.getvalue() + def __gt__(self, value: Union[int, float, str]) -> bool: + return self.value_dict[value] > self.default + + + + def is_legal(self, value: Union[int, float, str]) -> bool: """ checks if a certain value is represented in the sequence diff --git a/test/test_conditions.py b/test/test_conditions.py index 46ff9b64..09ecd16e 100644 --- a/test/test_conditions.py +++ b/test/test_conditions.py @@ -137,18 +137,18 @@ def test_greater_and_less_condition(self): self.assertFalse(lt.evaluate({hp.name: None})) hp4 = CategoricalHyperparameter("cat", list(range(6))) - self.assertRaisesRegexp(ValueError, "Parent hyperparameter in a > or < " - "condition must be a subclass of " - "NumericalHyperparameter or " - "OrdinalHyperparameter, but is " - "", - GreaterThanCondition, child, hp4, 1) - self.assertRaisesRegexp(ValueError, "Parent hyperparameter in a > or < " - "condition must be a subclass of " - "NumericalHyperparameter or " - "OrdinalHyperparameter, but is " - "", - LessThanCondition, child, hp4, 1) + # self.assertRaisesRegexp(ValueError, "Parent hyperparameter in a > or < " + # "condition must be a subclass of " + # "NumericalHyperparameter or " + # "OrdinalHyperparameter, but is " + # "", + # GreaterThanCondition, child, hp4, 1) + # self.assertRaisesRegexp(ValueError, "Parent hyperparameter in a > or < " + # "condition must be a subclass of " + # "NumericalHyperparameter or " + # "OrdinalHyperparameter, but is " + # "", + # LessThanCondition, child, hp4, 1) hp5 = OrdinalHyperparameter("ord", ['cold', 'luke warm', 'warm', 'hot']) From 1e15ef66a94dc447e9cbe8e668193005795736cf Mon Sep 17 00:00:00 2001 From: smohsinali Date: Thu, 9 Feb 2017 11:13:54 +0100 Subject: [PATCH 11/13] add compare function --- ConfigSpace/conditions.py | 30 ++++++++++++++++++------- ConfigSpace/hyperparameters.py | 40 +++++++++++++++++++++++++++++----- 2 files changed, 57 insertions(+), 13 deletions(-) diff --git a/ConfigSpace/conditions.py b/ConfigSpace/conditions.py index a52d4436..fd722c33 100644 --- a/ConfigSpace/conditions.py +++ b/ConfigSpace/conditions.py @@ -199,7 +199,11 @@ def _evaluate(self, value: Union[str, float, int]) -> bool: if not self.parent.is_legal(value): return False - return value == self.value + cmp = self.parent.compare(value, self.value) + if cmp == 0: + return True + else: + return False class NotEqualsCondition(AbstractCondition): @@ -220,14 +224,17 @@ def _evaluate(self, value: Union[str, float, int]) -> bool: if not self.parent.is_legal(value): return False - return value != self.value + cmp = self.parent.compare(value, self.value) + if cmp != 0: + return True + else: + return False class LessThanCondition(AbstractCondition): def __init__(self, child: Hyperparameter, parent: Hyperparameter, value: Union[str, float, int]) -> None: super(LessThanCondition, self).__init__(child, parent) - # self.parent.allow_inequality_checks() - + self.parent.allow_inequality_checks() if not parent.is_legal(value): raise ValueError("Hyperparameter '%s' is " "conditional on the illegal value '%s' of " @@ -243,13 +250,17 @@ def _evaluate(self, value: Union[str, float, int]) -> bool: if not self.parent.is_legal(value): return False - return value < self.value + cmp = self.parent.compare(value, self.value) + if cmp == -1: + return True + else: + return False class GreaterThanCondition(AbstractCondition): def __init__(self, child: Hyperparameter, parent: Hyperparameter, value: Union[str, float, int]) -> None: super(GreaterThanCondition, self).__init__(child, parent) - # self.parent.allow_inequality_checks() + self.parent.allow_inequality_checks() if not parent.is_legal(value): raise ValueError("Hyperparameter '%s' is " "conditional on the illegal value '%s' of " @@ -265,8 +276,11 @@ def _evaluate(self, value: Union[str, float, int]) -> bool: if not self.parent.is_legal(value): return False - # return self.parent.get_order(value) > self.parent.get_order(self.value) - return self.parent(value) > self.parent(self.value) + cmp = self.parent.compare(value, self.value) + if cmp == 1: + return True + else: + return False class InCondition(AbstractCondition): def __init__(self, child: Hyperparameter, parent: Hyperparameter, values: List[Union[str, float, int]]) -> None: diff --git a/ConfigSpace/hyperparameters.py b/ConfigSpace/hyperparameters.py index 0c23f7b7..a4cba639 100644 --- a/ConfigSpace/hyperparameters.py +++ b/ConfigSpace/hyperparameters.py @@ -160,6 +160,18 @@ def has_neighbors(self) -> bool: def get_num_neighbors(self, value=None) -> float: return np.inf + def compare(self, value: Union[int, float, str], value2: Union[int, float, str]) -> int: + if value < value2: + return -1 + elif value > value2: + return 1 + elif value == value2: + return 0 + + def allow_inequality_checks(self) -> bool: + return True + + class FloatHyperparameter(NumericalHyperparameter): def __init__(self, name: str, default: Union[int, float]) -> None: @@ -694,6 +706,12 @@ def __repr__(self) -> str: repr_str.seek(0) return repr_str.getvalue() + def compare(self, value: Union[int, float, str], value2: Union[int, float, str]) -> int: + if value == value2: + return 0 + else: + return 1 + def is_legal(self, value: Union[None, str, float, int]) -> bool: if value in self.choices: return True @@ -767,6 +785,13 @@ def get_neighbors(self, value: int, rs: np.random.RandomState, number: Union[int return neighbors + def allow_inequality_checks(self) -> bool: + raise ValueError("Parent hyperparameter in a > or < " + "condition must be a subclass of " + "NumericalHyperparameter or " + "OrdinalHyperparameter, but is " + "") + class OrdinalHyperparameter(Hyperparameter): def __init__(self, name: str, sequence: List[Union[float, int, str]], @@ -802,11 +827,13 @@ def __repr__(self) -> str: repr_str.seek(0) return repr_str.getvalue() - def __gt__(self, value: Union[int, float, str]) -> bool: - return self.value_dict[value] > self.default - - - + def compare(self, value: Union[int, float, str], value2: Union[int, float, str]) -> int: + if self.value_dict[value] < self.value_dict[value2]: + return -1 + elif self.value_dict[value] > self.value_dict[value2]: + return 1 + elif self.value_dict[value] == self.value_dict[value2]: + return 0 def is_legal(self, value: Union[int, float, str]) -> bool: """ @@ -921,3 +948,6 @@ def get_neighbors(self, value: Union[int, str, float], rs: None, number: int = 2 neighbors.append(neighbor_idx2) return neighbors + + def allow_inequality_checks(self) -> bool: + return True From a472ba0cbeeb3cd27c559f3478431c25e5a1e9e9 Mon Sep 17 00:00:00 2001 From: smohsinali Date: Thu, 9 Feb 2017 11:28:05 +0100 Subject: [PATCH 12/13] add compare function --- test/test_conditions.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/test/test_conditions.py b/test/test_conditions.py index 09ecd16e..46ff9b64 100644 --- a/test/test_conditions.py +++ b/test/test_conditions.py @@ -137,18 +137,18 @@ def test_greater_and_less_condition(self): self.assertFalse(lt.evaluate({hp.name: None})) hp4 = CategoricalHyperparameter("cat", list(range(6))) - # self.assertRaisesRegexp(ValueError, "Parent hyperparameter in a > or < " - # "condition must be a subclass of " - # "NumericalHyperparameter or " - # "OrdinalHyperparameter, but is " - # "", - # GreaterThanCondition, child, hp4, 1) - # self.assertRaisesRegexp(ValueError, "Parent hyperparameter in a > or < " - # "condition must be a subclass of " - # "NumericalHyperparameter or " - # "OrdinalHyperparameter, but is " - # "", - # LessThanCondition, child, hp4, 1) + self.assertRaisesRegexp(ValueError, "Parent hyperparameter in a > or < " + "condition must be a subclass of " + "NumericalHyperparameter or " + "OrdinalHyperparameter, but is " + "", + GreaterThanCondition, child, hp4, 1) + self.assertRaisesRegexp(ValueError, "Parent hyperparameter in a > or < " + "condition must be a subclass of " + "NumericalHyperparameter or " + "OrdinalHyperparameter, but is " + "", + LessThanCondition, child, hp4, 1) hp5 = OrdinalHyperparameter("ord", ['cold', 'luke warm', 'warm', 'hot']) From b75bf78cb096f04ddf7324ce38cd0ff9f98586a2 Mon Sep 17 00:00:00 2001 From: smohsinali Date: Thu, 9 Feb 2017 11:33:59 +0100 Subject: [PATCH 13/13] add compare function --- ConfigSpace/conditions.py | 4 ++-- ConfigSpace/hyperparameters.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ConfigSpace/conditions.py b/ConfigSpace/conditions.py index fd722c33..dee7bfdd 100644 --- a/ConfigSpace/conditions.py +++ b/ConfigSpace/conditions.py @@ -234,7 +234,7 @@ def _evaluate(self, value: Union[str, float, int]) -> bool: class LessThanCondition(AbstractCondition): def __init__(self, child: Hyperparameter, parent: Hyperparameter, value: Union[str, float, int]) -> None: super(LessThanCondition, self).__init__(child, parent) - self.parent.allow_inequality_checks() + self.parent.allow_greater_less_comparison() if not parent.is_legal(value): raise ValueError("Hyperparameter '%s' is " "conditional on the illegal value '%s' of " @@ -260,7 +260,7 @@ def _evaluate(self, value: Union[str, float, int]) -> bool: class GreaterThanCondition(AbstractCondition): def __init__(self, child: Hyperparameter, parent: Hyperparameter, value: Union[str, float, int]) -> None: super(GreaterThanCondition, self).__init__(child, parent) - self.parent.allow_inequality_checks() + self.parent.allow_greater_less_comparison() if not parent.is_legal(value): raise ValueError("Hyperparameter '%s' is " "conditional on the illegal value '%s' of " diff --git a/ConfigSpace/hyperparameters.py b/ConfigSpace/hyperparameters.py index a4cba639..e88cfcca 100644 --- a/ConfigSpace/hyperparameters.py +++ b/ConfigSpace/hyperparameters.py @@ -168,7 +168,7 @@ def compare(self, value: Union[int, float, str], value2: Union[int, float, str]) elif value == value2: return 0 - def allow_inequality_checks(self) -> bool: + def allow_greater_less_comparison(self) -> bool: return True @@ -785,7 +785,7 @@ def get_neighbors(self, value: int, rs: np.random.RandomState, number: Union[int return neighbors - def allow_inequality_checks(self) -> bool: + def allow_greater_less_comparison(self) -> bool: raise ValueError("Parent hyperparameter in a > or < " "condition must be a subclass of " "NumericalHyperparameter or " @@ -949,5 +949,5 @@ def get_neighbors(self, value: Union[int, str, float], rs: None, number: int = 2 return neighbors - def allow_inequality_checks(self) -> bool: + def allow_greater_less_comparison(self) -> bool: return True