Fuzzy association rule classifier#
ex_fuzzy.FuzzyRulesClassifier learns a compact linguistic rule base by
mining candidate fuzzy association rules and selecting a subset of them with a
genetic algorithm. It follows the FARC-HD family of fuzzy association rule
classifiers (Alcalá-Fdez, Alcalá and Herrera, IEEE Transactions on Fuzzy
Systems 19(5), 2011). ex_fuzzy.BaseFuzzyRulesClassifier, which evolves
rules directly, is a separate estimator and is unchanged.
How it learns#
Feature cap. Only the
max_featuresmost relevant features are kept, scored by mutual information by default. This keeps rule generation tractable and removes noisy inputs. Withfeature_selection="per_class", features are scored one class against the rest and each class keeps its ownmax_features. The rule base can then draw on more features overall, while each class’s rule search stays small.Fixed partitions. Each kept numerical feature is split into
n_linguistic_variablesquantile-based fuzzy terms. Categorical features get one term per category. Passlinguistic_variablesto use your own.Candidate mining. Rules with up to
nAntsconditions are scored per class (see Longer rules for four or five conditions). A rule is kept when its class support, confidence and penalized certainty factor pass their thresholds. Every class keeps some candidates, even when no rule passes them.Prescreening. A covering-based subgroup-discovery step keeps up to
candidates_per_classrules per class. It favours rules with high weighted relative accuracy on class samples that are not yet covered.Genetic rule selection. A genetic algorithm chooses the subset of prescreened rules that maximizes training accuracy, with a small penalty per rule. The firing strength of each candidate is computed once, so whole populations are scored with array operations.
Quick start#
from ex_fuzzy import FuzzyRulesClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
X, y = load_iris(return_X_y=True, as_frame=True)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.25, random_state=0, stratify=y
)
model = FuzzyRulesClassifier(max_features=8, rule_mode="additive", random_state=0)
model.fit(X_train, y_train)
labels = model.predict(X_test)
probabilities = model.predict_proba(X_test)
model.print_rules()
The estimator follows the scikit-learn API. It works with pipelines, cloning and cross-validation, and accepts DataFrames or arrays with any label type.
Additive and sufficient rules#
Each rule is weighted by its penalized certainty factor. rule_mode follows
the same convention as ex_fuzzy.BaseFuzzyRulesRegressor. With
rule_mode="additive" (the default), the weighted firing of each class’s
rules is summed and the largest total wins, so several moderately matching
rules can outvote one strong rule. With rule_mode="sufficient", only each
sample’s strongest weighted rule decides, which makes every prediction
traceable to a single rule. A sample that fires no rule takes the
majority class of the training data. predict_proba normalizes the class
scores, and gives the training class distribution to samples that fire no
rule.
Controlling size and cost#
max_featuresandnAntsbound the search space and rule length.class_features_records the features each class’s rules were mined on.max_features="auto"keeps 8 features for problems with up to five classes and 16 for problems with more.nAnts="auto"allows four conditions when a class’s rules come from at most six features, and three otherwise. The resolved values are stored inmax_features_andn_conditions_. The number of candidates grows with the number of feature combinations of up tonAntsfeatures.n_linguistic_variablessets the number of terms per numerical feature."auto"uses three terms for binary problems and five otherwise.nRulescaps the number of selected rules, andrules_per_classcaps it relative to the number of classes.nRules=Noneremoves the absolute cap, which problems with many classes may need.rule_penaltytrades training accuracy for fewer rules.candidates_per_classandexpansion_factorset how many prescreened rules the genetic search can choose from.n_gen,pop_sizeandpatiencebound the genetic search.
Longer rules#
Rules have at most three conditions by default. To allow longer rules, for example when classes are defined by interactions of several features, follow these steps.
Set
nAnts=4ornAnts=5. Beyond three conditions, candidate mining is pruned by support. Adding a condition can only lower a rule’s support for every class. So a rule is extended only while its support for some class reachesmin_support, and only if all of its shorter sub-rules were extended too. This keeps the same candidates as trying every combination, at a fraction of the cost. Up to three conditions the search stays exhaustive, which reproduces the published benchmark results exactly.model = FuzzyRulesClassifier(nAnts=5, random_state=0)
If fitting is too slow, shrink the search. Raising
min_support, for example to0.1, prunes the most, because it removes rare combinations early. Loweringmax_featuresreduces the number of feature combinations, and loweringn_linguistic_variablesreduces the number of term combinations per feature set.Compare against the default by cross-validation. Longer rules are more specific, not automatically more accurate.
As a guide, eight KEEL datasets were run with the benchmark protocol (5-fold cross-validation, 2 to 10 classes): pima, wdbc, vehicle, german, car, contraceptive, yeast and segment.
nAntsMean accuracy, additive
Mean accuracy, sufficient
3 (default)
0.745
0.743
4
0.750
0.741
5
0.752
0.745
Longer rules helped car and german by about two points and cost yeast one to two points. Fit time grew by up to about twice (yeast), and much less on the other datasets. Mining itself stays cheap: on 2,000 samples with 8 features and 5 terms, mining rules of up to five conditions took 0.07 s with pruning, against 3.2 s for exhaustive enumeration. Most of the extra time goes to selecting among the additional rules.
Check what the model used.
n_conditions_holds the resolved limit, andprint_rules()shows how many conditions the selected rules actually have. The genetic selection often keeps short rules even when long ones are allowed.
Inspecting the rules#
selected_features_ holds the indices of the features the rules use, and
linguistic_variables_ their partitions. rule_base_ is an Ex-Fuzzy
MasterRuleBase, with one rule base per class and the
certainty factors as rule weights, so the usual rule inspection and
persistence tools apply. internal_classifier() wraps it as a
BaseFuzzyRulesClassifier. That model expects only the
selected features and uses winning-rule inference without the majority-class
fallback.
Compatibility#
The constructor keeps the arguments of the earlier two-stage genetic
classifier of the same name, and fit(X, y, n_gen=..., pop_size=...)
still works. n_class and runner are accepted but ignored.
expansion_factor now multiplies the prescreened pool. Only Type-1 fuzzy
sets are supported.