Esempio n. 1
0
    def test_convert_restrictions(self):
        # This is a smoke test to make sure that the int/float values in the
        # greater or smaller statements are converted to the right type when
        # reading them
        s = """x1 real [0,1] [0]
        x2 real [0,1] [0]
        x3 real [0,1] [0]
        x4 integer [0,2] [0]
        x5 real [0,1] [0]
        x6 ordinal {cold, luke-warm, hot} [cold]
        x1 | x2 > 0.5
        x3 | x4 > 1 && x4 == 2 && x4 in {2}
        x5 | x6 > luke-warm"""

        pcs_new.read(s.split('\n'))
Esempio n. 2
0
    def test_convert_restrictions(self):
        # This is a smoke test to make sure that the int/float values in the
        # greater or smaller statements are converted to the right type when
        # reading them
        s = """x1 real [0,1] [0]
        x2 real [0,1] [0]
        x3 real [0,1] [0]
        x4 integer [0,2] [0]
        x5 real [0,1] [0]
        x6 ordinal {cold, luke-warm, hot} [cold]
        x1 | x2 > 0.5
        x3 | x4 > 1 && x4 == 2 && x4 in {2}
        x5 | x6 > luke-warm"""

        pcs_new.read(s.split('\n'))
    def run_test(self):
        try:
            with open(configuration_space_path) as fh:
                cs = pcs_parser.read(fh)
        except:
            with open(configuration_space_path) as fh:
                cs = pcs_new_parser.read(fh)

        default = cs.get_default_configuration()
        cs._check_configuration_rigorous(default)
        for i in range(10):
            neighborhood = ConfigSpace.util.get_one_exchange_neighbourhood(
                default, seed=i)

            for shuffle, n in enumerate(neighborhood):
                n.is_valid_configuration()
                cs._check_configuration_rigorous(n)
                if shuffle == 10:
                    break

        # Sample a little bit
        for i in range(10):
            cs.seed(i)
            configurations = cs.sample_configuration(size=5)
            for j, c in enumerate(configurations):
                c.is_valid_configuration()
                cs._check_configuration_rigorous(c)
                neighborhood = ConfigSpace.util.get_one_exchange_neighbourhood(
                    c, seed=i)

                for shuffle, n in enumerate(neighborhood):
                    n.is_valid_configuration()
                    cs._check_configuration_rigorous(n)
                    if shuffle == 20:
                        break
    def run_test(self):
        try:
            with open(configuration_space_path) as fh:
                cs = pcs_parser.read(fh)
        except Exception:
            with open(configuration_space_path) as fh:
                cs = pcs_new_parser.read(fh)

        default = cs.get_default_configuration()
        cs._check_configuration_rigorous(default)
        for i in range(10):
            neighborhood = ConfigSpace.util.get_one_exchange_neighbourhood(
                default, seed=i)

            for shuffle, n in enumerate(neighborhood):
                n.is_valid_configuration()
                cs._check_configuration_rigorous(n)
                if shuffle == 10:
                    break

        # Sample a little bit
        for i in range(10):
            cs.seed(i)
            configurations = cs.sample_configuration(size=5)
            for j, c in enumerate(configurations):
                c.is_valid_configuration()
                cs._check_configuration_rigorous(c)
                neighborhood = ConfigSpace.util.get_one_exchange_neighbourhood(
                    c, seed=i)

                for shuffle, n in enumerate(neighborhood):
                    n.is_valid_configuration()
                    cs._check_configuration_rigorous(n)
                    if shuffle == 20:
                        break
Esempio n. 5
0
    def test_read_new_configuration_space_complex_conditionals(self):
        classi = OrdinalHyperparameter("classi", ["random_forest", "extra_trees", "k_nearest_neighbors", "something"])
        knn_weights = CategoricalHyperparameter("knn_weights", ["uniform", "distance"])
        weather = OrdinalHyperparameter("weather", ["sunny", "rainy", "cloudy", "snowing"])
        temperature = CategoricalHyperparameter("temperature", ["high", "low"])
        rain = CategoricalHyperparameter("rain", ["yes", "no"])
        gloves = OrdinalHyperparameter("gloves", ["none", "yarn", "leather", "gortex"])
        heur1 = CategoricalHyperparameter("heur1", ["off", "on"])
        heur2 = CategoricalHyperparameter("heur2", ["off", "on"])
        heur_order = CategoricalHyperparameter("heur_order", ["heur1then2", "heur2then1"])
        gloves_condition = OrConjunction(EqualsCondition(gloves, rain, "yes"),
                                         EqualsCondition(gloves, temperature, "low"))
        heur_condition = AndConjunction(EqualsCondition(heur_order, heur1, "on"),
                                        EqualsCondition(heur_order, heur2, "on"))
        and_conjunction = AndConjunction(NotEqualsCondition(knn_weights, classi, "extra_trees"),
                                         EqualsCondition(knn_weights, classi, "random_forest"))
        Cl_condition = OrConjunction(EqualsCondition(knn_weights, classi, "k_nearest_neighbors"),
                                     and_conjunction,
                                     EqualsCondition(knn_weights, classi, "something"))

        and1 = AndConjunction(EqualsCondition(temperature, weather, "rainy"),
                              EqualsCondition(temperature, weather, "cloudy"))
        and2 = AndConjunction(EqualsCondition(temperature, weather, "sunny"),
                              NotEqualsCondition(temperature, weather, "snowing"))
        another_condition = OrConjunction(and1, and2)

        complex_conditional_space = ConfigurationSpace()
        complex_conditional_space.add_hyperparameter(classi)
        complex_conditional_space.add_hyperparameter(knn_weights)
        complex_conditional_space.add_hyperparameter(weather)
        complex_conditional_space.add_hyperparameter(temperature)
        complex_conditional_space.add_hyperparameter(rain)
        complex_conditional_space.add_hyperparameter(gloves)
        complex_conditional_space.add_hyperparameter(heur1)
        complex_conditional_space.add_hyperparameter(heur2)
        complex_conditional_space.add_hyperparameter(heur_order)

        complex_conditional_space.add_condition(gloves_condition)
        complex_conditional_space.add_condition(heur_condition)
        complex_conditional_space.add_condition(Cl_condition)
        complex_conditional_space.add_condition(another_condition)

        complex_cs = list()
        complex_cs.append("classi ordinal {random_forest,extra_trees,k_nearest_neighbors, something} [random_forest]")
        complex_cs.append("knn_weights categorical {uniform, distance} [uniform]")
        complex_cs.append("weather ordinal {sunny, rainy, cloudy, snowing} [sunny]")
        complex_cs.append("temperature categorical {high, low} [high]")
        complex_cs.append("rain categorical { yes, no } [yes]")
        complex_cs.append("gloves ordinal { none, yarn, leather, gortex } [none]")
        complex_cs.append("heur1 categorical { off, on } [off]")
        complex_cs.append("heur2 categorical { off, on } [off]")
        complex_cs.append("heur_order categorical { heur1then2, heur2then1 } [heur1then2]")
        complex_cs.append("gloves | rain == yes || temperature == low")
        complex_cs.append("heur_order | heur1 == on && heur2 == on")
        complex_cs.append("knn_weights | classi == k_nearest_neighbors || "
                          "classi != extra_trees && classi == random_forest || classi == something")
        complex_cs.append("temperature | weather == rainy && weather == cloudy || "
                          "weather == sunny && weather != snowing")
        cs_new = pcs_new.read(complex_cs)
        self.assertEqual(cs_new, complex_conditional_space)
Esempio n. 6
0
    def test_read_new_configuration_space_forbidden(self):
        cs_with_forbidden = ConfigurationSpace()
        int_hp = UniformIntegerHyperparameter('int_hp', 0, 50, 30)
        float_hp = UniformFloatHyperparameter('float_hp', 0., 50., 30.)
        cat_hp_str = CategoricalHyperparameter('cat_hp_str', ['a', 'b', 'c'], 'b')
        ord_hp_str = OrdinalHyperparameter('ord_hp_str', ['a', 'b', 'c'], 'b')

        cs_with_forbidden.add_hyperparameters([int_hp, float_hp, cat_hp_str, ord_hp_str])

        int_hp_forbidden = ForbiddenAndConjunction(ForbiddenEqualsClause(int_hp, 1))

        float_hp_forbidden_1 = ForbiddenEqualsClause(float_hp, 1.0)
        float_hp_forbidden_2 = ForbiddenEqualsClause(float_hp, 2.0)
        float_hp_forbidden = ForbiddenAndConjunction(float_hp_forbidden_1, float_hp_forbidden_2)

        cat_hp_str_forbidden = ForbiddenAndConjunction(ForbiddenEqualsClause(cat_hp_str, 'a'))
        ord_hp_float_forbidden = ForbiddenAndConjunction(ForbiddenEqualsClause(ord_hp_str, 'a'))
        cs_with_forbidden.add_forbidden_clauses([int_hp_forbidden, float_hp_forbidden,
                                                 cat_hp_str_forbidden, ord_hp_float_forbidden])

        complex_cs = list()
        complex_cs.append("int_hp integer [0,50] [30]")
        complex_cs.append("float_hp real [0.0, 50.0] [30.0]")
        complex_cs.append("cat_hp_str categorical {a, b, c} [b]")
        complex_cs.append("ord_hp_str ordinal {a, b, c} [b]")
        complex_cs.append("# Forbiddens:")
        complex_cs.append("{int_hp=1}")
        complex_cs.append("{float_hp=1.0, float_hp=2.0}")
        complex_cs.append("{cat_hp_str=a}")
        complex_cs.append("{ord_hp_str=a}")
        cs_new = pcs_new.read(complex_cs)

        self.assertEqual(cs_new, cs_with_forbidden)
Esempio n. 7
0
    def load_configspace(self, folder):
        """Will try to load the configspace. If it's a pcs-file, backup_cs will be a list containing all possible
        combinations of interpretation for Categoricals. If this issue will be fixed, we can drop this procedure."""
        cs_fn_json = os.path.join(folder, 'configspace.json')
        cs_fn_pcs = os.path.join(folder, 'configspace.pcs')
        if os.path.exists(cs_fn_json):
            with open(cs_fn_json, 'r') as fh:
                cs = pcs_json.read(fh.read())
                backup_cs = []
            self.logger.debug(
                "Detected and loaded \"%s\". No backup-cs necessary",
                cs_fn_json)
        elif os.path.exists(cs_fn_pcs):
            with open(cs_fn_pcs, 'r') as fh:
                cs = pcs_new.read(fh.readlines())
            # Create alternative interpretations
            categoricals = [
                hp for hp in cs.get_hyperparameters()
                if isinstance(hp, CategoricalHyperparameter)
            ]
            non_categoricals = [
                hp for hp in cs.get_hyperparameters()
                if not isinstance(hp, CategoricalHyperparameter)
            ]

            def _get_interpretations(choices):
                result = []
                if set(choices) == {"True", "False"}:
                    result.append([True, False])
                if all([c.isdigit() for c in choices]):
                    result.append([int(c) for c in choices])
                result.append(choices)
                return result

            choices_per_cat = [
                _get_interpretations(hp.choices) for hp in categoricals
            ]
            combinations = itertools.product(*choices_per_cat)
            self.logger.debug(combinations)
            backup_cs = []
            for combi in combinations:
                bcs = ConfigurationSpace()
                for hp in non_categoricals:
                    bcs.add_hyperparameter(hp)
                for name, choices in zip([hp.name for hp in categoricals],
                                         combi):
                    bcs.add_hyperparameter(
                        CategoricalHyperparameter(name, choices))
                bcs.add_conditions(cs.get_conditions())
                backup_cs.append(bcs)

            self.logger.debug("Sampled %d interpretations of \"%s\"",
                              len(backup_cs), cs_fn_pcs)
            self.logger.debug(choices_per_cat)
        else:
            raise ValueError("Missing pcs-file at '%s.[pcs|json]'!" %
                             os.path.join(folder, 'configspace'))
        return cs, backup_cs
Esempio n. 8
0
    def test_write_restrictions(self):
        s = "c integer [0, 2] [0]\n" + \
            "d ordinal {cold, luke-warm, hot} [cold]\n" + \
            "e real [0.0, 1.0] [0.0]\n" + \
            "b real [0.0, 1.0] [0.0]\n" + \
            "a real [0.0, 1.0] [0.0]\n" + \
            "\n" + \
            "b | d in {luke-warm, hot} || c > 1\n" + \
            "a | b == 0.5 && e > 0.5"

        a = pcs_new.read(s.split('\n'))
        out = pcs_new.write(a)
        self.assertEqual(out, s)
Esempio n. 9
0
    def test_write_restrictions(self):
        s = "c integer [0, 2] [0]\n" + \
            "d ordinal {cold, luke-warm, hot} [cold]\n" + \
            "e real [0.0, 1.0] [0.0]\n" + \
            "b real [0.0, 1.0] [0.0]\n" + \
            "a real [0.0, 1.0] [0.0]\n" + \
            "\n" + \
            "b | d in {luke-warm, hot} || c > 1\n" + \
            "a | b == 0.5 && e > 0.5"

        a = pcs_new.read(s.split('\n'))
        out = pcs_new.write(a)
        self.assertEqual(out, s)
Esempio n. 10
0
 def test_read_new_configuration_space_easy(self):
     expected = StringIO()
     expected.write('# This is a \n')
     expected.write('   # This is a comment with a leading whitespace ### ffds \n')
     expected.write('\n')
     expected.write('float_a real [-1.23, 6.45] [2.61] # bla\n')
     expected.write('e_float_a real [.5E-2, 4.5e+06] [2250000.0025]\n')
     expected.write('int_a integer [-1, 6] [2]\n')
     expected.write('log_a real [4e-1, 6.45] [1.6062378404]log\n')
     expected.write('int_log_a integer [1, 6] [2]log\n')
     expected.write('cat_a categorical {a,"b",c,d} [a]\n')
     expected.write(r'@.:;/\?!$%&_-<>*+1234567890 categorical {"const"} ["const"]\n')
     expected.seek(0)
     cs = pcs_new.read(expected)
     self.assertEqual(cs, easy_space)
Esempio n. 11
0
 def test_read_new_configuration_space_easy(self):
     expected = StringIO()
     expected.write('# This is a \n')
     expected.write('   # This is a comment with a leading whitespace ### ffds \n')
     expected.write('\n')
     expected.write('float_a real [-1.23, 6.45] [2.61] # bla\n')
     expected.write('e_float_a real [.5E-2, 4.5e+06] [2250000.0025]\n')
     expected.write('int_a integer [-1, 6] [2]\n')
     expected.write('log_a real [4e-1, 6.45] [1.6062378404]log\n')
     expected.write('int_log_a integer [1, 6] [2]log\n')
     expected.write('cat_a categorical {a,"b",c,d} [a]\n')
     expected.write(r'@.:;/\?!$%&_-<>*+1234567890 categorical {"const"} ["const"]\n')
     expected.seek(0)
     cs = pcs_new.read(expected)
     self.assertEqual(cs, easy_space)
Esempio n. 12
0
    def test_read_new_configuration_space_conditional(self):
        # More complex search space as string array
        complex_cs = list()
        complex_cs.append("preprocessing categorical {None, pca} [None]")
        complex_cs.append("classifier categorical {svm, nn} [svm]")
        complex_cs.append("kernel categorical {rbf, poly, sigmoid} [rbf]")
        complex_cs.append("C real [0.03125, 32768] [32]log")
        complex_cs.append("neurons integer [16, 1024] [520] # Should be Q16")
        complex_cs.append("lr real [0.0001, 1.0] [0.50005]")
        complex_cs.append("degree integer [1, 5] [3]")
        complex_cs.append("gamma real [0.000030518, 8] [0.0156251079996]log")

        complex_cs.append("C | classifier in {svm}")
        complex_cs.append("kernel | classifier in {svm}")
        complex_cs.append("lr | classifier in {nn}")
        complex_cs.append("neurons | classifier in {nn}")
        complex_cs.append("degree | kernel in {poly, sigmoid}")
        complex_cs.append("gamma | kernel in {rbf}")

        cs_new = pcs_new.read(complex_cs)
        self.assertEqual(cs_new, conditional_space)

        # same in older version
        complex_cs_old = list()
        complex_cs_old.append("preprocessing {None, pca} [None]")
        complex_cs_old.append("classifier {svm, nn} [svm]")
        complex_cs_old.append("kernel {rbf, poly, sigmoid} [rbf]")
        complex_cs_old.append("C [0.03125, 32768] [32]l")
        complex_cs_old.append("neurons [16, 1024] [520]i # Should be Q16")
        complex_cs_old.append("lr [0.0001, 1.0] [0.50005]")
        complex_cs_old.append("degree [1, 5] [3]i")
        complex_cs_old.append("gamma [0.000030518, 8] [0.0156251079996]l")

        complex_cs_old.append("C | classifier in {svm}")
        complex_cs_old.append("kernel | classifier in {svm}")
        complex_cs_old.append("lr | classifier in {nn}")
        complex_cs_old.append("neurons | classifier in {nn}")
        complex_cs_old.append("degree | kernel in {poly, sigmoid}")
        complex_cs_old.append("gamma | kernel in {rbf}")

        cs_old = pcs.read(complex_cs_old)
        self.assertEqual(cs_old, cs_new)
Esempio n. 13
0
    def test_read_new_configuration_space_conditional(self):
        # More complex search space as string array
        complex_cs = list()
        complex_cs.append("preprocessing categorical {None, pca} [None]")
        complex_cs.append("classifier categorical {svm, nn} [svm]")
        complex_cs.append("kernel categorical {rbf, poly, sigmoid} [rbf]")
        complex_cs.append("C real [0.03125, 32768] [32]log")
        complex_cs.append("neurons integer [16, 1024] [520] # Should be Q16")
        complex_cs.append("lr real [0.0001, 1.0] [0.50005]")
        complex_cs.append("degree integer [1, 5] [3]")
        complex_cs.append("gamma real [0.000030518, 8] [0.0156251079996]log")

        complex_cs.append("C | classifier in {svm}")
        complex_cs.append("kernel | classifier in {svm}")
        complex_cs.append("lr | classifier in {nn}")
        complex_cs.append("neurons | classifier in {nn}")
        complex_cs.append("degree | kernel in {poly, sigmoid}")
        complex_cs.append("gamma | kernel in {rbf}")

        cs_new = pcs_new.read(complex_cs)
        self.assertEqual(cs_new, conditional_space)

        # same in older version
        complex_cs_old = list()
        complex_cs_old.append("preprocessing {None, pca} [None]")
        complex_cs_old.append("classifier {svm, nn} [svm]")
        complex_cs_old.append("kernel {rbf, poly, sigmoid} [rbf]")
        complex_cs_old.append("C [0.03125, 32768] [32]l")
        complex_cs_old.append("neurons [16, 1024] [520]i # Should be Q16")
        complex_cs_old.append("lr [0.0001, 1.0] [0.50005]")
        complex_cs_old.append("degree [1, 5] [3]i")
        complex_cs_old.append("gamma [0.000030518, 8] [0.0156251079996]l")

        complex_cs_old.append("C | classifier in {svm}")
        complex_cs_old.append("kernel | classifier in {svm}")
        complex_cs_old.append("lr | classifier in {nn}")
        complex_cs_old.append("neurons | classifier in {nn}")
        complex_cs_old.append("degree | kernel in {poly, sigmoid}")
        complex_cs_old.append("gamma | kernel in {rbf}")

        cs_old = pcs.read(complex_cs_old)
        self.assertEqual(cs_old, cs_new)
Esempio n. 14
0
    def convert(self, folder):
        try:
            from hpbandster.core.result import Result as HPBResult
            from hpbandster.core.result import logged_results_to_HB_result
        except ImportError as e:
            raise ImportError(
                "To analyze BOHB-data, please install hpbandster (e.g. `pip install hpbandster`)"
            )

        result = logged_results_to_HB_result(folder)

        cs_fn = os.path.join(folder, 'configspace.pcs')
        if not os.path.exists(cs_fn):
            raise ValueError("Missing pcs-file at '%s'!" % cs_fn)
        with open(cs_fn, 'r') as fh:
            cs = pcs_new.read(fh.readlines())

        # Using temporary files for the intermediate smac-result-like format
        tmp_dir = tempfile.mkdtemp()
        paths = list(self.hpbandster2smac(result, cs, tmp_dir).values())
        return result, paths
Esempio n. 15
0
def load_configspace(path_to_cs_file):
    """
    Load configuration space definition
    Args:
        path_to_cs_file: Path to the file, in which the configuration space is
            defined. Must be in format pcs or json

    Returns:
        ConfigSpace.configuration_space
    """
    if path_to_cs_file.endswith('.pcs'):
        with open(path_to_cs_file, 'r') as f:
            cfg = pcs_new.read(f)
    elif path_to_cs_file.endswith('.json'):
        with open(path_to_cs_file, 'r') as f:
            cfg = json.read(f.read())
    else:
        raise ImportError('Configuration space definition not understood. File'
                          ' must be in format pcs or json.')

    return cfg
Esempio n. 16
0
    def execute(save_folder, runhistory_location, configspace_location, manual_logtransform, use_percentiles, interaction_effect, n_trees, run_limit=None, draw_plots=True):
        with open(runhistory_location) as runhistory_file:
            runhistory = json.load(runhistory_file)
        with open(configspace_location) as configspace_file:
            configspace = read(configspace_file)
        os.makedirs(save_folder, exist_ok=True)

        X = []
        y = []

        for item in runhistory['data']:
            if run_limit is not None and len(X) > run_limit:
                break

            valid = True
            current = []
            setup_id = str(item[0][0])
            configuration = runhistory['configs'][setup_id]
            for param in configspace.get_hyperparameters():
                value = configuration[param.name]
                if isinstance(param, ConfigSpace.hyperparameters.UniformFloatHyperparameter) and not isinstance(value, float):
                    valid = False
                elif isinstance(param, ConfigSpace.hyperparameters.UniformIntegerHyperparameter) and not isinstance(value, int):
                    valid = False

                if isinstance(param, ConfigSpace.hyperparameters.CategoricalHyperparameter):
                    value = param.choices.index(value)
                elif param.log and manual_logtransform:
                    value = np.log(value)

                current.append(value)
            if valid:
                X.append(current)
                y.append(item[1][0])
            else:
                print('Illegal configuration', current)
        X = np.array(X)
        y = np.array(y)

        if X.ndim != 2:
            raise ValueError('Wrong shape')

        if manual_logtransform:
            configspace = openmlpimp.utils.scale_configspace_to_log(configspace)

        cutoffs = (-np.inf, np.inf)
        if use_percentiles:
            p75 = np.percentile(y, 75.0)
            p100 = np.percentile(y, 100.0)
            cutoffs = (p75, p100)

        # start the evaluator
        evaluator = fanova_pyrfr(X=X, Y=y, config_space=configspace, config_on_hypercube=False, cutoffs=cutoffs, n_trees=n_trees)
        # obtain the results
        params = configspace.get_hyperparameters()
        result = {}

        for idx, param in enumerate(params):
            importance = evaluator.quantify_importance([idx])[(idx,)]['total importance']
            result[param.name] = importance

        # store main results to disk
        filename = 'pimp_values_fanova.json'
        with open(os.path.join(save_folder, filename), 'w') as out_file:
            json.dump(result, out_file, sort_keys=True, indent=4, separators=(',', ': '))
            print('Saved individuals to %s' %os.path.join(save_folder, filename))

        # call plotting fn
        yrange = (0, 1)
        if use_percentiles:
            yrange = (p75, p100)
        if draw_plots:
            FanovaBackend._plot_result(evaluator, configspace, save_folder + '/fanova', yrange)

        if interaction_effect:
            result_interaction = {}
            for idx, param in enumerate(params):
                for idx2, param2 in enumerate(params):
                    if param.name >= param2.name: # string comparison cause stable
                        continue
                    print('interaction effects between', param.name, param2.name)
                    interaction = evaluator.quantify_importance([idx, idx2])[(idx,idx2)]['total importance']
                    interaction -= result[param.name]
                    interaction -= result[param2.name]
                    combined_name = param.name + '__' + param2.name
                    if interaction < 0.0:
                        raise ValueError('interaction score too low. Params: %s score %d' %(combined_name, interaction))
                    result_interaction[combined_name] = interaction

            for idx, param in enumerate(params):
                for idx2, param2 in enumerate(params):
                    if param.name >= param2.name:  # string comparison cause stable
                        continue
                    for idx3, param3 in enumerate(params):
                        if param2.name >= param3.name:  # string comparison cause stable
                            continue

                        print('interaction effects between', param.name, param2.name, param3.name)
                        interaction = evaluator.quantify_importance([idx, idx2, idx3])[(idx, idx2, idx3)]['total importance']
                        interaction -= result[param.name]
                        interaction -= result[param2.name]
                        interaction -= result[param3.name]
                        combined_name = param.name + '__' + param2.name + '__' + param3.name

                        interaction -= result_interaction[param.name + '__' + param2.name]
                        interaction -= result_interaction[param2.name + '__' + param3.name]
                        interaction -= result_interaction[param.name + '__' + param3.name]

                        if interaction < 0.0:
                            raise ValueError('interaction score too low. Params: %s score %d' % (combined_name, interaction))
                        result_interaction[combined_name] = interaction

            # store interaction effects to disk

            if sum(result_interaction.values()) + sum(result.values()) > 1:
                raise ValueError('Sum of results too high')

            filename = 'pimp_values_fanova_interaction.json'
            with open(os.path.join(save_folder, filename), 'w') as out_file:
                json.dump(result_interaction, out_file, sort_keys=True, indent=4, separators=(',', ': '))
                print('Saved interactions to %s' %os.path.join(save_folder, filename))
            if draw_plots:
                vis = Visualizer(evaluator, configspace, save_folder + '/fanova', y_label='Predictive Accuracy')
                vis.create_most_important_pairwise_marginal_plots()

        return save_folder + "/" + filename
Esempio n. 17
0
    def test_read_new_configuration_space_complex_conditionals(self):
        classi = OrdinalHyperparameter(
            "classi",
            [
                "random_forest", "extra_trees", "k_nearest_neighbors",
                "something"
            ],
        )
        knn_weights = CategoricalHyperparameter("knn_weights",
                                                ["uniform", "distance"])
        weather = OrdinalHyperparameter(
            "weather", ["sunny", "rainy", "cloudy", "snowing"])
        temperature = CategoricalHyperparameter("temperature", ["high", "low"])
        rain = CategoricalHyperparameter("rain", ["yes", "no"])
        gloves = OrdinalHyperparameter("gloves",
                                       ["none", "yarn", "leather", "gortex"])
        heur1 = CategoricalHyperparameter("heur1", ["off", "on"])
        heur2 = CategoricalHyperparameter("heur2", ["off", "on"])
        heur_order = CategoricalHyperparameter("heur_order",
                                               ["heur1then2", "heur2then1"])
        gloves_condition = OrConjunction(
            EqualsCondition(gloves, rain, "yes"),
            EqualsCondition(gloves, temperature, "low"))
        heur_condition = AndConjunction(
            EqualsCondition(heur_order, heur1, "on"),
            EqualsCondition(heur_order, heur2, "on"))
        and_conjunction = AndConjunction(
            NotEqualsCondition(knn_weights, classi, "extra_trees"),
            EqualsCondition(knn_weights, classi, "random_forest"))
        Cl_condition = OrConjunction(
            EqualsCondition(knn_weights, classi, "k_nearest_neighbors"),
            and_conjunction, EqualsCondition(knn_weights, classi, "something"))

        and1 = AndConjunction(EqualsCondition(temperature, weather, "rainy"),
                              EqualsCondition(temperature, weather, "cloudy"))
        and2 = AndConjunction(
            EqualsCondition(temperature, weather, "sunny"),
            NotEqualsCondition(temperature, weather, "snowing"))
        another_condition = OrConjunction(and1, and2)

        complex_conditional_space = ConfigurationSpace()
        complex_conditional_space.add_hyperparameter(classi)
        complex_conditional_space.add_hyperparameter(knn_weights)
        complex_conditional_space.add_hyperparameter(weather)
        complex_conditional_space.add_hyperparameter(temperature)
        complex_conditional_space.add_hyperparameter(rain)
        complex_conditional_space.add_hyperparameter(gloves)
        complex_conditional_space.add_hyperparameter(heur1)
        complex_conditional_space.add_hyperparameter(heur2)
        complex_conditional_space.add_hyperparameter(heur_order)

        complex_conditional_space.add_condition(gloves_condition)
        complex_conditional_space.add_condition(heur_condition)
        complex_conditional_space.add_condition(Cl_condition)
        complex_conditional_space.add_condition(another_condition)

        complex_cs = list()
        complex_cs.append(
            "classi ordinal {random_forest,extra_trees,k_nearest_neighbors, something} "
            "[random_forest]")
        complex_cs.append(
            "knn_weights categorical {uniform, distance} [uniform]")
        complex_cs.append(
            "weather ordinal {sunny, rainy, cloudy, snowing} [sunny]")
        complex_cs.append("temperature categorical {high, low} [high]")
        complex_cs.append("rain categorical { yes, no } [yes]")
        complex_cs.append(
            "gloves ordinal { none, yarn, leather, gortex } [none]")
        complex_cs.append("heur1 categorical { off, on } [off]")
        complex_cs.append("heur2 categorical { off, on } [off]")
        complex_cs.append(
            "heur_order categorical { heur1then2, heur2then1 } [heur1then2]")
        complex_cs.append("gloves | rain == yes || temperature == low")
        complex_cs.append("heur_order | heur1 == on && heur2 == on")
        complex_cs.append(
            "knn_weights | classi == k_nearest_neighbors || "
            "classi != extra_trees && classi == random_forest || classi == something"
        )
        complex_cs.append(
            "temperature | weather == rainy && weather == cloudy || "
            "weather == sunny && weather != snowing")
        cs_new = pcs_new.read(complex_cs)
        self.assertEqual(cs_new, complex_conditional_space)
Esempio n. 18
0
    def handle_update_search_space(self, data):
        """change json format to ConfigSpace format dict<dict> -> configspace

        Parameters
        ----------
        data: JSON object
            search space of this experiment
        """
        search_space = data
        cs = None
        logger.debug(f'Received data: {data}')
        if self.config_space:
            logger.info(
                f'Got a ConfigSpace file path, parsing the search space directly from {self.config_space}. '
                'The NNI search space is ignored.')
            with open(self.config_space, 'r') as fh:
                cs = pcs_new.read(fh)
        else:
            cs = CS.ConfigurationSpace()
            for var in search_space:
                _type = str(search_space[var]["_type"])
                if _type == 'choice':
                    cs.add_hyperparameter(
                        CSH.CategoricalHyperparameter(
                            var, choices=search_space[var]["_value"]))
                elif _type == 'randint':
                    cs.add_hyperparameter(
                        CSH.UniformIntegerHyperparameter(
                            var,
                            lower=search_space[var]["_value"][0],
                            upper=search_space[var]["_value"][1] - 1))
                elif _type == 'uniform':
                    cs.add_hyperparameter(
                        CSH.UniformFloatHyperparameter(
                            var,
                            lower=search_space[var]["_value"][0],
                            upper=search_space[var]["_value"][1]))
                elif _type == 'quniform':
                    cs.add_hyperparameter(
                        CSH.UniformFloatHyperparameter(
                            var,
                            lower=search_space[var]["_value"][0],
                            upper=search_space[var]["_value"][1],
                            q=search_space[var]["_value"][2]))
                elif _type == 'loguniform':
                    cs.add_hyperparameter(
                        CSH.UniformFloatHyperparameter(
                            var,
                            lower=search_space[var]["_value"][0],
                            upper=search_space[var]["_value"][1],
                            log=True))
                elif _type == 'qloguniform':
                    cs.add_hyperparameter(
                        CSH.UniformFloatHyperparameter(
                            var,
                            lower=search_space[var]["_value"][0],
                            upper=search_space[var]["_value"][1],
                            q=search_space[var]["_value"][2],
                            log=True))
                elif _type == 'normal':
                    cs.add_hyperparameter(
                        CSH.NormalFloatHyperparameter(
                            var,
                            mu=search_space[var]["_value"][1],
                            sigma=search_space[var]["_value"][2]))
                elif _type == 'qnormal':
                    cs.add_hyperparameter(
                        CSH.NormalFloatHyperparameter(
                            var,
                            mu=search_space[var]["_value"][1],
                            sigma=search_space[var]["_value"][2],
                            q=search_space[var]["_value"][3]))
                elif _type == 'lognormal':
                    cs.add_hyperparameter(
                        CSH.NormalFloatHyperparameter(
                            var,
                            mu=search_space[var]["_value"][1],
                            sigma=search_space[var]["_value"][2],
                            log=True))
                elif _type == 'qlognormal':
                    cs.add_hyperparameter(
                        CSH.NormalFloatHyperparameter(
                            var,
                            mu=search_space[var]["_value"][1],
                            sigma=search_space[var]["_value"][2],
                            q=search_space[var]["_value"][3],
                            log=True))
                else:
                    raise ValueError(
                        'unrecognized type in search_space, type is {}'.format(
                            _type))

        self.search_space = cs
Esempio n. 19
0
    def load_configspace(self, folder):
        """Will try to load the configspace. cs_options will be a list containing all possible
        combinations of interpretation for Categoricals. If this issue will be fixed, we can drop this procedure.

        Parameters
        ----------
        folder: str
            path to folder in which to look for configspace

        Returns
        -------
        cs_options: list[ConfigurationSpace]
            list with possible interpretations for config-space-file. Only contains multiple items if file-format is pcs.
        """
        cs_options = []
        cs_fn_json = os.path.join(folder, 'configspace.json')
        cs_fn_pcs = os.path.join(folder, 'configspace.pcs')

        if os.path.exists(cs_fn_json):
            with open(cs_fn_json, 'r') as fh:
                cs_options = [pcs_json.read(fh.read())]
            self.logger.debug(
                "Detected and loaded \"%s\". No alternative interpretations necessary",
                cs_fn_json)
        elif os.path.exists(cs_fn_pcs):
            with open(cs_fn_pcs, 'r') as fh:
                cs = pcs_new.read(fh.readlines())
            # Create alternative interpretations
            categoricals = [
                hp for hp in cs.get_hyperparameters()
                if isinstance(hp, CategoricalHyperparameter)
            ]
            non_categoricals = [
                hp for hp in cs.get_hyperparameters()
                if not isinstance(hp, CategoricalHyperparameter)
            ]

            def _get_interpretations(choices):
                """ Generate different interpretations for critical categorical hyperparameters that are not seamlessly
                supported by pcs-format."""
                result = []
                if set(choices) == {"True", "False"}:
                    result.append([True, False])
                if all([c.isdigit() for c in choices]):
                    result.append([int(c) for c in choices])
                result.append(choices)
                return result

            choices_per_cat = [
                _get_interpretations(hp.choices) for hp in categoricals
            ]
            combinations = itertools.product(*choices_per_cat)
            self.logger.debug(combinations)
            for combi in combinations:
                bcs = ConfigurationSpace()
                for hp in non_categoricals:
                    bcs.add_hyperparameter(hp)
                for name, choices in zip([hp.name for hp in categoricals],
                                         combi):
                    bcs.add_hyperparameter(
                        CategoricalHyperparameter(name, choices))
                bcs.add_conditions(cs.get_conditions())
                cs_options.append(bcs)

            self.logger.debug("Sampled %d interpretations of \"%s\"",
                              len(cs_options), cs_fn_pcs)
        else:
            raise ValueError("Missing pcs-file at '%s.[pcs|json]'!" %
                             os.path.join(folder, 'configspace'))
        return cs_options
Esempio n. 20
0
 def get_configspace():
     with open('searchspace.pcs', 'r') as fh:
         cs = pcs_new.read(fh)
         return cs
            # TODO: make the default!
            ignore_parameters = fixed_parameters_to_ignore_parameters(
                args.fixed_parameters)
            runhistory_path, configspace_path = openmlpimp.utils.cache_runhistory_configspace(
                task_cache_folder,
                args.flow_id,
                task_id,
                model_type=args.model_type,
                required_setups=args.required_setups,
                reverse=False,
                fixed_parameters=args.fixed_parameters,
                ignore_parameters=ignore_parameters)

            if total_ranks is None:
                with open(configspace_path) as configspace_file:
                    configspace = read(configspace_file)
                total_ranks = {
                    param.name: 0
                    for param in configspace.get_hyperparameters()
                }

            if args.modus == 'fanova':
                print('Running FANOVA backend on task %d' % task_id)
                results_file = FanovaBackend.execute(
                    task_save_folder,
                    runhistory_path,
                    configspace_path,
                    use_percentiles=args.use_quantiles,
                    interaction_effect=args.interaction_effect,
                    n_trees=args.n_trees,
                    run_limit=args.limit,