diff --git a/.gitignore b/.gitignore index 264d282..2f3c148 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ tmp.prof iris_partitions.txt .vscode/settings.json *.gz +test_data_set.csv diff --git a/Demos/demos_module/iris_demo.py b/Demos/demos_module/iris_demo.py index da21225..769f870 100644 --- a/Demos/demos_module/iris_demo.py +++ b/Demos/demos_module/iris_demo.py @@ -21,7 +21,6 @@ import sys -import ex_fuzzy.fuzzy_sets as fs diff --git a/docs/build/doctrees/api.doctree b/docs/build/doctrees/api.doctree index c49ac03..c56fd1f 100644 Binary files a/docs/build/doctrees/api.doctree and b/docs/build/doctrees/api.doctree differ diff --git a/docs/build/doctrees/classifiers.doctree b/docs/build/doctrees/classifiers.doctree index 9df2d85..c6ebc3d 100644 Binary files a/docs/build/doctrees/classifiers.doctree and b/docs/build/doctrees/classifiers.doctree differ diff --git a/docs/build/doctrees/environment.pickle b/docs/build/doctrees/environment.pickle index 3e870b5..d489037 100644 Binary files a/docs/build/doctrees/environment.pickle and b/docs/build/doctrees/environment.pickle differ diff --git a/docs/build/doctrees/extending.doctree b/docs/build/doctrees/extending.doctree index c3353c1..7599337 100644 Binary files a/docs/build/doctrees/extending.doctree and b/docs/build/doctrees/extending.doctree differ diff --git a/docs/build/doctrees/function_resume/centroid.doctree b/docs/build/doctrees/function_resume/centroid.doctree index b08a680..3e37d09 100644 Binary files a/docs/build/doctrees/function_resume/centroid.doctree and b/docs/build/doctrees/function_resume/centroid.doctree differ diff --git a/docs/build/doctrees/function_resume/classifiers.doctree b/docs/build/doctrees/function_resume/classifiers.doctree index 81fc3e1..f58641a 100644 Binary files a/docs/build/doctrees/function_resume/classifiers.doctree and b/docs/build/doctrees/function_resume/classifiers.doctree differ diff --git a/docs/build/doctrees/function_resume/cognitive_maps.doctree b/docs/build/doctrees/function_resume/cognitive_maps.doctree index 913bb9c..df2f6dd 100644 Binary files a/docs/build/doctrees/function_resume/cognitive_maps.doctree and b/docs/build/doctrees/function_resume/cognitive_maps.doctree differ diff --git a/docs/build/doctrees/function_resume/eval_rules.doctree b/docs/build/doctrees/function_resume/eval_rules.doctree index cf5a80a..b074a3e 100644 Binary files a/docs/build/doctrees/function_resume/eval_rules.doctree and b/docs/build/doctrees/function_resume/eval_rules.doctree differ diff --git a/docs/build/doctrees/function_resume/eval_tools.doctree b/docs/build/doctrees/function_resume/eval_tools.doctree index bc3b3b0..e40a622 100644 Binary files a/docs/build/doctrees/function_resume/eval_tools.doctree and b/docs/build/doctrees/function_resume/eval_tools.doctree differ diff --git a/docs/build/doctrees/function_resume/evolutionary_fit.doctree b/docs/build/doctrees/function_resume/evolutionary_fit.doctree index 2c21f54..efd9413 100644 Binary files a/docs/build/doctrees/function_resume/evolutionary_fit.doctree and b/docs/build/doctrees/function_resume/evolutionary_fit.doctree differ diff --git a/docs/build/doctrees/function_resume/fuzzy_sets.doctree b/docs/build/doctrees/function_resume/fuzzy_sets.doctree index 07d5bfa..e3a0aa5 100644 Binary files a/docs/build/doctrees/function_resume/fuzzy_sets.doctree and b/docs/build/doctrees/function_resume/fuzzy_sets.doctree differ diff --git a/docs/build/doctrees/function_resume/pattern_stability.doctree b/docs/build/doctrees/function_resume/pattern_stability.doctree index bd816d2..0af7e4b 100644 Binary files a/docs/build/doctrees/function_resume/pattern_stability.doctree and b/docs/build/doctrees/function_resume/pattern_stability.doctree differ diff --git a/docs/build/doctrees/function_resume/persistence.doctree b/docs/build/doctrees/function_resume/persistence.doctree index a04a2da..d4ef6c3 100644 Binary files a/docs/build/doctrees/function_resume/persistence.doctree and b/docs/build/doctrees/function_resume/persistence.doctree differ diff --git a/docs/build/doctrees/function_resume/rule_mining.doctree b/docs/build/doctrees/function_resume/rule_mining.doctree index a4fcb0b..d390b48 100644 Binary files a/docs/build/doctrees/function_resume/rule_mining.doctree and b/docs/build/doctrees/function_resume/rule_mining.doctree differ diff --git a/docs/build/doctrees/function_resume/rules.doctree b/docs/build/doctrees/function_resume/rules.doctree index 011a44b..6bd0f1b 100644 Binary files a/docs/build/doctrees/function_resume/rules.doctree and b/docs/build/doctrees/function_resume/rules.doctree differ diff --git a/docs/build/doctrees/function_resume/temporal.doctree b/docs/build/doctrees/function_resume/temporal.doctree index 284142c..a53898d 100644 Binary files a/docs/build/doctrees/function_resume/temporal.doctree and b/docs/build/doctrees/function_resume/temporal.doctree differ diff --git a/docs/build/doctrees/function_resume/utils.doctree b/docs/build/doctrees/function_resume/utils.doctree index 2c7b910..752fa53 100644 Binary files a/docs/build/doctrees/function_resume/utils.doctree and b/docs/build/doctrees/function_resume/utils.doctree differ diff --git a/docs/build/doctrees/function_resume/vis_rules.doctree b/docs/build/doctrees/function_resume/vis_rules.doctree index ea008f3..76d41e4 100644 Binary files a/docs/build/doctrees/function_resume/vis_rules.doctree and b/docs/build/doctrees/function_resume/vis_rules.doctree differ diff --git a/docs/build/doctrees/gt2.doctree b/docs/build/doctrees/gt2.doctree index dc8de51..2d0a70a 100644 Binary files a/docs/build/doctrees/gt2.doctree and b/docs/build/doctrees/gt2.doctree differ diff --git a/docs/build/doctrees/index.doctree b/docs/build/doctrees/index.doctree index 43e690a..58a3617 100644 Binary files a/docs/build/doctrees/index.doctree and b/docs/build/doctrees/index.doctree differ diff --git a/docs/build/doctrees/optimize.doctree b/docs/build/doctrees/optimize.doctree index 21fc398..03cbf2a 100644 Binary files a/docs/build/doctrees/optimize.doctree and b/docs/build/doctrees/optimize.doctree differ diff --git a/docs/build/doctrees/pattern_stats.doctree b/docs/build/doctrees/pattern_stats.doctree index 51e9214..4593773 100644 Binary files a/docs/build/doctrees/pattern_stats.doctree and b/docs/build/doctrees/pattern_stats.doctree differ diff --git a/docs/build/doctrees/persistence.doctree b/docs/build/doctrees/persistence.doctree index 294a920..acc75ba 100644 Binary files a/docs/build/doctrees/persistence.doctree and b/docs/build/doctrees/persistence.doctree differ diff --git a/docs/build/doctrees/precom.doctree b/docs/build/doctrees/precom.doctree index f023319..a4e8981 100644 Binary files a/docs/build/doctrees/precom.doctree and b/docs/build/doctrees/precom.doctree differ diff --git a/docs/build/doctrees/step1.doctree b/docs/build/doctrees/step1.doctree index 014acf2..3a93437 100644 Binary files a/docs/build/doctrees/step1.doctree and b/docs/build/doctrees/step1.doctree differ diff --git a/docs/build/doctrees/step2.doctree b/docs/build/doctrees/step2.doctree index a37deda..8819bea 100644 Binary files a/docs/build/doctrees/step2.doctree and b/docs/build/doctrees/step2.doctree differ diff --git a/docs/build/doctrees/step3.doctree b/docs/build/doctrees/step3.doctree index 64f0cee..2028dbd 100644 Binary files a/docs/build/doctrees/step3.doctree and b/docs/build/doctrees/step3.doctree differ diff --git a/docs/build/doctrees/step4.doctree b/docs/build/doctrees/step4.doctree index 39c7046..c4f95a0 100644 Binary files a/docs/build/doctrees/step4.doctree and b/docs/build/doctrees/step4.doctree differ diff --git a/docs/build/doctrees/tmpfs.doctree b/docs/build/doctrees/tmpfs.doctree index 2bf159a..1ecf24a 100644 Binary files a/docs/build/doctrees/tmpfs.doctree and b/docs/build/doctrees/tmpfs.doctree differ diff --git a/docs/build/doctrees/usage.doctree b/docs/build/doctrees/usage.doctree index 140264e..0e72232 100644 Binary files a/docs/build/doctrees/usage.doctree and b/docs/build/doctrees/usage.doctree differ diff --git a/docs/build/html/.buildinfo b/docs/build/html/.buildinfo index 1ea0ddd..b99a06f 100644 --- a/docs/build/html/.buildinfo +++ b/docs/build/html/.buildinfo @@ -1,4 +1,4 @@ # Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: 7184ad333879fb5e4f199b3de50a2caf +config: bbbf35d0940a0dcfa2922ad1d1125950 tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/build/html/_modules/ex_fuzzy/eval_rules.html b/docs/build/html/_modules/ex_fuzzy/eval_rules.html index e6af77d..6fb188a 100644 --- a/docs/build/html/_modules/ex_fuzzy/eval_rules.html +++ b/docs/build/html/_modules/ex_fuzzy/eval_rules.html @@ -1,22 +1,20 @@ + + - +
try:
from . import rules
from . import fuzzy_sets as fs
+ from . import permutation_test as bt
except ImportError:
import rules
import fuzzy_sets as fs
+ import permutation_test as bt
-[docs]class evalRuleBase():
+
+[docs]
+class evalRuleBase():
'''
Class to evaluate a set of rules given a evaluation dataset.
'''
@@ -127,7 +129,9 @@ Source code for ex_fuzzy.eval_rules
-[docs] def compute_pattern_support(self) -> np.array:
+
+[docs]
+ def compute_pattern_support(self) -> np.array:
'''
Computes the pattern support for each of the rules for the given X.
Each pattern support firing strength is the result of the tnorm for all the antecedent memeberships,
@@ -162,7 +166,10 @@ Source code for ex_fuzzy.eval_rules
return res
-[docs] def compute_aux_pattern_support(self) -> np.array:
+
+
+[docs]
+ def compute_aux_pattern_support(self) -> np.array:
'''
Computes the pattern support for each of the rules for each of the classes for the given X.
Each pattern support firing strength is the result of the tnorm for all the antecedent memeberships,
@@ -201,6 +208,7 @@ Source code for ex_fuzzy.eval_rules
return res
+
def _get_all_rules(self) -> list[rules.RuleSimple]:
'''
Returns a list of all the rules in the master rule base.
@@ -214,7 +222,9 @@ Source code for ex_fuzzy.eval_rules
return res
-[docs] def compute_pattern_confidence(self) -> np.array:
+
+[docs]
+ def compute_pattern_confidence(self) -> np.array:
'''
Computes the pattern confidence for each of the rules for the given X.
Each pattern confidence is the normalized firing strength.
@@ -250,7 +260,10 @@ Source code for ex_fuzzy.eval_rules
return res
-[docs] def compute_aux_pattern_confidence(self) -> np.array:
+
+
+[docs]
+ def compute_aux_pattern_confidence(self) -> np.array:
'''
Computes the pattern confidence for each of the rules for the given X.
Each pattern confidence is the normalized firing strength.
@@ -287,7 +300,10 @@ Source code for ex_fuzzy.eval_rules
return res
-[docs] def dominance_scores(self) -> np.array:
+
+
+[docs]
+ def dominance_scores(self) -> np.array:
'''
Returns the dominance score of each pattern for each rule.
@@ -296,7 +312,10 @@ Source code for ex_fuzzy.eval_rules
return self.compute_pattern_confidence() * self.compute_pattern_support()
-[docs] def association_degree(self) -> np.array:
+
+
+[docs]
+ def association_degree(self) -> np.array:
'''
Returns the association degree of each rule for each sample.
@@ -311,7 +330,10 @@ Source code for ex_fuzzy.eval_rules
return res
-[docs] def aux_dominance_scores(self) -> np.array:
+
+
+[docs]
+ def aux_dominance_scores(self) -> np.array:
'''
Returns the dominance score of each pattern for each rule.
@@ -320,7 +342,10 @@ Source code for ex_fuzzy.eval_rules
return self.compute_aux_pattern_confidence() * self.compute_aux_pattern_support()
-[docs] def add_rule_weights(self) -> None:
+
+
+[docs]
+ def add_rule_weights(self) -> None:
'''
Add dominance score field to each of the rules present in the master Rule Base.
'''
@@ -336,9 +361,12 @@ Source code for ex_fuzzy.eval_rules
rules[jx].confidence = confidences[aux_counter]
aux_counter += 1
+
-[docs] def add_auxiliary_rule_weights(self) -> None:
+
+[docs]
+ def add_auxiliary_rule_weights(self) -> None:
'''
Add dominance score field to each of the rules present in the master Rule Base for each consequent.
They are labeled as aux_score, aux_support and aux_confidence. (Because they are not the main rule weights)
@@ -357,7 +385,10 @@ Source code for ex_fuzzy.eval_rules
aux_counter += 1
-[docs] def add_classification_metrics(self, X: np.array=None, y: np.array=None) -> None:
+
+
+[docs]
+ def add_classification_metrics(self, X: np.array=None, y: np.array=None) -> None:
'''
Adds the accuracy of each rule in the master rule base. It also adds the f1, precision and recall scores.
If X and y are None uses the train set.
@@ -403,9 +434,12 @@ Source code for ex_fuzzy.eval_rules
rules[jx].accuracy = accuracy_score(relevant_labels, relevant_preds)
else:
rules[jx].accuracy = 0.0
+
-[docs] def classification_eval(self) -> float:
+
+[docs]
+ def classification_eval(self) -> float:
'''
Returns the matthews correlation coefficient for a classification task using
the rules evaluated.
@@ -416,10 +450,16 @@ Source code for ex_fuzzy.eval_rules
self.add_rule_weights()
preds = self.mrule_base.winning_rule_predict(self.X, precomputed_truth=self.precomputed_truth)
- return matthews_corrcoef(self.y, preds)
+ self.mcc = matthews_corrcoef(self.y, preds)
+ self.acc = accuracy_score(self.y, preds)
+
+ return self.mcc
-[docs] def size_antecedents_eval(self, tolerance=0.1) -> float:
+
+
+[docs]
+ def size_antecedents_eval(self, tolerance=0.1) -> float:
'''
Returns a score between 0 and 1, where 1 means that the rule base only contains almost no antecedents.
@@ -454,9 +494,12 @@ Source code for ex_fuzzy.eval_rules
rule_density = 0.0
return rule_density
+
-[docs] def effective_rulesize_eval(self, tolerance=0.1) -> float:
+
+[docs]
+ def effective_rulesize_eval(self, tolerance=0.1) -> float:
'''
Returns a score between 0 and 1, where 1 means that the rule base only contains almost no antecedents.
@@ -489,12 +532,51 @@ Source code for ex_fuzzy.eval_rules
return rule_density
-[docs] def add_full_evaluation(self):
+
+
+[docs]
+ def p_permutation_classifier_validation(self, n=100, r=10) -> float:
+ '''
+ Performs a boostrap test to evaluate the performance of the rule base.
+ Returns the p-valuefor the label permutation test and the feature coalition test.
+
+ :param n: int. Number of boostrap samples.
+ :param r: int. Number of repetitions to estimate the original error rate.
+ :return: p-value of the permutation test.
+ '''
+ test1 = bt.permutation_labels_test(self.mrule_base, self.X, self.y, k=n, r=r)
+ test2 = bt.permute_columns_class_test(self.mrule_base, self.X, self.y, k=n, r=r)
+
+ bt.rulewise_label_permutation_test(self.mrule_base, self.X, self.y, k=n, r=r)
+ bt.rulewise_column_permutation_test(self.mrule_base, self.X, self.y, k=n, r=r)
+
+ self.mrule_base.p_value_class_structure = test1
+ self.mrule_base.p_value_feature_coalition = test2
+
+ return test1, test2
+
+
+
+ def p_bootstrapping_rules_validation(self, n=100) -> float:
+ import ex_fuzzy.bootstrapping_test as bt
+ rules_p_values = bt.compute_rule_p_value(self.mrule_base, self.X, self.y, n).flatten()
+
+ for jx, rule in enumerate(self.mrule_base.get_rules()):
+ rule.boot_p_value = rules_p_values[jx]
+
+
+
+[docs]
+ def add_full_evaluation(self):
'''
Adds classification scores, both Dominance Scores and accuracy metrics, for each individual rule.
'''
self.add_rule_weights()
- self.add_classification_metrics()
+ self.add_classification_metrics()
+ self.classification_eval()
+
+
+
diff --git a/docs/build/html/_modules/ex_fuzzy/eval_tools.html b/docs/build/html/_modules/ex_fuzzy/eval_tools.html
index c58d281..809af04 100644
--- a/docs/build/html/_modules/ex_fuzzy/eval_tools.html
+++ b/docs/build/html/_modules/ex_fuzzy/eval_tools.html
@@ -1,22 +1,20 @@
+
+
-
+
ex_fuzzy.eval_tools — Ex-Fuzzy documentation
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
@@ -89,7 +87,7 @@ Source code for ex_fuzzy.eval_tools
"""
import numpy as np
import pandas as pd
-from sklearn.metrics import matthews_corrcoef
+import sklearn.metrics as metrics
try:
from . import evolutionary_fit as evf
@@ -97,68 +95,118 @@ Source code for ex_fuzzy.eval_tools
except ImportError:
import evolutionary_fit as evf
import vis_rules
-
-
-[docs]def eval_fuzzy_model(fl_classifier: evf.BaseFuzzyRulesClassifier, X_train: np.array, y_train: np.array,
- X_test: np.array, y_test: np.array, plot_rules=True, print_rules=True, plot_partitions=True,
- return_rules=False, print_accuracy=True, print_matthew=True, export_path:str=None) -> None:
+
+
+
+[docs]
+class FuzzyEvaluator():
'''
- Function that evaluates a fuzzy rule based model. It also plots the rules and the fuzzy partitions.
-
- :param fl_classifier: Fuzzy rule based model.
- :param X_train: Training data.
- :param y_train: Training labels.
- :param X_test: Test data.
- :param y_test: Test labels.
- :param plot_rules: If True, it plots the rules.
- :param print_rules: If True, it prints the rules.
- :param plot_partitions: If True, it plots the fuzzy partitions.
- :return: None
+ Takes a model and associated data and permits rule evaluation
'''
- # Get the unique classes from the classifier
- unique_classes = fl_classifier.classes_names
+ def __init__(self,fl_classifier: evf.BaseFuzzyRulesClassifier):
+ '''
+ :param fl_classifier: Fuzzy rule based model
+ '''
+ self.fl_classifier = fl_classifier
+
- # Convert the names from the labels to the corresponding class if necessary
- if isinstance(y_train[0], str):
- y_train = np.array([list(unique_classes).index(str(y)) for y in y_train])
- y_test = np.array([list(unique_classes).index(str(y)) for y in y_test])
-
- if print_accuracy:
- print('------------')
- print('ACCURACY')
- print('Train performance: ' +
- str(np.mean(np.equal(y_train, fl_classifier.predict(X_train, out_class_names=isinstance(y_train[0], str))))))
- print('Test performance: ' +
- str(np.mean(np.equal(y_test, fl_classifier.predict(X_test, out_class_names=isinstance(y_train[0], str))))))
- print('------------')
- if print_matthew:
- print('MATTHEW CORRCOEF')
- print('Train performance: ' +
- str(matthews_corrcoef(y_train, fl_classifier.predict(X_train, out_class_names=isinstance(y_train[0], str))))
- )
- print('Test performance: ' +
- str(matthews_corrcoef(y_test, fl_classifier.predict(X_test, out_class_names=isinstance(y_train[0], str))))
- )
- print('------------')
-
-
- if print_rules or return_rules:
- res = fl_classifier.print_rules(True)
-
- if print_rules:
- print(res)
-
- if plot_partitions:
- fl_classifier.plot_fuzzy_variables()
-
- if plot_rules:
- vis_rules.visualize_rulebase(fl_classifier.rule_base, export_path=export_path)
-
- if return_rules:
- return res
-
+ def predict(self,X: np.array) -> np.array:
+ # Predict y for given X for use in metric evaluation
+ return self.fl_classifier.predict(X)
+
+
+[docs]
+ def get_metric(self,metric:str,X_true:np.array,y_true:np.array,**kwargs) -> float:
+ '''
+ :param metric: named metric in string format available in sklearn library for evaluation
+ :param X_true: np.array of X values for prediction
+ :param y_true: np.array of true class outcomes for X values
+ :param **kwargs: additional arguments for different sklearn.metrics functions
+ '''
+ #Get y predictions
+ y_pred = self.predict(X_true)
+ y_true = np.array(y_true)
+ #Convert str classes to numbers in corresponding class if necessary
+ unique_classes = self.fl_classifier.classes_names
+
+ if isinstance(y_true[0],str):
+ y_true = np.array([list[unique_classes].index(str(y)) for y in y_true])
+
+ #Find metrics requested in sklearn library, if not found
+ try:
+ # Get the metric function dynamically from sklearn.metrics
+ metric_function = getattr(metrics, metric)
+ # Call the metric function with y_true, y_pred, and any additional keyword arguments
+ return metric_function(y_true, y_pred, **kwargs)
+ except AttributeError:
+ return f"Metric '{metric}' not found in sklearn.metrics."
+ except TypeError:
+ return f"Invalid arguments passed for the metric '{metric}'."
+
+
+
+
+[docs]
+ def eval_fuzzy_model(self,X_train: np.array, y_train: np.array,X_test: np.array, y_test: np.array,
+ plot_rules=True, print_rules=True, plot_partitions=True,
+ return_rules=False, print_accuracy=True, print_matthew=True, export_path:str=None) -> None:
+ '''
+ Function that evaluates a fuzzy rule based model. It also plots the rules and the fuzzy partitions.
+
+ :param X_train: Training data.
+ :param y_train: Training labels.
+ :param X_test: Test data.
+ :param y_test: Test labels.
+ :param plot_rules: If True, it plots the rules.
+ :param print_rules: If True, it prints the rules.
+ :param plot_partitions: If True, it plots the fuzzy partitions.
+ :return: None
+ '''
+ # Get the unique classes from the classifier
+ unique_classes = self.fl_classifier.classes_names
+
+ # Convert the names from the labels to the corresponding class if necessary
+ if isinstance(y_train[0], str):
+ y_train = np.array([list(unique_classes).index(str(y)) for y in y_train])
+ y_test = np.array([list(unique_classes).index(str(y)) for y in y_test])
+
+ if print_accuracy:
+ print('------------')
+ print('ACCURACY')
+ print('Train performance: ' +
+ str(self.get_metric('accuracy_score',X_train,y_train)))
+ print('Test performance: ' +
+ str(self.get_metric('accuracy_score',X_test,y_test)))
+ print('------------')
+ if print_matthew:
+ print('MATTHEW CORRCOEF')
+ print('Train performance: ' +
+ str(self.get_metric('matthews_corrcoef',X_train,y_train))
+ )
+ print('Test performance: ' +
+ str(self.get_metric('matthews_corrcoef',X_test,y_test))
+ )
+ print('------------')
+
+
+ if print_rules or return_rules:
+ res = self.fl_classifier.print_rules(True)
+
+ if print_rules:
+ print(res)
+
+ if plot_partitions:
+ self.fl_classifier.plot_fuzzy_variables()
+
+ if plot_rules:
+ vis_rules.visualize_rulebase(self.fl_classifier.rule_base, export_path=export_path)
+
+ if return_rules:
+ return res
+
+
diff --git a/docs/build/html/_modules/ex_fuzzy/evolutionary_fit.html b/docs/build/html/_modules/ex_fuzzy/evolutionary_fit.html
index b6aeb8e..03443bd 100644
--- a/docs/build/html/_modules/ex_fuzzy/evolutionary_fit.html
+++ b/docs/build/html/_modules/ex_fuzzy/evolutionary_fit.html
@@ -1,22 +1,20 @@
+
+
-
+
ex_fuzzy.evolutionary_fit — Ex-Fuzzy documentation
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
@@ -118,7 +116,9 @@ Source code for ex_fuzzy.evolutionary_fit
-[docs]class BaseFuzzyRulesClassifier(ClassifierMixin):
+
+[docs]
+class BaseFuzzyRulesClassifier(ClassifierMixin):
'''
Class that is used as a classifier for a fuzzy rule based system. Supports precomputed and optimization of the linguistic variables.
'''
@@ -207,7 +207,9 @@ Source code for ex_fuzzy.evolutionary_fit
self.beta_ = 0.0
-[docs] def customized_loss(self, loss_function):
+
+[docs]
+ def customized_loss(self, loss_function):
'''
Function to customize the loss function used for the optimization.
@@ -217,8 +219,12 @@ Source code for ex_fuzzy.evolutionary_fit
self.custom_loss = loss_function
-[docs] def fit(self, X: np.array, y: np.array, n_gen:int=70, pop_size:int=30,
- checkpoints:int=0, candidate_rules:rules.MasterRuleBase=None, initial_rules:rules.MasterRuleBase=None, random_state:int=33) -> None:
+
+
+[docs]
+ def fit(self, X: np.array, y: np.array, n_gen:int=70, pop_size:int=30,
+ checkpoints:int=0, candidate_rules:rules.MasterRuleBase=None, initial_rules:rules.MasterRuleBase=None, random_state:int=33,
+ var_prob:float=0.3, sbx_eta:float=3.0, mutation_eta=7.0, tournament_size=3, bootstrap_size=1000) -> None:
'''
Fits a fuzzy rule based classifier using a genetic algorithm to the given data.
@@ -228,6 +234,12 @@ Source code for ex_fuzzy.evolutionary_fit
:param pop_size: integer. Population size for each gneration.
:param checkpoints: integer. Number of checkpoints to save the best rulebase found so far.
:param candidate_rules: if these rules exist, the optimization process will choose the best rules from this set. If None (default) the rules will be generated from scratch.
+ :param initial_rules: if these rules exist, the optimization process will start from this set. If None (default) the rules will be generated from scratch.
+ :param random_state: integer. Random seed for the optimization process.
+ :param var_prob: float. Probability of crossover for the genetic algorithm.
+ :param sbx_eta: float. Eta parameter for the SBX crossover.
+ :param mutation_eta: float. Eta parameter for the polynomial mutation.
+ :param tournament_size: integer. Size of the tournament for the genetic algorithm.
:return: None. The classifier is fitted to the data.
'''
if mnt.save_usage_flag:
@@ -287,8 +299,9 @@ Source code for ex_fuzzy.evolutionary_fit
algorithm = GA(
pop_size=pop_size,
- crossover=SBX(prob=.3, eta=3.0),
- mutation=PolynomialMutation(eta=7.0),
+ crossover=SBX(prob=var_prob, eta=sbx_eta),
+ mutation=PolynomialMutation(eta=mutation_eta),
+ tournament_size=tournament_size,
sampling=rules_gene,
eliminate_duplicates=False)
@@ -349,20 +362,27 @@ Source code for ex_fuzzy.evolutionary_fit
self.var_names = [str(ix) for ix in range(X.shape[1])]
self.rule_base = problem._construct_ruleBase(
- best_individual, fz_type=self.fuzzy_type)
- self.rule_base.rename_cons(self.classes_names)
+ best_individual, self.fuzzy_type)
+
self.eval_performance = evr.evalRuleBase(
self.rule_base, np.array(X), y)
-
- self.eval_performance.add_full_evaluation()
+ self.eval_performance.add_full_evaluation()
+ self.rule_base.purge_rules(self.tolerance)
+ self.eval_performance.add_full_evaluation() # After purging the bad rules we update the metrics.
+
+ self.p_value_class_structure, self.p_value_feature_coalitions = self.eval_performance.p_permutation_classifier_validation()
+ self.eval_performance.p_bootstrapping_rules_validation(bootstrap_size)
+ self.rule_base.rename_cons(self.classes_names)
if self.lvs is None:
- self.rename_fuzzy_variables()
+ self.rename_fuzzy_variables()
+
- self.rule_base.purge_rules(self.tolerance)
-[docs] def load_master_rule_base(self, rule_base: rules.MasterRuleBase) -> None:
+
+[docs]
+ def load_master_rule_base(self, rule_base: rules.MasterRuleBase) -> None:
'''
Loads a master rule base to be used in the prediction process.
@@ -373,9 +393,12 @@ Source code for ex_fuzzy.evolutionary_fit
self.nRules = len(rule_base.get_rules())
self.nAnts = len(rule_base.get_rules()[0].antecedents)
self.nclasses_ = len(rule_base)
+
-[docs] def forward(self, X: np.array, out_class_names=False) -> np.array:
+
+[docs]
+ def forward(self, X: np.array, out_class_names=False) -> np.array:
'''
Returns the predicted class for each sample.
@@ -389,9 +412,12 @@ Source code for ex_fuzzy.evolutionary_fit
pass
return self.rule_base.winning_rule_predict(X, out_class_names=out_class_names)
+
-[docs] def predict(self, X: np.array, out_class_names=False) -> np.array:
+
+[docs]
+ def predict(self, X: np.array, out_class_names=False) -> np.array:
'''
Returns the predicted class for each sample.
@@ -400,9 +426,12 @@ Source code for ex_fuzzy.evolutionary_fit
:return: np array samples (x 1) with the predicted class.
'''
return self.forward(X, out_class_names=out_class_names)
+
-[docs] def predict_proba(self, X: np.array) -> np.array:
+
+[docs]
+ def predict_proba(self, X: np.array) -> np.array:
'''
Returns the predicted class probabilities for each sample.
@@ -417,14 +446,20 @@ Source code for ex_fuzzy.evolutionary_fit
return self.rule_base.compute_association_degrees(X)
-[docs] def print_rules(self, return_rules:bool=False) -> None:
+
+
+[docs]
+ def print_rules(self, return_rules:bool=False) -> None:
'''
Print the rules contained in the fitted rulebase.
'''
return self.rule_base.print_rules(return_rules)
-[docs] def plot_fuzzy_variables(self) -> None:
+
+
+[docs]
+ def plot_fuzzy_variables(self) -> None:
'''
Plot the fuzzy partitions in each fuzzy variable.
'''
@@ -434,7 +469,10 @@ Source code for ex_fuzzy.evolutionary_fit
vis_rules.plot_fuzzy_variable(fv)
-[docs] def rename_fuzzy_variables(self) -> None:
+
+
+[docs]
+ def rename_fuzzy_variables(self) -> None:
'''
Renames the linguist labels so that high, low and so on are consistent. It does so usually after an optimization process.
@@ -474,16 +512,22 @@ Source code for ex_fuzzy.evolutionary_fit
fuzzy_sets_vl[x].name = possible_names[jx]
-[docs] def get_rulebase(self) -> list[np.array]:
+
+
+[docs]
+ def get_rulebase(self) -> list[np.array]:
'''
Get the rulebase obtained after fitting the classifier to the data.
:return: a matrix format for the rulebase.
'''
return self.rule_base.get_rulebase_matrix()
+
-[docs] def reparametrice_loss(self, alpha:float, beta:float) -> None:
+
+[docs]
+ def reparametrice_loss(self, alpha:float, beta:float) -> None:
'''
Changes the parameters in the loss function.
@@ -492,11 +536,24 @@ Source code for ex_fuzzy.evolutionary_fit
:param beta: controls the average rule size loss.
'''
self.alpha_ = alpha
- self.beta_ = beta
+ self.beta_ = beta
+
+
+ def __call__(self, X:np.array) -> np.array:
+ '''
+ Returns the predicted class for each sample.
+
+ :param X: np array samples x features.
+ :return: np array samples (x 1) with the predicted class.
+ '''
+ return self.predict(X)
+
-[docs]class ExploreRuleBases(Problem):
+
+[docs]
+class ExploreRuleBases(Problem):
'''
Class to model as pymoo problem the fitting of a rulebase to a set of data given a series of candidate rules for a classification problem using Evolutionary strategies
Supports type 1 and t2.
@@ -624,7 +681,9 @@ Source code for ex_fuzzy.evolutionary_fit
out["F"] = 1
-[docs] def fitness_func(self, ruleBase: rules.RuleBase, X:np.array, y:np.array, tolerance:float, alpha:float=0.0, beta:float=0.0, precomputed_truth=None) -> float:
+
+[docs]
+ def fitness_func(self, ruleBase: rules.RuleBase, X:np.array, y:np.array, tolerance:float, alpha:float=0.0, beta:float=0.0, precomputed_truth=None) -> float:
'''
Fitness function for the optimization problem.
:param ruleBase: RuleBase object
@@ -642,11 +701,15 @@ Source code for ex_fuzzy.evolutionary_fit
score = score_acc + score_rules_size * alpha + score_nrules * beta
- return score
+ return score
+
+
-[docs]class FitRuleBase(Problem):
+
+[docs]
+class FitRuleBase(Problem):
'''
Class to model as pymoo problem the fitting of a rulebase for a classification problem using Evolutionary strategies.
Supports type 1 and iv fs (iv-type 2)
@@ -850,7 +913,9 @@ Source code for ex_fuzzy.evolutionary_fit
xu=varbound[:, 1])
-[docs] def encode_rulebase(self, rule_base: rules.MasterRuleBase, optimize_lv: bool, encode_mods:bool=False) -> np.array:
+
+[docs]
+ def encode_rulebase(self, rule_base: rules.MasterRuleBase, optimize_lv: bool, encode_mods:bool=False) -> np.array:
'''
Given a rule base, constructs the corresponding gene associated with that rule base.
@@ -869,10 +934,10 @@ Source code for ex_fuzzy.evolutionary_fit
gene = np.zeros((self.single_gen_size,))
n_lv_possible = len(rule_base.rule_bases[0].antecedents[0].linguistic_variables)
- fz_type = rule_base.fuzzy_type()
+ fuzzy_type = rule_base.fuzzy_type()
rule_consequents = rule_base.get_consequents()
nreal_rules = len(rule_consequents)
- mf_size = 4 if fz_type == fs.FUZZY_SETS.t1 else 8
+ mf_size = 4 if fuzzy_type == fs.FUZZY_SETS.t1 else 8
# Pointer to the fourth section of the gene: consequents
if optimize_lv:
@@ -939,15 +1004,16 @@ Source code for ex_fuzzy.evolutionary_fit
aux_pointer += 1
return np.array(list(map(int, gene)))
+
- def _construct_ruleBase(self, x: np.array, fz_type: fs.FUZZY_SETS, **kwargs) -> rules.MasterRuleBase:
+ def _construct_ruleBase(self, x: np.array, fuzzy_type: fs.FUZZY_SETS, **kwargs) -> rules.MasterRuleBase:
'''
Given a subject, it creates a rulebase according to its specification.
:param x: gen of a rulebase. type: dict.
- :param fz_type: a enum type. Check fuzzy_sets for complete specification (two fields, t1 and t2, to mark which fs you want to use)
+ :param fuzzy_type: a enum type. Check fuzzy_sets for complete specification (two fields, t1 and t2, to mark which fs you want to use)
:param kwargs: additional parameters to pass to the rule
:return: a rulebase object.
@@ -958,7 +1024,7 @@ Source code for ex_fuzzy.evolutionary_fit
rule_list = [[] for _ in range(self.n_classes)]
- mf_size = 4 if fz_type == fs.FUZZY_SETS.t1 else 8
+ mf_size = 4 if fuzzy_type == fs.FUZZY_SETS.t1 else 8
'''
GEN STRUCTURE
@@ -1061,7 +1127,7 @@ Source code for ex_fuzzy.evolutionary_fit
fz_parameters = self.antecedents_referencial[fuzzy_variable][fz_parameters_idx]
aux_pointer += mf_size
- if fz_type == fs.FUZZY_SETS.t2:
+ if fuzzy_type == fs.FUZZY_SETS.t2:
fz_parameters[0:6] = np.sort(fz_parameters[0:6])
mu = [np.min(fz_parameters[0:2]), fz_parameters[2],
fz_parameters[3], np.max(fz_parameters[4:6])]
@@ -1086,14 +1152,14 @@ Source code for ex_fuzzy.evolutionary_fit
for i in range(self.n_classes):
- if fz_type == fs.FUZZY_SETS.temporal:
- fz_type = self.lvs[0][0].inside_type()
+ if fuzzy_type == fs.FUZZY_SETS.temporal:
+ fuzzy_type = self.lvs[0][0].inside_type()
- if fz_type == fs.FUZZY_SETS.t1:
+ if fuzzy_type == fs.FUZZY_SETS.t1:
rule_base = rules.RuleBaseT1(antecedents, rule_list[i])
- elif fz_type == fs.FUZZY_SETS.t2:
+ elif fuzzy_type == fs.FUZZY_SETS.t2:
rule_base = rules.RuleBaseT2(antecedents, rule_list[i])
- elif fz_type == fs.FUZZY_SETS.gt2:
+ elif fuzzy_type == fs.FUZZY_SETS.gt2:
rule_base = rules.RuleBaseGT2(antecedents, rule_list[i])
@@ -1124,7 +1190,9 @@ Source code for ex_fuzzy.evolutionary_fit
out["F"] = 1 - score
-[docs] def fitness_func(self, ruleBase: rules.RuleBase, X:np.array, y:np.array, tolerance:float, alpha:float=0.0, beta:float=0.0, precomputed_truth:np.array=None) -> float:
+
+[docs]
+ def fitness_func(self, ruleBase: rules.RuleBase, X:np.array, y:np.array, tolerance:float, alpha:float=0.0, beta:float=0.0, precomputed_truth:np.array=None) -> float:
'''
Fitness function for the optimization problem.
:param ruleBase: RuleBase object
@@ -1152,7 +1220,9 @@ Source code for ex_fuzzy.evolutionary_fit
else:
score = 0.0
- return score
+ return score
+
+
diff --git a/docs/build/html/_modules/ex_fuzzy/fuzzy_sets.html b/docs/build/html/_modules/ex_fuzzy/fuzzy_sets.html
index 799f97e..89823d9 100644
--- a/docs/build/html/_modules/ex_fuzzy/fuzzy_sets.html
+++ b/docs/build/html/_modules/ex_fuzzy/fuzzy_sets.html
@@ -1,22 +1,20 @@
+
+
-
+
ex_fuzzy.fuzzy_sets — Ex-Fuzzy documentation
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
@@ -118,7 +116,9 @@ Source code for ex_fuzzy.fuzzy_sets
return self.value == __value.value
-[docs]def trapezoidal_membership(x: np.array, params: list[float], epsilon=10E-5) -> np.array:
+
+[docs]
+def trapezoidal_membership(x: np.array, params: list[float], epsilon=10E-5) -> np.array:
'''
Trapezoidal membership functions.
@@ -162,6 +162,7 @@ Source code for ex_fuzzy.fuzzy_sets
+
def __gaussian2(x, params: list[float]) -> np.array:
'''
Gaussian membership functions.
@@ -174,7 +175,9 @@ Source code for ex_fuzzy.fuzzy_sets
return amplitude * np.exp(- ((x - mean) / standard_deviation) ** 2)
-[docs]class FS():
+
+[docs]
+class FS():
'''
Class that defines the most basic fuzzy sets (also known as Type 1 fuzzy sets or Zadeh sets).
'''
@@ -196,7 +199,9 @@ Source code for ex_fuzzy.fuzzy_sets
self.membership_parameters = membership_parameters
-[docs] def membership(self, x: np.array) -> np.array:
+
+[docs]
+ def membership(self, x: np.array) -> np.array:
'''
Computes the membership of a point or a vector.
@@ -205,7 +210,10 @@ Source code for ex_fuzzy.fuzzy_sets
return trapezoidal_membership(x, self.membership_parameters)
-[docs] def type(self) -> FUZZY_SETS:
+
+
+[docs]
+ def type(self) -> FUZZY_SETS:
'''
Returns the corresponding fuzzy set type according to FUZZY_SETS enum.
@@ -214,6 +222,7 @@ Source code for ex_fuzzy.fuzzy_sets
return FUZZY_SETS.t1
+
def __call__(self, x: np.array) -> np.array:
'''
Calling the Fuzzy set returns its membership.
@@ -234,7 +243,10 @@ Source code for ex_fuzzy.fuzzy_sets
-[docs]class categoricalFS(FS):
+
+
+[docs]
+class categoricalFS(FS):
def __init__(self, name: str, category) -> None:
'''
@@ -252,7 +264,9 @@ Source code for ex_fuzzy.fuzzy_sets
mnt.usage_data[mnt.usage_categories.FuzzySets][self.type().name] += 1
-[docs] def membership(self, x: np.array) -> np.array:
+
+[docs]
+ def membership(self, x: np.array) -> np.array:
'''
Computes the membership of a point or vector of elements.
@@ -272,14 +286,30 @@ Source code for ex_fuzzy.fuzzy_sets
return res
-[docs] def type(self) -> FUZZY_SETS:
+
+
+[docs]
+ def type(self) -> FUZZY_SETS:
'''
Returns the corresponding fuzzy set type according to FUZZY_SETS enum.
'''
- return FUZZY_SETS.t1
+ return FUZZY_SETS.t1
+
+
+
+ def __str__(self) -> str:
+ '''
+ Returns the name of the fuzzy set, its type and its parameters.
+
+ :return: string.
+ '''
+ return f'Categorical set: {self.name}, type 1 output'
-[docs]class IVFS(FS):
+
+
+[docs]
+class IVFS(FS):
'''
Class to define a iv fuzzy set.
'''
@@ -312,7 +342,9 @@ Source code for ex_fuzzy.fuzzy_sets
self.lower_height = lower_height
-[docs] def membership(self, x: np.array) -> np.array:
+
+[docs]
+ def membership(self, x: np.array) -> np.array:
'''
Computes the iv-membership of a point or a vector.
@@ -331,14 +363,30 @@ Source code for ex_fuzzy.fuzzy_sets
return np.stack([lower, upper], axis=-1)
-[docs] def type(self) -> FUZZY_SETS:
+
+
+[docs]
+ def type(self) -> FUZZY_SETS:
'''
Returns the corresponding fuzzy set type according to FUZZY_SETS enum: (t2)
'''
- return FUZZY_SETS.t2
+ return FUZZY_SETS.t2
+
+
+
+ def __str__(self) -> str:
+ '''
+ Returns the name of the fuzzy set, its type and its parameters.
+
+ :return: string.
+ '''
+ return f'{self.name} ({self.type().name}) - {self.secondMF_lower} - {self.secondMF_upper}'
+
-[docs]class categoricalIVFS(IVFS):
+
+[docs]
+class categoricalIVFS(IVFS):
'''
Class to define a iv fuzzy set with categorical membership.
'''
@@ -360,7 +408,9 @@ Source code for ex_fuzzy.fuzzy_sets
mnt.usage_data[mnt.usage_categories.FuzzySets][self.type().name] += 1
-[docs] def membership(self, x: np.array) -> np.array:
+
+[docs]
+ def membership(self, x: np.array) -> np.array:
'''
Computes the membership of a point or vector of elements.
@@ -385,15 +435,31 @@ Source code for ex_fuzzy.fuzzy_sets
return res
-[docs] def type(self) -> FUZZY_SETS:
+
+
+[docs]
+ def type(self) -> FUZZY_SETS:
'''
Returns the corresponding fuzzy set type according to FUZZY_SETS enum.
'''
- return FUZZY_SETS.t2
+ return FUZZY_SETS.t2
+
+
+
+ def __str__(self) -> str:
+ '''
+ Returns the name of the fuzzy set, its type and its parameters.
+
+ :return: string.
+ '''
+ return f'Categorical set: {self.name}, type 2 output'
+
-[docs]class GT2(FS):
+
+[docs]
+class GT2(FS):
'''
Class to define a gt2 fuzzy set.
'''
@@ -464,7 +530,9 @@ Source code for ex_fuzzy.fuzzy_sets
self.iv_secondary_memberships[alpha_cut] = array_level_memberships
-[docs] def membership(self, x: np.array) -> np.array:
+
+[docs]
+ def membership(self, x: np.array) -> np.array:
'''
Computes the alpha cut memberships of a point.
@@ -489,8 +557,12 @@ Source code for ex_fuzzy.fuzzy_sets
return np.swapaxes(alpha_cut_memberships, 0, 1)
-[docs] def type(self) -> FUZZY_SETS:
+
+
+
def _alpha_reduction(self, x) -> np.array:
@@ -508,22 +580,30 @@ Source code for ex_fuzzy.fuzzy_sets
return np.sum(formatted * x, axis=-1) / np.sum(self.alpha_cuts)
-[docs] def alpha_reduction(self, x) -> np.array:
+
+[docs]
+ def alpha_reduction(self, x) -> np.array:
'''
Computes the type reduction to reduce the alpha cuts to one value.
:param x: array with the values of the inputs.
:return: array with the memberships of the consequents for each sample.
'''
- return self._alpha_reduction(x)
+ return self._alpha_reduction(x)
+
+
-[docs]class gaussianIVFS(IVFS):
+
+[docs]
+class gaussianIVFS(IVFS):
'''
Class to define a iv fuzzy set with gaussian membership.
'''
-[docs] def membership(self, input: np.array) -> np.array:
+
+[docs]
+ def membership(self, input: np.array) -> np.array:
'''
Computes the gaussian iv-membership of a point or a vector.
@@ -536,19 +616,28 @@ Source code for ex_fuzzy.fuzzy_sets
return np.array(np.concatenate([lower, upper])).T
-[docs] def type(self) -> FUZZY_SETS:
+
+
+[docs]
+ def type(self) -> FUZZY_SETS:
'''
Returns the type of the fuzzy set. (t1)
'''
- return FUZZY_SETS.t2
+ return FUZZY_SETS.t2
+
+
-[docs]class gaussianFS(FS):
+
+[docs]
+class gaussianFS(FS):
'''
Class to define a gaussian fuzzy set.
'''
-[docs] def membership(self, input: np.array) -> np.array:
+
+[docs]
+ def membership(self, input: np.array) -> np.array:
'''
Computes the gaussian membership of a point or a vector.
@@ -558,14 +647,21 @@ Source code for ex_fuzzy.fuzzy_sets
return __gaussian2(input, self.membership_parameters)
-[docs] def type(self) -> FUZZY_SETS:
+
+
+[docs]
+ def type(self) -> FUZZY_SETS:
'''
Returns the type of the fuzzy set. (t1)
'''
- return FUZZY_SETS.t1
+ return FUZZY_SETS.t1
+
+
-[docs]class fuzzyVariable():
+
+[docs]
+class fuzzyVariable():
'''
Class to implement a fuzzy Variable. Contains a series of fuzzy sets and computes the memberships to all of them.
'''
@@ -588,7 +684,21 @@ Source code for ex_fuzzy.fuzzy_sets
self.fs_type = self.linguistic_variables[0].type()
-[docs] def linguistic_variable_names(self) -> list:
+
+[docs]
+ def append(self, fs: FS) -> None:
+ '''
+ Appends a fuzzy set to the fuzzy variable.
+
+ :param fs: FS. Fuzzy set to append.
+ '''
+ self.linguistic_variables.append(fs)
+
+
+
+
+[docs]
+ def linguistic_variable_names(self) -> list:
'''
Returns the name of the linguistic variables.
@@ -597,7 +707,10 @@ Source code for ex_fuzzy.fuzzy_sets
return [fs.name for fs in self.linguistic_variables]
-[docs] def get_linguistic_variables(self) -> list[FS]:
+
+
+[docs]
+ def get_linguistic_variables(self) -> list[FS]:
'''
Returns the name of the linguistic variables.
@@ -606,7 +719,10 @@ Source code for ex_fuzzy.fuzzy_sets
return self.linguistic_variables
-[docs] def compute_memberships(self, x: np.array) -> list:
+
+
+[docs]
+ def compute_memberships(self, x: np.array) -> list:
'''
Computes the membership to each of the FS in the fuzzy variables.
@@ -621,7 +737,10 @@ Source code for ex_fuzzy.fuzzy_sets
return res
-[docs] def domain(self) -> list[float]:
+
+
+[docs]
+ def domain(self) -> list[float]:
'''
Returns the domain of the fuzzy variable.
@@ -630,7 +749,10 @@ Source code for ex_fuzzy.fuzzy_sets
return self.linguistic_variables[0].domain
-[docs] def fuzzy_type(self) -> FUZZY_SETS:
+
+
+[docs]
+ def fuzzy_type(self) -> FUZZY_SETS:
'''
Returns the fuzzy type of the domain
@@ -639,6 +761,7 @@ Source code for ex_fuzzy.fuzzy_sets
return self.fs_type
+
def __getitem__(self, item) -> FS:
'''
Returns the corresponding fs.
@@ -689,6 +812,7 @@ Source code for ex_fuzzy.fuzzy_sets
return self.compute_memberships(x)
+
diff --git a/docs/build/html/_modules/ex_fuzzy/persistence.html b/docs/build/html/_modules/ex_fuzzy/persistence.html
index fa45946..4d7ee2f 100644
--- a/docs/build/html/_modules/ex_fuzzy/persistence.html
+++ b/docs/build/html/_modules/ex_fuzzy/persistence.html
@@ -1,22 +1,20 @@
+
+
-
+
ex_fuzzy.persistence — Ex-Fuzzy documentation
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
@@ -117,13 +115,21 @@ Source code for ex_fuzzy.persistence
return re.sub(pattern, replacement, text)
-[docs]def load_fuzzy_rules(rules_printed: str, fuzzy_variables: list) -> rules.MasterRuleBase:
+import re
+
+def remove_parentheses(text):
+ return re.sub(r'\(.*?\)', '', text)
+
+
+
+[docs]
+def load_fuzzy_rules(rules_printed: str, fuzzy_variables: list) -> rules.MasterRuleBase:
'''
Load the rules from a string.
:param rules_printed: string with the rules. Follows the specification given by the same printing method of rules.MasterRuleBase
:param fuzzy_variables: list with the linguistic variables. Objects of FuzzyVariable class.
-
+ :return mrule_base: object of MasterRuleBase class that contains the rules.
'''
if mnt.save_usage_flag:
mnt.usage_data[mnt.usage_categories.Persistence]['persistence_read'] += 1
@@ -146,7 +152,8 @@ Source code for ex_fuzzy.persistence
rule_acc = stat.strip()
elif 'WGHT' in stat:
rule_weight = stat.strip()
-
+
+ consequent_ds = remove_parentheses(consequent_ds)
consequent_ds = consequent_ds.split(',')[0].strip()
modifiers = np.ones((len(fuzzy_variables),))
init_rule_antecedents = np.zeros(
@@ -216,12 +223,15 @@ Source code for ex_fuzzy.persistence
return mrule_base
-[docs]def load_fuzzy_variables(fuzzy_variables_printed: str) -> list:
+
+
+[docs]
+def load_fuzzy_variables(fuzzy_variables_printed: str) -> list:
'''
Load the linguistic variables from a string.
:param fuzzy_variables_printed: string with the linguistic variables. Follows the specification given by the same printing method of FuzzyVariable class.
-
+ :return fuzzy_variables: list with the linguistic variables. Objects of FuzzyVariable class.
'''
if mnt.save_usage_flag:
mnt.usage_data[mnt.usage_categories.Persistence]['persistence_read'] += 1
@@ -297,12 +307,15 @@ Source code for ex_fuzzy.persistence
return fuzzy_variables
-[docs]def print_fuzzy_variable(fuzzy_variable: fs.fuzzyVariable) -> str:
+
+
+[docs]
+def print_fuzzy_variable(fuzzy_variable: fs.fuzzyVariable) -> str:
'''
Save the linguistic variable to a string.
:param fuzzy_variable: linguistic variable. Object of FuzzyVariable class.
-
+ :return fuzzy_variable_printed: string with the linguistic variable. Follows the specification given by the same printing method of FuzzyVariable class.
'''
if mnt.save_usage_flag:
mnt.usage_data[mnt.usage_categories.Persistence]['persistence_write'] += 1
@@ -335,12 +348,15 @@ Source code for ex_fuzzy.persistence
return fuzzy_variable_printed
-[docs]def save_fuzzy_variables(fuzzy_variables: list) -> str:
+
+
+[docs]
+def save_fuzzy_variables(fuzzy_variables: list) -> str:
'''
Save the linguistic variables to a string.
:param fuzzy_variables: list with the linguistic variables. Objects of FuzzyVariable class.
-
+ :return fuzzy_variables_printed: string with the linguistic variables. Follows the specification given by the same printing method of FuzzyVariable class.
'''
if mnt.save_usage_flag:
mnt.usage_data[mnt.usage_categories.Persistence]['persistence_write'] += 1
@@ -350,6 +366,7 @@ Source code for ex_fuzzy.persistence
fuzzy_variables_printed += print_fuzzy_variable(fvar) + '\n'
return fuzzy_variables_printed
+
diff --git a/docs/build/html/_modules/ex_fuzzy/rules.html b/docs/build/html/_modules/ex_fuzzy/rules.html
index 1a29809..65eb9b7 100644
--- a/docs/build/html/_modules/ex_fuzzy/rules.html
+++ b/docs/build/html/_modules/ex_fuzzy/rules.html
@@ -1,22 +1,20 @@
+
+
-
+
ex_fuzzy.rules — Ex-Fuzzy documentation
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
@@ -101,7 +99,9 @@ Source code for ex_fuzzy.rules
modifiers_names = {0.5: 'Somewhat', 1.0: '', 1.3: 'A little', 1.7: 'Slightly', 2.0: 'Very', 3.0: 'Extremely', 4.0: 'Very very'}
-[docs]def compute_antecedents_memberships(antecedents: list[fs.fuzzyVariable], x: np.array) -> list[dict]:
+
+[docs]
+def compute_antecedents_memberships(antecedents: list[fs.fuzzyVariable], x: np.array) -> list[dict]:
'''
Returns a list of of dictionaries that contains the memberships for each x value to the ith antecedents, nth linguistic variable.
x must be a vector (only one sample)
@@ -118,9 +118,12 @@ Source code for ex_fuzzy.rules
return cache_antecedent_memberships
+
-[docs]class RuleError(Exception):
+
+[docs]
+class RuleError(Exception):
'''
Exception raised when a rule is not well defined.
'''
@@ -135,6 +138,7 @@ Source code for ex_fuzzy.rules
+
def _myprod(x: np.array, y: np.array) -> np.array:
'''
Proxy function to change the product operation interface
@@ -142,7 +146,9 @@ Source code for ex_fuzzy.rules
return x*y
-[docs]class Rule():
+
+[docs]
+class Rule():
'''
Class of Rule designed to work with one single rule. It contains the whole inference functionally in itself.
'''
@@ -158,7 +164,9 @@ Source code for ex_fuzzy.rules
self.consequent = consequent
-[docs] def membership(self, x: np.array, tnorm=_myprod) -> np.array:
+
+[docs]
+ def membership(self, x: np.array, tnorm=_myprod) -> np.array:
'''
Computes the membership of one input to the antecedents of the rule.
@@ -174,7 +182,10 @@ Source code for ex_fuzzy.rules
return res
-[docs] def consequent_centroid(self) -> np.array:
+
+
+[docs]
+ def consequent_centroid(self) -> np.array:
'''
Returns the centroid of the consequent using a Karnik and Mendel algorithm.
'''
@@ -190,11 +201,15 @@ Source code for ex_fuzzy.rules
self.centroid_consequent = centroid.compute_centroid_fs(
domain_linspace, consequent_memberships)
- return self.centroid_consequent
+ return self.centroid_consequent
+
-[docs]class RuleSimple():
+
+
+[docs]
+class RuleSimple():
'''
Class designed to represent rules in its simplest form to optimize the computation in a rulebase.
@@ -242,7 +257,8 @@ Source code for ex_fuzzy.rules
aux = 'Rule: antecedents: ' + str(self.antecedents) + ' consequent: ' + str(self.consequent)
try:
- aux += ' modifiers: ' + str(self.modifiers)
+ if self.modifiers is not None:
+ aux += ' modifiers: ' + str(self.modifiers)
except AttributeError:
pass
@@ -261,6 +277,16 @@ Source code for ex_fuzzy.rules
except AttributeError:
pass
+ try:
+ aux += ' p-value class structure: ' + str(self.p_value_class_structure)
+ except AttributeError:
+ pass
+
+ try:
+ aux += ' p-value feature coalitions: ' + str(self.p_value_feature_coalitions)
+ except AttributeError:
+ pass
+
return aux
@@ -286,7 +312,10 @@ Source code for ex_fuzzy.rules
-[docs]class RuleBase():
+
+
+[docs]
+class RuleBase():
'''
Class optimized to work with multiple rules at the same time. Right now supports only one consequent. (Solution: use one rulebase per consequent to study)
'''
@@ -327,14 +356,19 @@ Source code for ex_fuzzy.rules
self.delete_duplicates()
-[docs] def get_rules(self) -> list[RuleSimple]:
+
+[docs]
+ def get_rules(self) -> list[RuleSimple]:
'''
Returns the list of rules in the rulebase.
'''
return self.rules
-[docs] def add_rule(self, new_rule: RuleSimple):
+
+
+[docs]
+ def add_rule(self, new_rule: RuleSimple):
'''
Adds a new rule to the rulebase.
:param new_rule: rule to add.
@@ -342,7 +376,10 @@ Source code for ex_fuzzy.rules
self.rules.append(new_rule)
-[docs] def add_rules(self, new_rules: list[RuleSimple]):
+
+
+[docs]
+ def add_rules(self, new_rules: list[RuleSimple]):
'''
Adds a list of new rules to the rulebase.
@@ -351,7 +388,10 @@ Source code for ex_fuzzy.rules
self.rules += new_rules
-[docs] def remove_rule(self, ix: int) -> None:
+
+
+[docs]
+ def remove_rule(self, ix: int) -> None:
'''
Removes the rule in the given index.
:param ix: index of the rule to remove.
@@ -359,7 +399,10 @@ Source code for ex_fuzzy.rules
del self.rules[ix]
-[docs] def remove_rules(self, delete_list: list[int]) -> None:
+
+
+[docs]
+ def remove_rules(self, delete_list: list[int]) -> None:
'''
Removes the rules in the given list of indexes.
@@ -369,7 +412,10 @@ Source code for ex_fuzzy.rules
self.rules) if ix not in delete_list]
-[docs] def get_rulebase_matrix(self):
+
+
+[docs]
+ def get_rulebase_matrix(self):
'''
Returns a matrix with the antecedents values for each rule.
'''
@@ -381,7 +427,10 @@ Source code for ex_fuzzy.rules
return res
-[docs] def get_scores(self):
+
+
+[docs]
+ def get_scores(self):
'''
Returns an array with the dominance score for each rule.
(Must been already computed by an evalRule object)
@@ -392,9 +441,12 @@ Source code for ex_fuzzy.rules
res[ix] = rule.score
return res
+
-[docs] def get_weights(self):
+
+[docs]
+ def get_weights(self):
'''
Returns an array with the weights for each rule.
(Different from dominance scores: must been already computed by an optimization algorithm)
@@ -407,6 +459,7 @@ Source code for ex_fuzzy.rules
return res
+
def delete_rule_duplicates(self, list_rules:list[RuleSimple]):
# Delete the rules that are duplicated in the rule list
unique = {}
@@ -421,7 +474,9 @@ Source code for ex_fuzzy.rules
return new_list
-[docs] def compute_antecedents_memberships(self, x: np.array) -> list[dict]:
+
+[docs]
+ def compute_antecedents_memberships(self, x: np.array) -> list[dict]:
'''
Returns a list of of dictionaries that contains the memberships for each x value to the ith antecedents, nth linguistic variable.
x must be a vector (only one sample)
@@ -451,7 +506,10 @@ Source code for ex_fuzzy.rules
return [np.zeros((x.shape[0], len(self.alpha_cuts), 2))]
-[docs] def compute_rule_antecedent_memberships(self, x: np.array, scaled=False, antecedents_memberships:list[np.array]=None) -> np.array:
+
+
+[docs]
+ def compute_rule_antecedent_memberships(self, x: np.array, scaled=False, antecedents_memberships:list[np.array]=None) -> np.array:
'''
Computes the antecedent truth value of an input array.
@@ -544,7 +602,10 @@ Source code for ex_fuzzy.rules
return res
-[docs] def print_rules(self, return_rules:bool=False) -> None:
+
+
+[docs]
+ def print_rules(self, return_rules:bool=False) -> None:
'''
Print the rules from the rule base.
@@ -561,10 +622,13 @@ Source code for ex_fuzzy.rules
else:
return all_rules
+
-[docs] @abc.abstractmethod
+
+[docs]
+ @abc.abstractmethod
def inference(self, x: np.array) -> np.array:
'''
Computes the fuzzy output of the fl inference system.
@@ -577,7 +641,10 @@ Source code for ex_fuzzy.rules
raise NotImplementedError
-[docs] @abc.abstractmethod
+
+
+[docs]
+ @abc.abstractmethod
def forward(self, x: np.array) -> np.array:
'''
Computes the deffuzified output of the fl inference system.
@@ -590,7 +657,10 @@ Source code for ex_fuzzy.rules
raise NotImplementedError
-[docs] @abc.abstractmethod
+
+
+[docs]
+ @abc.abstractmethod
def fuzzy_type(self) -> fs.FUZZY_SETS:
'''
Returns the corresponding type of the RuleBase using the enum type in the fuzzy_sets module.
@@ -600,6 +670,7 @@ Source code for ex_fuzzy.rules
raise NotImplementedError
+
def __len__(self):
'''
Returns the number of rules in the rule base.
@@ -607,7 +678,9 @@ Source code for ex_fuzzy.rules
return len(self.rules)
-[docs] def prune_bad_rules(self, tolerance=0.01) -> None:
+
+[docs]
+ def prune_bad_rules(self, tolerance=0.01) -> None:
'''
Delete the rules from the rule base that do not have a dominance score superior to the threshold or have 0 accuracy in the training set.
@@ -632,7 +705,10 @@ Source code for ex_fuzzy.rules
self.remove_rules(delete_list)
-[docs] def scores(self) -> np.array:
+
+
+[docs]
+ def scores(self) -> np.array:
'''
Returns the dominance score for each rule.
@@ -645,6 +721,7 @@ Source code for ex_fuzzy.rules
return np.array(scores)
+
def __getitem__(self, item: int) -> RuleSimple:
'''
Returns the corresponding rulebase.
@@ -703,14 +780,20 @@ Source code for ex_fuzzy.rules
return RuleBase(self.antecedents, self.rules + other.rules, self.consequent, self.tnorm)
-[docs] def n_linguistic_variables(self) -> int:
+
+[docs]
+ def n_linguistic_variables(self) -> int:
'''
Returns the number of linguistic variables in the rule base.
'''
- return [len(amt) for amt in self.antecedents]
+ return [len(amt) for amt in self.antecedents]
+
+
-[docs]class RuleBaseT2(RuleBase):
+
+[docs]
+class RuleBaseT2(RuleBase):
'''
Class optimized to work with multiple rules at the same time. Supports only one consequent.
(Use one rulebase per consequent to study classification problems. Check MasterRuleBase class for more documentation)
@@ -755,7 +838,9 @@ Source code for ex_fuzzy.rules
self.consequent_centroids_rules[ix] = self.consequent_centroids[consequent_ix]
-[docs] def inference(self, x: np.array) -> np.array:
+
+[docs]
+ def inference(self, x: np.array) -> np.array:
'''
Computes the iv output of the t2 inference system.
@@ -774,7 +859,10 @@ Source code for ex_fuzzy.rules
return res
-[docs] def forward(self, x: np.array) -> np.array:
+
+
+[docs]
+ def forward(self, x: np.array) -> np.array:
'''
Computes the deffuzified output of the t2 inference system.
@@ -786,16 +874,23 @@ Source code for ex_fuzzy.rules
return np.mean(self.inference(x))
-[docs] def fuzzy_type(self) -> fs.FUZZY_SETS:
+
+
+[docs]
+ def fuzzy_type(self) -> fs.FUZZY_SETS:
'''
Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module.
:return: the corresponding fuzzy set type of the RuleBase.
'''
- return fs.FUZZY_SETS.t2
+ return fs.FUZZY_SETS.t2
+
+
-[docs]class RuleBaseGT2(RuleBase):
+
+[docs]
+class RuleBaseGT2(RuleBase):
'''
Class optimized to work with multiple rules at the same time. Supports only one consequent.
(Use one rulebase per consequent to study classification problems. Check MasterRuleBase class for more documentation)
@@ -826,7 +921,9 @@ Source code for ex_fuzzy.rules
self.fuzzy_modifier = fuzzy_modifiers
-[docs] def inference(self, x: np.array) -> np.array:
+
+[docs]
+ def inference(self, x: np.array) -> np.array:
'''
Computes the output of the gt2 inference system.
@@ -845,6 +942,7 @@ Source code for ex_fuzzy.rules
return res
+
def _alpha_reduction(self, x) -> np.array:
'''
Computes the type reduction to reduce the alpha cuts to one value.
@@ -857,7 +955,9 @@ Source code for ex_fuzzy.rules
return np.sum(formtatted * x, axis=2) / np.sum(self.alpha_cuts)
-[docs] def forward(self, x: np.array) -> np.array:
+
+[docs]
+ def forward(self, x: np.array) -> np.array:
'''
Computes the deffuzified output of the t2 inference system.
@@ -869,7 +969,10 @@ Source code for ex_fuzzy.rules
return np.sum(np.array(self.alpha_cuts) * (self.inference(x)), axis=1) / np.sum(self.alpha_cuts)
-[docs] def fuzzy_type(self) -> fs.FUZZY_SETS:
+
+
+[docs]
+ def fuzzy_type(self) -> fs.FUZZY_SETS:
'''
Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module.
@@ -878,7 +981,10 @@ Source code for ex_fuzzy.rules
return fs.FUZZY_SETS.gt2
-[docs] def compute_rule_antecedent_memberships(self, x: np.array, scaled=True, antecedents_memberships=None) -> np.array:
+
+
+[docs]
+ 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.
@@ -887,11 +993,16 @@ Source code for ex_fuzzy.rules
: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)
+
+ rules_truth_values = super().compute_rule_antecedent_memberships(x, scaled, antecedents_memberships=antecedents_memberships)
+
+ return self._alpha_reduction(rules_truth_values)
+
-[docs] def alpha_compute_rule_antecedent_memberships(self, x: np.array, scaled=True, antecedents_memberships=None) -> np.array:
+
+[docs]
+ 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.
@@ -900,11 +1011,15 @@ Source code for ex_fuzzy.rules
: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)
+ return super().compute_rule_antecedent_memberships(x, scaled)
+
+
-[docs]class RuleBaseT1(RuleBase):
+
+[docs]
+class RuleBaseT1(RuleBase):
'''
Class optimized to work with multiple rules at the same time. Supports only one consequent.
(Use one rulebase per consequent to study classification problems. Check MasterRuleBase class for more documentation)
@@ -947,7 +1062,9 @@ Source code for ex_fuzzy.rules
self.consequent_centroids_rules[ix] = self.consequent_centroids[consequent_ix]
-[docs] def inference(self, x: np.array) -> np.array:
+
+[docs]
+ def inference(self, x: np.array) -> np.array:
'''
Computes the output of the t1 inference system.
@@ -966,7 +1083,10 @@ Source code for ex_fuzzy.rules
return res
-[docs] def forward(self, x: np.array) -> np.array:
+
+
+[docs]
+ def forward(self, x: np.array) -> np.array:
'''
Same as inference() in the t1 case.
@@ -978,17 +1098,24 @@ Source code for ex_fuzzy.rules
return self.inference(x)
-[docs] def fuzzy_type(self) -> fs.FUZZY_SETS:
+
+
+[docs]
+ def fuzzy_type(self) -> fs.FUZZY_SETS:
'''
Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module.
:return: the corresponding fuzzy set type of the RuleBase.
'''
- return fs.FUZZY_SETS.t1
+ return fs.FUZZY_SETS.t1
+
+
-[docs]class MasterRuleBase():
+
+[docs]
+class MasterRuleBase():
'''
This Class encompasses a list of rule bases where each one corresponds to a different class.
'''
@@ -1013,14 +1140,19 @@ Source code for ex_fuzzy.rules
self.allow_unknown = allow_unknown
-[docs] def rename_cons(self, consequent_names: list[str]) -> None:
+
+[docs]
+ def rename_cons(self, consequent_names: list[str]) -> None:
'''
Renames the consequents of the rule base.
'''
self.consequent_names = consequent_names
-[docs] def add_rule(self, rule: RuleSimple, consequent: int) -> None:
+
+
+[docs]
+ def add_rule(self, rule: RuleSimple, consequent: int) -> None:
'''
Adds a rule to the rule base of the given consequent.
@@ -1028,9 +1160,12 @@ Source code for ex_fuzzy.rules
:param consequent: index of the rule base to add the rule.
'''
self.rule_bases[consequent].add_rule(rule)
+
-[docs] def get_consequents(self) -> list[int]:
+
+[docs]
+ def get_consequents(self) -> list[int]:
'''
Returns a list with the consequents of each rule base.
@@ -1039,16 +1174,22 @@ Source code for ex_fuzzy.rules
return sum([[ix]*len(x) for ix, x in enumerate(self.rule_bases)], [])
-[docs] def get_consequents_names(self) -> list[str]:
+
+
+[docs]
+ def get_consequents_names(self) -> list[str]:
'''
Returns a list with the names of the consequents.
:return: list with the names of the consequents.
'''
return self.consequent_names
+
-[docs] def get_rulebase_matrix(self) -> list[np.array]:
+
+[docs]
+ def get_rulebase_matrix(self) -> list[np.array]:
'''
Returns a list with the rulebases for each antecedent in matrix format.
@@ -1057,7 +1198,10 @@ Source code for ex_fuzzy.rules
return [x.get_rulebase_matrix() for x in self.rule_bases]
-[docs] def get_scores(self) -> np.array:
+
+
+[docs]
+ def get_scores(self) -> np.array:
'''
Returns the dominance score for each rule in all the rulebases.
@@ -1070,9 +1214,12 @@ Source code for ex_fuzzy.rules
res = [x for x in res if len(x) > 0]
return np.concatenate(res, axis=0)
+
-[docs] def get_weights(self) -> np.array:
+
+[docs]
+ def get_weights(self) -> np.array:
'''
Returns the weights for each rule in all the rulebases.
@@ -1087,7 +1234,10 @@ Source code for ex_fuzzy.rules
return np.concatenate(res, axis=0)
-[docs] def compute_firing_strenghts(self, X, precomputed_truth=None) -> np.array:
+
+
+[docs]
+ def compute_firing_strenghts(self, X, precomputed_truth=None) -> np.array:
'''
Computes the firing strength of each rule for each sample.
@@ -1099,10 +1249,11 @@ Source code for ex_fuzzy.rules
for ix in range(len(self.rule_bases)):
aux.append(self[ix].compute_rule_antecedent_memberships(X, antecedents_memberships=precomputed_truth))
- # Firing strengths shape: samples x rules
+ # Firing strengths shape: samples x rules (x 2) (last is iv dimension) or (x alpha_cuts x 2) for gt2
return np.concatenate(aux, axis=1)
+
def _winning_rules(self, X: np.array, precomputed_truth=None, allow_unkown=True) -> np.array:
association_degrees = self.compute_association_degrees(X, precomputed_truth)
@@ -1115,7 +1266,9 @@ Source code for ex_fuzzy.rules
return winning_rules
-[docs] def compute_association_degrees(self, X, precomputed_truth=None):
+
+[docs]
+ def compute_association_degrees(self, X, precomputed_truth=None):
'''
Returns the winning rule for each sample. Takes into account dominance scores if already computed.
:param X: array with the values of the inputs.
@@ -1145,9 +1298,12 @@ Source code for ex_fuzzy.rules
association_degrees = np.mean(association_degrees, axis=3)
return association_degrees
+
-[docs] def winning_rule_predict(self, X: np.array, precomputed_truth=None, out_class_names=False) -> np.array:
+
+[docs]
+ def winning_rule_predict(self, X: np.array, precomputed_truth=None, out_class_names=False) -> np.array:
'''
Returns the winning rule for each sample. Takes into account dominance scores if already computed.
@@ -1188,7 +1344,10 @@ Source code for ex_fuzzy.rules
return np.array(res)
-[docs] def add_rule_base(self, rule_base: RuleBase) -> None:
+
+
+[docs]
+ def add_rule_base(self, rule_base: RuleBase) -> None:
'''
Adds a rule base to the list of rule bases.
@@ -1201,7 +1360,10 @@ Source code for ex_fuzzy.rules
self.consequent_names = [ix for ix in range(len(self.rule_bases))]
-[docs] def print_rules(self, return_rules=False) -> None:
+
+
+[docs]
+ def print_rules(self, return_rules=False) -> None:
'''
Print all the rules for all the consequents.
@@ -1220,7 +1382,10 @@ Source code for ex_fuzzy.rules
print(res)
-[docs] def get_rules(self) -> list[RuleSimple]:
+
+
+[docs]
+ def get_rules(self) -> list[RuleSimple]:
'''
Returns a list with all the rules.
@@ -1229,7 +1394,10 @@ Source code for ex_fuzzy.rules
return [rule for ruleBase in self.rule_bases for rule in ruleBase.rules]
-[docs] def fuzzy_type(self) -> fs.FUZZY_SETS:
+
+
+[docs]
+ def fuzzy_type(self) -> fs.FUZZY_SETS:
'''
Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module.
@@ -1238,7 +1406,10 @@ Source code for ex_fuzzy.rules
return self.rule_bases[0].fuzzy_type()
-[docs] def purge_rules(self, tolerance=0.001) -> None:
+
+
+[docs]
+ def purge_rules(self, tolerance=0.001) -> None:
'''
Delete the roles with a dominance score lower than the tolerance.
@@ -1248,6 +1419,7 @@ Source code for ex_fuzzy.rules
ruleBase.prune_bad_rules(tolerance)
+
def __getitem__(self, item) -> RuleBase:
'''
Returns the corresponding rulebase.
@@ -1297,9 +1469,24 @@ Source code for ex_fuzzy.rules
# Convert the predictions to the names of the consequents
#return np.array(self.consequent_names)[aux]
return aux
+
+
+
+[docs]
+ def predict(self, X: np.array) -> np.array:
+ '''
+ Gives the prediction for each sample (same as winning_rule_predict)
+
+ :param X: array of dims: samples x features.
+ :return: vector of predictions, size: samples,
+ '''
+ return self(X)
+
-