def _build_decision_matrix(self, context, ensemble_name, information, pattern_kind): """ Assign the values of the classifiers to the ensemble matrix decision :param context: :param ensemble_name: :param information: """ outputs_kind = context["classifiers"][ensemble_name]["outputs_kind"] classes_array = context["classifiers"][ensemble_name]["classes_names"] if context["classifiers"][ensemble_name]["combination_rule"] == "WMV": self._obtain_weights(context, ensemble_name, information) combination_rule = nested_dict_access(["classifiers", ensemble_name, "combination_rule"], context) if combination_rule in ("SMV", "WMV"): # Forcing the threshold to 0.5, calculate the mean, then apply the threshold context["classifiers"][ensemble_name]["thresholds"]["value"] = \ [0.5] * len(context["classifiers"][ensemble_name]["classes_names"]) instances_number = len(context["patterns"].patterns[ensemble_name][pattern_kind]) for class_pos, class_text in enumerate(classes_array): classifier_list = [classifier for classifier in context["classifiers"][ensemble_name]["classifiers"] if class_text in context["classifiers"][classifier]["classes_names"]] for i in range(instances_number): for j, classifier_name in enumerate(classifier_list): self.info[ensemble_name]["decision_matrix"][pattern_kind][class_text][i, j] = \ information.info[classifier_name][outputs_kind][pattern_kind][i][class_pos]
def _build_decision_matrix(self, context, ensemble_name, information, pattern_kind): """ Assign the values of the classifiers to the ensemble matrix decision :param context: :param ensemble_name: :param information: """ outputs_kind = context["classifiers"][ensemble_name]["outputs_kind"] classes_array = context["classifiers"][ensemble_name]["classes_names"] if context["classifiers"][ensemble_name]["combination_rule"] == "WMV": self._obtain_weights(context, ensemble_name, information) combination_rule = nested_dict_access( ["classifiers", ensemble_name, "combination_rule"], context) if combination_rule in ("SMV", "WMV"): # Forcing the threshold to 0.5, calculate the mean, then apply the threshold context["classifiers"][ensemble_name]["thresholds"]["value"] = \ [0.5] * len(context["classifiers"][ensemble_name]["classes_names"]) instances_number = len( context["patterns"].patterns[ensemble_name][pattern_kind]) for class_pos, class_text in enumerate(classes_array): classifier_list = [ classifier for classifier in context["classifiers"] [ensemble_name]["classifiers"] if class_text in context["classifiers"][classifier]["classes_names"] ] for i in range(instances_number): for j, classifier_name in enumerate(classifier_list): self.info[ensemble_name]["decision_matrix"][pattern_kind][class_text][i, j] = \ information.info[classifier_name][outputs_kind][pattern_kind][i][class_pos]
def __init__(self, context, ensemble_name, information, pattern_kind_list): """ Complete the Information class with the ensembles decisions Self.info as a AutoVivification class might contain only ensemble internal information Build real and discretized outputs of the Ensemble, depending of the Ensemble kind. """ self.info = AutoVivification() self.weights = None self.determine_ensemble_threshold(context, ensemble_name) for pattern_kind in pattern_kind_list: self._init_decision_matrix(context, ensemble_name, pattern_kind) self._build_decision_matrix(context, ensemble_name, information, pattern_kind) if nested_dict_access(["classifiers", ensemble_name, "meta_learner"], context): self.meta_learner(context, ensemble_name, information) else: self._schedule_decisions(context, ensemble_name, information, pattern_kind)
def meta_learner(self, context, ensemble_name, information): """ The meta_learner will be used only in a deployment phase. The learning and validation phases will be developed as a normal classifier. The pattern kind will be always test. The meta learner has to be initialized with all the classifiers at the beginning. It is supposed to be learned before taking this point. :param context: :param ensemble_name: :return: """ meta_learner_name = context["classifiers"][ensemble_name][ "meta_learner"] amount_classifiers = len( context["classifiers"][ensemble_name]["classifiers"].keys()) len_classes_names = len( context["classifiers"][ensemble_name]["classes_names"]) classes_names = context["classifiers"][ensemble_name]["classes_names"] instances_number = 1 pattern_kind = "test" # Create the patterns structure context["patterns"].patterns[meta_learner_name][pattern_kind] = \ np.ndarray(shape=(instances_number, amount_classifiers * len_classes_names), dtype=np.float32, order='C') # Feed the pattern structure with the outputs of the ensemble members for class_index in range(len_classes_names): for instance in range(instances_number): context["patterns"].patterns[meta_learner_name][pattern_kind][instance][class_index] = \ self.info[ensemble_name]["decision_matrix"][pattern_kind][classes_names[class_index]][instance] # Transform the data if corresponds if nested_dict_access( ["classifiers", meta_learner_name, "transformer"], context): len_inputs = len(context["patterns"].patterns[meta_learner_name] [pattern_kind][0]) - len_classes_names context["patterns"].patterns[meta_learner_name][pattern_kind][0][:len_inputs] = \ context["classifiers"][meta_learner_name]["transformer"].transform( context["patterns"].patterns[meta_learner_name][pattern_kind][0][:len_inputs]) # The output of the ensembles will be take from information.info structure information.build_real_outputs(context, meta_learner_name, pattern_kind) information.discretize_outputs(context, meta_learner_name, pattern_kind)
def __init__(self, context, ensemble_name, information, pattern_kind_list): """ Complete the Information class with the ensembles decisions Self.info as a AutoVivification class might contain only ensemble internal information Build real and discretized outputs of the Ensemble, depending of the Ensemble kind. """ self.info = AutoVivification() self.weights = None self.determine_ensemble_threshold(context, ensemble_name) for pattern_kind in pattern_kind_list: self._init_decision_matrix(context, ensemble_name, pattern_kind) self._build_decision_matrix(context, ensemble_name, information, pattern_kind) if nested_dict_access( ["classifiers", ensemble_name, "meta_learner"], context): self.meta_learner(context, ensemble_name, information) else: self._schedule_decisions(context, ensemble_name, information, pattern_kind)
def meta_learner(self, context, ensemble_name, information): """ The meta_learner will be used only in a deployment phase. The learning and validation phases will be developed as a normal classifier. The pattern kind will be always test. The meta learner has to be initialized with all the classifiers at the beginning. It is supposed to be learned before taking this point. :param context: :param ensemble_name: :return: """ meta_learner_name = context["classifiers"][ensemble_name]["meta_learner"] amount_classifiers = len(context["classifiers"][ensemble_name]["classifiers"].keys()) len_classes_names = len(context["classifiers"][ensemble_name]["classes_names"]) classes_names = context["classifiers"][ensemble_name]["classes_names"] instances_number = 1 pattern_kind = "test" # Create the patterns structure context["patterns"].patterns[meta_learner_name][pattern_kind] = \ np.ndarray(shape=(instances_number, amount_classifiers * len_classes_names), dtype=np.float32, order='C') # Feed the pattern structure with the outputs of the ensemble members for class_index in range(len_classes_names): for instance in range(instances_number): context["patterns"].patterns[meta_learner_name][pattern_kind][instance][class_index] = \ self.info[ensemble_name]["decision_matrix"][pattern_kind][classes_names[class_index]][instance] # Transform the data if corresponds if nested_dict_access(["classifiers", meta_learner_name, "transformer"], context): len_inputs = len(context["patterns"].patterns[meta_learner_name][pattern_kind][0]) - len_classes_names context["patterns"].patterns[meta_learner_name][pattern_kind][0][:len_inputs] = \ context["classifiers"][meta_learner_name]["transformer"].transform( context["patterns"].patterns[meta_learner_name][pattern_kind][0][:len_inputs]) # The output of the ensembles will be take from information.info structure information.build_real_outputs(context, meta_learner_name, pattern_kind) information.discretize_outputs(context, meta_learner_name, pattern_kind)