def to_networkx(self, prefix: str = None):
        import networkx as nx
        g = nx.DiGraph()
        predecessor = None
        for name, estimator in self.steps_.items():
            name = prefixed_name(prefix, name)
            g.add_node(name, label=estimator.name().split('.')[-1], name=name)

            if predecessor is not None:
                g.add_edge(predecessor, name)
            predecessor = name
        return g
Example #2
0
    def _get_config_for_step(self, idx: int, prefix: str, name: str,
                             logger: ProcessLogger) -> Configuration:
        start = timeit.default_timer()

        cfg_key = self.cfg_keys[idx]
        config, cfg_key = self.cfg_cache.sample_configuration(cid=self.cid,
                                                              name=name,
                                                              cfg_key=cfg_key)

        intermediate = PartialConfig(cfg_key, config, name, None)
        logger.new_step(prefixed_name(prefix, name), intermediate)

        self.config_time += timeit.default_timer() - start
        return config
Example #3
0
def merge_configurations(
        partial_configs,  # type: List[PartialConfig]
        cs: ConfigurationSpace) -> Configuration:
    complete = {}
    for partial_config in partial_configs:
        for param, value in partial_config.config.get_dictionary().items():
            param = prefixed_name(partial_config.name, param)
            complete[param] = value

    config = Configuration(cs, complete)
    config.origin = Counter([
        p.config.origin for p in partial_configs if not p.is_empty()
    ]).most_common(1)[0][0]
    return config
Example #4
0
    def __init__(self, data: Dict[CandidateId, CandidateStructure],
                 meta_information: MetaInformation,
                 structure_xai: Dict[str, Any], config_xai: Dict[ConfigKey,
                                                                 Any]):
        # Map structures to JSON structure
        structures = []

        config_explanations = {}

        for s in data.values():
            structure = s.as_dict()
            # Store budget in each configuration instead of only in structure. Only necessary for compatability with
            # other AutoML frameworks
            structure['configs'] = [
                r.as_dict(s.budget,
                          loss_sign=metric_sign(meta_information.metric))
                for r in s.results
            ]
            del structure['budget']
            del structure['cfg_keys']
            structures.append(structure)

            # Extract and merge all (partial-) configurations
            explanations_for_steps = [config_xai[key] for key in s.cfg_keys]

            for cid in [r.cid.external_name for r in s.results]:
                try:
                    partial_configs = []
                    loss = []
                    marginalization = {}
                    for explanations_for_step in explanations_for_steps:
                        pcs = explanations_for_step[cid]['candidates']
                        if len(pcs) == 0:
                            continue

                        prefix = pcs[0].name
                        partial_configs.append(pcs)
                        loss.append(explanations_for_step[cid]['loss'])
                        marginalization = {
                            **marginalization,
                            **{
                                prefixed_name(prefix, key): value
                                for key, value in explanations_for_step[cid]['marginalization'].items(
                                )
                            }
                        }

                    if len(loss) > 0 and len(partial_configs) == len(
                            explanations_for_steps):
                        loss = np.array(loss).T.mean(axis=1)
                        configs = [
                            merge_configurations(
                                pc.tolist(), s.configspace).get_dictionary()
                            for pc in np.array(partial_configs).T
                        ]

                        config_explanations[cid] = {
                            'loss': np.clip(loss, -100, 100).tolist(),
                            'candidates': configs,
                            'marginalization': marginalization
                        }
                except ValueError as ex:
                    # noinspection PyUnboundLocalVariable
                    logging.error(
                        'Failed to reconstruct global config.\n'
                        f'Exception: {ex}\nStructure: {structure["pipeline"]}\n'
                        f'ConfigSpace: {structure["configspace"]}\nConfig: {partial_configs}'
                    )
                except KeyError:
                    logging.error(
                        f'Failed to find cid {cid} in config explanations')

        self.data = data
        self.meta_information = meta_information
        self.complete_data = {
            'meta': meta_information.as_dict(),
            'structures': structures,
            'explanations': {
                'structures': structure_xai,
                'configs': config_explanations
            }
        }
Example #5
0
 def all_names(self, prefix: str = None) -> List[str]:
     res = []
     for name, component in self.steps_.items():
         res.append(prefixed_name(prefix, name))
     return res