diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..bbedb4b --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,25 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python Debugger: Current File", + "type": "debugpy", + "request": "launch", + "program": "${file}", + "console": "integratedTerminal", + "justMyCode": false + }, + // With profiling + { + "name": "Python: Profile", + "type": "debugpy", + "request": "launch", + "module": "cProfile", + "console": "integratedTerminal", + "args": ["-o", "tmp.prof", "${file}"], + } + ] +} \ No newline at end of file diff --git a/Demos/demos_module/iris_demo.py b/Demos/demos_module/iris_demo.py index b17e827..36ab07a 100644 --- a/Demos/demos_module/iris_demo.py +++ b/Demos/demos_module/iris_demo.py @@ -48,13 +48,16 @@ nRules = 15 nAnts = 4 vl = 3 -tolerance = 0.01 -fz_type_studied = fs.FUZZY_SETS.t2 +tolerance = 0.1 +fz_type_studied = fs.FUZZY_SETS.gt2 # Import some data to play with iris = datasets.load_iris() X = pd.DataFrame(iris.data, columns=iris.feature_names) y = iris.target +# Convert the numeric targets to class names +# y = [iris.target_names[i] for i in y] +class_names = list(iris.target_names) # Compute the fuzzy partitions using 3 quartiles precomputed_partitions = utils.construct_partitions(X, fz_type_studied) @@ -63,11 +66,11 @@ X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0) # We create a FRBC with the precomputed partitions and the specified fuzzy set type, -fl_classifier = GA.BaseFuzzyRulesClassifier(nRules=nRules, linguistic_variables=precomputed_partitions, nAnts=nAnts, - n_linguist_variables=vl, fuzzy_type=fz_type_studied, verbose=False, tolerance=tolerance, runner=runner) -# fl_classifier.customized_loss(utils.mcc_loss) +fl_classifier = GA.BaseFuzzyRulesClassifier(nRules=nRules, linguistic_variables=precomputed_partitions, nAnts=nAnts, class_names=class_names, + n_linguist_variables=vl, fuzzy_type=fz_type_studied, verbose=True, tolerance=tolerance, runner=runner) +fl_classifier.customized_loss(utils.mcc_loss) fl_classifier.fit(X_train, y_train, n_gen=n_gen, pop_size=n_pop, checkpoints=0, random_state=0) -print(vis_rules.rules_to_latex(fl_classifier.rule_base)) +# print(vis_rules.rules_to_latex(fl_classifier.rule_base)) str_rules = eval_tools.eval_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test, plot_rules=True, print_rules=True, plot_partitions=True, return_rules=True) diff --git a/ex_fuzzy/ex_fuzzy/rules.py b/ex_fuzzy/ex_fuzzy/rules.py index 404f504..c0ea1dd 100644 --- a/ex_fuzzy/ex_fuzzy/rules.py +++ b/ex_fuzzy/ex_fuzzy/rules.py @@ -341,6 +341,9 @@ def compute_rule_antecedent_memberships(self, x: np.array, scaled=False, anteced membership = np.zeros((x.shape[0], len(rule_antecedents))) elif self.fuzzy_type() == fs.FUZZY_SETS.t2: membership = np.zeros((x.shape[0], len(rule_antecedents), 2)) + elif self.fuzzy_type() == fs.FUZZY_SETS.gt2: + membership = np.zeros( + (x.shape[0], len(rule_antecedents), len(self.alpha_cuts), 2)) for ix, vl in enumerate(rule_antecedents): @@ -737,23 +740,26 @@ def fuzzy_type(self) -> fs.FUZZY_SETS: return fs.FUZZY_SETS.gt2 - def compute_rule_antecedent_memberships(self, x: np.array, scaled=True) -> np.array: + def compute_rule_antecedent_memberships(self, x: np.array, scaled=True, antecedents_memberships=None) -> np.array: ''' Computes the membership for the antecedents performing the alpha_cut reduction. :param x: array with the values of the inputs. :param scaled: if True, the memberships are scaled to sum 1 in each sample. + :param antecedents_memberships: precomputed antecedent memberships. Not supported for GT2. + :return: array with the memberships of the antecedents for each sample. ''' antecedent_membership = super().compute_rule_antecedent_memberships(x, scaled) return self._alpha_reduction(antecedent_membership) - def alpha_compute_rule_antecedent_memberships(self, x: np.array, scaled=True) -> np.array: + def alpha_compute_rule_antecedent_memberships(self, x: np.array, scaled=True, antecedents_memberships=None) -> np.array: ''' Computes the membership for the antecedents for all the alpha cuts. :param x: array with the values of the inputs. :param scaled: if True, the memberships are scaled to sum 1 in each sample. + :param antecedents_memberships: precomputed antecedent memberships. Not supported for GT2. :return: array with the memberships of the antecedents for each sample. ''' return super().compute_rule_antecedent_memberships(x, scaled)