Changelog#
This document tracks all notable changes to Ex-Fuzzy.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased]#
[3.2.0] - 2026-09-16#
Changed#
Rule text without statistics loads: the
WITHclause of a printed rule lists whichever ofDS,ACCandWGHTthe rule has, andload_fuzzy_rulesaccepts any subset of them, a missingWITHclause, and ignores aTHENclause, so rules printed before evaluation round-tripRuleMineClassifierandRuleFineTuneClassifiertaken_gen,pop_size,patienceandrandom_statein their constructors, with the same fit-time overrides asBaseFuzzyRulesClassifierLazy package import:
import ex_fuzzyno longer imports every submodule; submodules and the top-level classes load on first access, which takes the import from about two seconds to a few millisecondsDocstrings follow the Google style throughout, with triple double quotes
Demos: seven executed notebooks replace the previous notebooks and scripts. They cover getting started, scikit-learn pipelines and grid search on the Titanic data, rules and partitions by hand, controlling the search and comparing every classifier, regression on California housing, conformal and evidential uncertainty, and robustness.
Demos/run_notebooks.pyrefreshes their outputsSearch settings are constructor parameters:
n_gen,pop_size,patience,min_delta,random_state,var_prob,sbx_eta,mutation_etaandtournament_sizecan be given toBaseFuzzyRulesClassifier, socloneandGridSearchCVsee them. Passing them tofitoverrides them for that fit only, as beforeds_modeaccepts the names'dominance','unweighted'and'optimized'besides0,1and2, and rejects anything else in the classifier,FitRuleBaseandMasterRuleBaseexplainable_predictreturns anExplainedPredictionnamed tuple with the fieldsprediction,winning_rule,association_degreeandconfidence_interval; it still unpacks as a four-tupleConformal prediction uses the fitted labels: calibration encodes them through
classes_, and prediction sets, p-values, rule contributions, calibration info and coverage reports are keyed by labelRuleMineClassifierpasses itsnAntsto the inner classifierThe
runnerparameter documents that threads disable the fit-local caches, so serial fits are usually fasterRule mining: the itemset search prunes with the Apriori property (min t-norm support never grows when an item is added) and the confidence and lift pruning computes the memberships once per variable. The candidate rules, their order and the pruned rule bases are identical
Packaging: metadata moved to
pyproject.tomlwithrequires-python >= 3.10, the AGPL license, and classifiers for Python 3.10 to 3.13;setup.pyonly builds the optional native FERL extension. CI tests Python 3.10 to 3.13 and runs the EvoX backend tests on CPUImport time: matplotlib is imported when a plot is drawn, not when the package is imported
Warnings and errors: the classifier reports the backend fallback, antecedent clamping and unsupported checkpoints with
warnings.warninstead of printing; incoherent interval fuzzy sets, missing dominance scores, empty rule lists and temporal sets without a fixed time raiseValueErrorinstead ofAssertionError;FuzzyEvaluator.get_metricraises instead of returning an error stringNames:
MasterRuleBase.compute_firing_strengthsandBaseFuzzyRulesClassifier.reparametrize_lossare the spelled names; the former misspellings remain as deprecated aliasesDocs: the duplicate Getting Started page was removed, the step-by-step pages form a Tutorial section, the multiprocessing advice was replaced by what speeds up a fit, and the README points at the documentation site
Package layout: the package now lives in
ex_fuzzy/at the repository root instead ofex_fuzzy/ex_fuzzy/, and the outer re-export shim is gone. Modules import each other with relative imports only, withouttry/except ImportErrorfallbacks, and the tests, benchmarks and demos import through the package.FUZZY_SETSuses the default enum equality and hashing again, since every module now exists once per process. Reinstall withpip install -e .after updating a checkoutType-1 rule-base inference computes the centroid of every sample with one matrix-vector product instead of a per-sample loop. Outputs agree with the former computation to about 1e-12 relative
BaseFuzzyRulesClassifier is a scikit-learn estimator: the constructor keeps every argument under its own name, so
get_params,clone,repr,cross_val_scoreandPipelinework.fitreturns the classifier and setsclasses_andn_features_in_. Labels are encoded as consequent indexes for the search andpredictreturns the labels the classifier was fitted with, soscoreworks with string labels and integer labels need not be0..n_classes-1. Samples with no firing rule predict-1for numeric labels and'Unknown'otherwise. Classifiers built from precomputed rules still predict consequent indexes. Thebackendparameter also accepts a backend instancePrediction computes memberships and firing once: a
MasterRuleBaseevaluates the antecedent memberships once for all its rule bases instead of once per rule base, and the winning-rule prediction no longer computes the firing strengths twice. Predictions are unchanged; the winning-rule predictions of a rule base are now integer arraysRule evaluation computes firing once: the
evalRuleBaseweight, accuracy and metric methods share one firing computation per call instead of recomputing it for support, confidence and dominance. Results are unchangedRule identity:
RuleSimpleequality and hashing now depend on the antecedents, consequent and modifiers only, not on the score, weight or accuracy attached later. Rule-base construction therefore removes rules with equal antecedents even when their weights differ, keeping the first one. This changesds_mode=2searches whose candidates repeat an antecedent pattern in one class; the array evaluator applies the same ruleRuleMineClassifier and RuleFineTuneClassifier are scikit-learn estimators: constructor arguments are stored under their own names and the inner classifiers are built when
fitis called, socloneand cross-validation work.fitsetsclasses_andn_features_in_, andpredictreturns the fitted labels. Thefl_classifier,fl_classifier1andfl_classifier2attributes remain available afterfitConformalFuzzyClassifier takes the wrapped classifier as
estimator(clf_or_nRulesis still accepted), whichget_paramsandclonesee;clfremains as an alias.fitnow also fits a wrapped classifier that has not been fitted yetTemporalFuzzyRulesClassifier gained
predict(X, time_moments), and itsfitreturns the classifier
Fixed#
FERLfailed to predict string labels, and could have truncated labels longer than the root’s, because its prediction arrays were typed by the first label; they now take the dtype ofclasses_With optimized partitions, numerical columns of a mixed DataFrame (as an imputer returns it) got a domain of 0 to their number of distinct values instead of their minimum and maximum
The pattern stability report printed a fraction of the trials as a percentage
Conformal prediction scored test samples with the membership nonconformity whatever
score_typewas calibrated with, so theentropysets did not reach their coverage; prediction now uses the calibrated score typeMissing or infinite feature values were silently assigned class 0, because NaN firing strengths made
argmaxpick the first rule, and gave NaN probabilities.fitand the prediction methods now reject them with aValueErrornaming the columnsConformal calibration crashed with string labels and mis-indexed integer labels that do not start at 0
Categorical fuzzy sets now define
domainandmembership_parametersasNone, sofuzzyVariable.domain()no longer raises for a categorical variable, and membership computation no longer relies on a swallowed exception to skip the domain clippingload_fuzzy_rulesparses theIF,IS,ANDandWITHkeywords as whole words, so variable and label names containing them (for example DISTANCE or WITHIN) load correctly, and rule text withoutRules forheaders loads as a single rule base instead of failingmulticlass_mine_rulebasepruned rules by comparing the labels with the rule base indexes, which failed for string labels and silently mismatched integer labels that do not start at 0; the labels are now encoded in the order the rule bases are builtRuleMineClassifiermined its candidate rules on freshly built partitions and ignored thelinguistic_variablesit was given; it now mines on the partitions it predicts withBaseFuzzyRulesClassifier.scorereturned 0 for string labels becausepredictreturned class indexesGeneral Type-2 rule bases with
ds_mode=2failed to predict because the rule weights were not broadcast over the interval axis
[3.1.0] - 2026-09-15#
Added#
EvoX GPU classification fitness: On a CUDA device the EvoX backend can score whole generations of the built-in Type-1 classification objective with an exact PyTorch implementation, for fixed or optimized partitions. Each fit checks it against the CPU on a few candidates of its first generation and then uses it only where it measures faster, so results are unchanged
Changed#
EvoX classification speed: EvoX fits use the fit-local fitness and firing caches and population batching, and score chromosomes repeated within a generation once. Results are unchanged
Final model evaluation: Classification fits reuse the selected fuzzy memberships and firing strengths while calculating rule weights, pruning, and final metrics. The temporary arrays are released before resampling or fit return, and the final model is unchanged
The fitness cache holds four populations of chromosomes (at least 256)
pymoo is imported only when used: importing Ex-Fuzzy and EvoX fits no longer import pymoo.
FitRuleBase,FitRuleBaseRegressionandExploreRuleBasesno longer subclass pymoo’sProblem; the PyMoo backend and the temporal classifier wrap them when they run. To pass one to pymoo directly, wrap it withevolutionary_backends.as_pymoo_problem
Fixed#
The batched population evaluator added the
alphasize penalty when every surviving rule scored exactly the tolerance; the reference adds nonePattern stability usage charts show “No variable usage” instead of failing when no variable is used
Removed#
The unused NetworkX rule-graph visualization and
vizinstallation extra. Text/LaTeX rule output and fuzzy-partition plotting remain available.
[3.0.0] - 2026-09-14#
Added#
FERL: Native Fast Evidential Rule Learning with compact or learned fuzzy splits, soft rule aggregation, Dempster–Shafer belief/plausibility, ignorance, prediction sets, missing-feature masks, and MDLP partitioning
FERL Demo and Documentation: Runnable Iris example, user guide, and API reference
DeepFERL: Deep evidential rule trees grown recursively with weighted-Gini learned soft splits and a leaves-only soft vote, with bounded-support out-of-distribution handling, missing-feature masks, and the same evidential outputs as FERL. Ports
LearnedFuzzyTree(FERL-deep) fromfuzzy_greedy_treeand reproduces its trees and predictionsFERL evidence: The
"mixture"combination rule, now shared with DeepFERL through a common evidence moduleFuzzyRulesClassifier: Rebuilt as a FARC-HD-style fuzzy association rule classifier. It caps features by relevance, mines candidate rules on fixed partitions, prescreens them by covering subgroup discovery, and selects a compact certainty-factor-weighted rule base with a vectorized genetic algorithm. It is a proper scikit-learn estimator; the earlier constructor and
fitarguments still work. Rules combine additively or sufficiently (rule_mode), as in Ex-Fuzzy regression. Rules with four or five conditions are mined with Apriori-style support pruning, which keeps the same candidates as exhaustive enumerationFuzzy Regression: Scikit-learn-compatible Type-1 rule learning for continuous targets with crisp Takagi-Sugeno and fuzzy Mamdani consequents
GPU-Accelerated Regression: EvoX/PyTorch population evaluation for both regression consequent types and additive or sufficient rule modes
Regression Runtime Metadata: Fitted estimators expose
backend_,optimization_device_,gpu_accelerated_, and generation statusEvoX Backend Support: GPU-accelerated evolutionary optimization using EvoX and PyTorch
Automatic Memory Management: Batch processing for large datasets to prevent out-of-memory errors
Performance Improvements: 2-10x speedup for large datasets with GPU acceleration
Backend Selection: Easy switching between PyMoo (CPU) and EvoX (GPU) backends
Comprehensive test suite with 100% statement and branch coverage
Modern documentation website with PyData theme
Interactive examples with Jupyter notebooks
GitHub Actions CI/CD pipeline
Type hints throughout the codebase
Performance benchmarking suite
Changed#
Fuzzy Tree Learning: The experimental prototype implementations were replaced by the public
ex_fuzzy.FERLestimatorFERL validation:
split_mode="learned"withtarget_metric="purity"now raisesValueErrorinstead of silently ignoring the learned splits, and an unknowntarget_metricis rejectedFERL evidence: An unknown
ruleinpredict_dsand related methods now raisesValueErrorinstead of silently using Dempster’s ruleRule mining:
rule_miningaccepts NumPy arrays as well as DataFrames, reading columns by position, soRuleMineClassifierno longer requires a DataFrameRuleFineTuneClassifier: Builds partitions before mining when none are given, and predicts with its second-stage model; both steps previously failed.
fitreturns the estimator for all rule-mining classifiersEvolutionary Optimization: Vectorized fitness evaluation for significant speedups
Memory Efficiency: Automatic batching prevents memory overflow on large datasets
GPU Utilization: Seamless GPU/CPU switching based on hardware availability
Improved API consistency across all modules
Better error messages and exception handling
Enhanced visualization capabilities
Optimized memory usage for large datasets
Fixed#
Unknown classification consequents no longer cause invalid one-hot indices during CUDA population evaluation
Bug in fuzzy set membership calculation
Memory leak in evolutionary optimization
Incorrect rule dominance score calculation
Threading issues in parallel processing
Deprecated#
Old maintenance module (mnt.*) - will be removed in v2.0
Legacy configuration format - use new YAML format
[1.0.0] - 2023-12-15#
Added#
Complete fuzzy logic inference system
Evolutionary optimization for rule discovery
Pattern stability analysis tools
Comprehensive visualization suite
Type-1 and Type-2 fuzzy set support
Multi-objective optimization capabilities
Rule mining and analysis tools
Model persistence and serialization
Changed#
Complete API redesign for better usability
Improved performance with vectorized operations
Enhanced documentation and examples
Better integration with scikit-learn
Fixed#
Various numerical stability issues
Compatibility with newer Python versions
Edge cases in fuzzy set operations
[0.9.0] - 2023-06-20#
Added#
Initial pattern stability analysis
Basic visualization tools
Evolutionary algorithm optimization
Type-1 fuzzy sets implementation
Changed#
Refactored core fuzzy logic engine
Improved rule representation
Better handling of categorical variables
Fixed#
Issues with rule evaluation
Memory usage optimization
Threading synchronization
[0.8.0] - 2023-03-15#
Added#
Basic fuzzy classification system
Rule-based inference engine
Simple optimization algorithms
Core fuzzy set operations
Changed#
Initial stable API design
Basic documentation structure
[0.7.0] - 2023-01-10#
Added#
Initial release
Basic fuzzy logic capabilities
Simple rule representation
Experimental optimization
Migration Guides#
Migrating from 0.9.x to 1.0.0#
API Changes:
# Old way (0.9.x)
from ex_fuzzy import FuzzyClassifier
classifier = FuzzyClassifier(rules=10, antecedents=4)
# New way (1.0.x)
from ex_fuzzy.evolutionary_fit import BaseFuzzyRulesClassifier
classifier = BaseFuzzyRulesClassifier(nRules=10, nAnts=4)
Configuration Changes:
# Old way (0.9.x)
classifier.set_config('tolerance', 0.1)
# New way (1.0.x)
classifier = BaseFuzzyRulesClassifier(tolerance=0.1)
Visualization Changes:
# Old way (0.9.x)
classifier.plot_rules()
# New way (1.0.x)
from ex_fuzzy.eval_tools import FuzzyEvaluator
evaluator = FuzzyEvaluator(classifier)
evaluator.eval_fuzzy_model(X_train, y_train, X_test, y_test, plot_rules=True)
Breaking Changes#
Version 1.0.0#
Removed deprecated mnt module
Changed main classifier import path
Renamed several configuration parameters
Modified visualization API for consistency
Version 0.9.0#
Changed rule representation format
Removed experimental features
Updated optimization algorithm interface
Notable Improvements#
Performance Improvements#
Version 1.0.0: - 40% faster rule evaluation - 60% reduction in memory usage - 3x improvement in optimization speed - Better scaling for large datasets
Version 0.9.0: - 25% faster fuzzy set operations - Improved numerical stability - Better caching mechanisms
Documentation Improvements#
Version 1.0.0: - Complete documentation overhaul - Interactive examples and tutorials - Comprehensive API reference - Best practices guide
Version 0.9.0: - Added user guide - Basic examples and tutorials - API documentation improvements
Acknowledgments#
We thank all contributors who made these releases possible:
Version 1.0.0 Contributors: - Javier Fumanal Idocin - Lead developer - Community contributors - Bug reports and feature requests - Beta testers - Early feedback and testing
Version 0.9.0 Contributors: - Initial development team - Academic collaborators - Open source community