Skip to content

Read ForbiddenRelations clauses from json #356

@JosuaCarl

Description

@JosuaCarl

As mentioned in #352, there still is some work to be done on the documentation side of things for ForbiddenRelations. Today I encountered another problem when trying to read in a ConfigurationSpace from a .json file, created with ConfigSpace.

Version: 0.7.1

Error:

"name": "KeyError",
"message": "'name'",
"stack": "---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
Cell In[3], line 20
18 with open('configspace.json', 'r') as f:
19 json_string = f.read()
---> 20 config = cs_json.read(json_string)

File XYZ/.conda/envs/MStoML/lib/python3.11/site-packages/ConfigSpace/read_and_write/json.py:459, in read(jason_string)
450 configuration_space.add_condition(
451 _construct_condition(
452 condition,
453 configuration_space,
454 ),
455 )
457 for forbidden in jason["forbiddens"]:
458 configuration_space.add_forbidden_clause(
--> 459 _construct_forbidden(
460 forbidden,
461 configuration_space,
462 ),
463 )
465 return configuration_space

File XYZ/.conda/envs/MStoML/lib/python3.11/site-packages/ConfigSpace/read_and_write/json.py:668, in _construct_forbidden(clause, cs)
661 forbidden_type = clause["type"]
662 methods = {
663 "EQUALS": _construct_forbidden_equals,
664 "IN": _construct_forbidden_in,
665 "AND": _construct_forbidden_and,
666 "RELATION": _construct_forbidden_equals,
667 }
--> 668 return methods[forbidden_type](clause, cs)

File XYZ/.conda/envs/MStoML/lib/python3.11/site-packages/ConfigSpace/read_and_write/json.py:675, in _construct_forbidden_equals(clause, cs)
671 def _construct_forbidden_equals(
672 clause: dict,
673 cs: ConfigurationSpace,
674 ) -> ForbiddenEqualsClause:
--> 675 return ForbiddenEqualsClause(hyperparameter=cs[clause["name"]], value=clause["value"])

KeyError: 'name'"

Code to reproduce:

ConfigSpace import ConfigurationSpace, Integer, ForbiddenGreaterThanRelation
from ConfigSpace.read_and_write import json as cs_json

configuration_space = ConfigurationSpace(seed=42)
hyperparameters = [
    Integer(        "intermediate_dimension",   (100, 200), log=True, default=200),
    Integer(        "latent_dimension",         (10, 200), log=False, default=50),
]
configuration_space.add_hyperparameters(hyperparameters)
forbidden_clauses = [
    ForbiddenGreaterThanRelation(configuration_space["latent_dimension"], configuration_space["intermediate_dimension"])
]
configuration_space.add_forbidden_clauses(forbidden_clauses)

cs_string = cs_json.write(configuration_space)
with open('configspace.json', 'w') as f:
     f.write(cs_string)

with open('configspace.json', 'r') as f:
    json_string = f.read()
    config = cs_json.read(json_string)

Tracing:
It seems like the following constructor:

def _construct_forbidden_relation( # pyright: ignore
clause: dict,
cs: ConfigurationSpace,
) -> ForbiddenRelation:
left = cs[clause["left"]]
right = cs[clause["right"]]
if clause["lambda"] == "LESS":
return ForbiddenLessThanRelation(left, right)
if clause["lambda"] == "EQUALS":
return ForbiddenEqualsRelation(left, right)
if clause["lambda"] == "GREATER":
return ForbiddenGreaterThanRelation(left, right)
raise ValueError("Unknown relation '%s'" % clause["lambda"])

is never called, which should happen at

"RELATION": _construct_forbidden_equals,

Instead,

def _construct_forbidden_equals(
clause: dict,
cs: ConfigurationSpace,
) -> ForbiddenEqualsClause:
return ForbiddenEqualsClause(hyperparameter=cs[clause["name"]], value=clause["value"])

is called, which in turn causes the accession attempt of 'name', which is not present in the ForbiddenRelations clause

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions