def _step_id_to_string( step_id: int, pipeline: TrainablePipeline, cls2label: Dict[str, str] = {}, ) -> str: if step_id == _DUMMY_INPUT_STEP: return "INP" if step_id == _DUMMY_SCORE_STEP: return "SCR" step = pipeline.steps_list()[step_id] cls = step.class_name() return cls2label[cls] if cls in cls2label else step.name()
def create_instance_from_hyperopt_search_space(lale_object, hyperparams): ''' Hyperparams is a n-tuple of dictionaries of hyper-parameters, each dictionary corresponds to an operator in the pipeline ''' #lale_object can either be an individual operator, a pipeline or an operatorchoice #Validate that the number of elements in the n-tuple is the same #as the number of steps in the current pipeline from lale.operators import IndividualOp from lale.operators import Pipeline from lale.operators import TrainablePipeline from lale.operators import OperatorChoice if isinstance(lale_object, IndividualOp): if hyperparams: hyperparams.pop('name', None) return lale_object(**hyperparams) elif isinstance(lale_object, Pipeline): if len(hyperparams) != len(lale_object.steps()): raise ValueError( 'The number of steps in the hyper-parameter space does not match the number of steps in the pipeline.' ) op_instances = [] edges = lale_object.edges() #op_map:Dict[PlannedOpType, TrainableOperator] = {} op_map = {} for op_index in range(len(hyperparams)): state_params = hyperparams[op_index] #TODO: Should ideally check if the class_name is the same as the class name of the op from self.operators() at op_index op_instance = create_instance_from_hyperopt_search_space( lale_object.steps()[op_index], state_params) op_instances.append(op_instance) orig_op = lale_object._steps[op_index] op_map[orig_op] = op_instance #trainable_edges:List[Tuple[TrainableOperator, TrainableOperator]] try: trainable_edges = [(op_map[x], op_map[y]) for (x, y) in edges] except KeyError as e: raise ValueError( "An edge was found with an endpoint that is not a step (" + str(e) + ")") return TrainablePipeline(op_instances, trainable_edges, ordered=True) elif isinstance(lale_object, OperatorChoice): #Hyperopt search space for an OperatorChoice is generated as a dictionary with a single element #corresponding to the choice made, the only key is the index of the step and the value is #the params corresponding to that step. step_index, hyperparams = hyperparams.popitem() step_object = lale_object.steps()[step_index] return create_instance_from_hyperopt_search_space( step_object, hyperparams)
def create_instance_from_hyperopt_search_space(lale_object, hyperparams): ''' Hyperparams is a n-tuple of dictionaries of hyper-parameters, each dictionary corresponds to an operator in the pipeline ''' #lale_object can either be an individual operator, a pipeline or an operatorchoice #Validate that the number of elements in the n-tuple is the same #as the number of steps in the current pipeline from lale.operators import (BasePipeline, IndividualOp, Operator, OperatorChoice, TrainablePipeline) if isinstance(lale_object, IndividualOp): new_hyperparams: Dict[str, Any] = dict_without(hyperparams, 'name') if lale_object._hyperparams is not None: obj_hyperparams = dict(lale_object._hyperparams) else: obj_hyperparams = {} for k, sub_params in new_hyperparams.items(): if k in obj_hyperparams: sub_op = obj_hyperparams[k] updated_params = instantiate_from_hyperopt_search_space( sub_op, sub_params) if updated_params is not None: new_hyperparams[k] = updated_params all_hyperparams = {**obj_hyperparams, **new_hyperparams} return lale_object(**all_hyperparams) elif isinstance(lale_object, BasePipeline): steps = lale_object.steps() if len(hyperparams) != len(steps): raise ValueError( 'The number of steps in the hyper-parameter space does not match the number of steps in the pipeline.' ) op_instances = [] edges = lale_object.edges() #op_map:Dict[PlannedOpType, TrainableOperator] = {} op_map = {} for op_index, sub_params in enumerate(hyperparams): sub_op = steps[op_index] op_instance = create_instance_from_hyperopt_search_space( sub_op, sub_params) assert isinstance(sub_op, OperatorChoice) or sub_op.class_name( ) == op_instance.class_name( ), f'sub_op {sub_op.class_name()}, op_instance {op_instance.class_name()}' op_instances.append(op_instance) op_map[sub_op] = op_instance #trainable_edges:List[Tuple[TrainableOperator, TrainableOperator]] try: trainable_edges = [(op_map[x], op_map[y]) for (x, y) in edges] except KeyError as e: raise ValueError( "An edge was found with an endpoint that is not a step (" + str(e) + ")") return TrainablePipeline(op_instances, trainable_edges, ordered=True) elif isinstance(lale_object, OperatorChoice): #Hyperopt search space for an OperatorChoice is generated as a dictionary with a single element #corresponding to the choice made, the only key is the index of the step and the value is #the params corresponding to that step. step_index: int choices = lale_object.steps() if len(choices) == 1: step_index = '0' else: step_index, hyperparams = list(hyperparams.items())[0] step_object = choices[int(step_index)] return create_instance_from_hyperopt_search_space( step_object, hyperparams)
def get_operation(self, pipeline: TrainablePipeline) -> _Operation: if self.step_id == _DUMMY_INPUT_STEP: return _Operation.SCAN step = pipeline.steps_list()[self.step_id] return _Operation.TRANSFORM if step.is_transformer( ) else _Operation.PREDICT