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.5.0] - 2026-11-10#
Added#
Ordinal conditions:
ordinal_conditions=TrueonBaseFuzzyRulesClassifier(winning-rule and mixture inference, also withmixture_search) andBaseFuzzyRulesRegressor(and onFitRuleBaseandFitRuleBaseRegression) lets a rule statex IS at least torx IS at most tover the terms of a variable, ordered as listed from low to high, besides a single term. A variable withnterms offers thensingle terms plusat least t_jandat most t_jforj = 1 ... n - 2(3n - 4conditions; the vacuousat least t_0and the duplicates of a single term are not offered). The membership is the bounded summin(1, sum of the memberships of the terms covered), a shouldered trapezoid on a strong partition; it works for Type-1 and interval Type-2 sets, categorical variables keep single terms, and general Type-2 sets andcandidate_rulesare refused. The search widens the term gene to the condition codes (no gene is added), so mutation, crossover, sampling, the array, population, streamed and PyTorch objectives (on fixed partitions) and duplicate-rule detection handle it, and a set of terms has one code. Rules printIS at least Fair/IS at most Fair;rules.rule_conditions(RuleSimple.conditions) reads the operator (is,at_least,at_most) and term without parsing text; text rules and variables (persistence), pickles,print_mixture, the regression rules,rules_to_latexand thepattern_stabilityrule keys handle it. Off by default: the encoding, rules, printing, files and every seeded fit are those of 3.4.0 (a test replays nine recorded fits). The search space grows, so give it a larger budget when comparing (docs/source/ordinal_conditions.rst,benchmarks/benchmark_ordinal_conditions.py)Per-variable ordinal conditions and named compound terms:
ordinal_conditionsalso accepts a collection of features (names or indexes) that getat least/at mostwhile the others keep single terms, for example to leave a cyclic clock variable out. The newcompound_terms={feature: [(name, [terms])...]}adds one condition per entry,x IS <name>, whose membership is the bounded sum of the listed terms, which need not be contiguous (a union that wraps around midnight is two shoulders). Entries are validated (at least 2 distinct terms, not all of them, no repeated set, no ordinal duplicate, a name that is unique within its variable), work with or without ordinal conditions through the same codes, rows and evaluators, print by their name, are read asCondition(operator='any_of', terms=..., name=...)and round-trip through the rule and variable text and pickle. Same estimators; refused withcandidate_rules. Off by default and then bit-identical to 3.4.0
[3.4.0] - 2026-11-09#
Added#
Mixture of rules:
BaseFuzzyRulesClassifier(inference='mixture')lets every rule contribute to the decision: the score of class c isb_c + sum_r W[r, c] * firing_rand the prediction its argmax. After the genetic search (unchanged), the weights and biases are fitted on the training samples by L2-regularised multinomial logistic regression on the rule firing strengths (mixture_C), unconstrained or non-negative (mixture_non_negative).fit_mixturefits them for the rules of an existing model;mixture_scores,mixture_contributionsandprint_mixture(each rule with its weight per class, its strongest class and the biases) read them;predict_probareturns the softmax of the scores, the probabilities of a fitted model, not calibrated ones.mixture_search=Truealso scores each candidate of the search by the macro F1 of its own fitted mixture (much slower), after pruning it by the rules’ role in that mixture (mixture_pruning='mixture': a rule whose largest centred contribution over the training samples is at mostmixture_prune_thresholdis deleted, so a rule that only suppresses some classes stays;'winning_rule'prunes as a winning-rule model). Pickling keeps the weights. Off by default: the winning-rule path, its objective and every seeded fit are unchanged (docs/source/rule_mixture.rst)Regression:
BaseFuzzyRulesRegressor(unique_antecedents=True)keeps only the first of several rules that share the same antecedents. The genetic search often fills part of thenRulesbudget with such repeats, which in additive mode act as one rule with the mean consequent and in sufficient mode never speak. The option applies to the NumPy and PyTorch objectives and to the fitted rule base. It is off by default and then leaves every objective value, seeded fit and prediction unchangedPartitions from breakpoints:
utils.construct_breakpoint_partitionbuilds a Type-1 trapezoidal variable from user-given band boundaries (for example the official bands of an index), with shoulders at the ends of the domain and a linear crossover of a chosen width around each boundary, so rules can use a domain vocabulary instead of quantile termsPattern stability: rule-set stability diagnostics for classification rule bases.
pattern_stabilizer.rule_set_stabilityruns the existing resampled fits, which must share theirlinguistic_variables, and returns the selection frequency of each rule (identified by its sorted(variable, term)pairs and class), the pairwise Jaccard of the rule sets (mean, sd, min, max) and, givenpi, the consensus rules selected in at least that share of the fits. The pure functionsrule_keys,selection_frequencies,pairwise_jaccard,consensus_keys,check_shared_variablesandrule_set_stability_summarywork on any list ofMasterRuleBase, andconsensus_rule_basebuilds a rule base from consensus keys with the dominance scores recomputed on the given data. A frequency is a count of fits, not a probability. Existing methods and outputs are unchangedPruning tolerance:
MasterRuleBase.pruning_tolerancerecords the tolerance of the lastpurge_rulescall, so a fitted or stored model says which dominance-score threshold produced its rules (Noneif it was never purged). Fitted classifiers carry theirtolerance;copyand pickling keep it. The text format ofpersistencedoes not store itTraining sets too large for memory:
BaseFuzzyRulesClassifier(batch_size=n)(also afitargument) computes each candidate’s firing strengths forntraining samples at a time instead of all at once. Every candidate is still scored on all the samples and gets exactly the same score, so seeded fits are identical with and without it: per-rule sums are added in NumPy’s own order, which is checked when the fit starts. On 2,000,000 samples with 30 rules the peak memory of scoring a Type-1 candidate fell from about 1,000 MB to 95 MB (batch_size=100_000) for 8-16% more time. Needs the built-in loss and Type-1 or interval Type-2 sets; population batching and the GPU objective stay off while it streamsGrowing training subset:
BaseFuzzyRulesClassifier(initial_data_fraction=x)(also afitargument) scores the first generation of the pymoo search on a sharexof the training samples and grows it linearly, on stratified subsets that each hold the previous one, to all of them byfull_data_atof the generations (half by default). Candidates keep the scores of the subsets they were scored on until the data is complete; the population is then re-scored on every sample, and the result and early stopping only compare full-data scores. Off by default, since it changes seeded fits
Changed#
Smaller fitted models:
optimization_result_of genetic classifiers and regressors no longer keeps pymoo’s problem, which held the training samples and their memberships (about 200 bytes per row for a regressor), so pickled models no longer grow with the training set: a regressor fitted on 20,000 rows went from 4.2 MB to 16 kB. The population, evaluator counters, best solution andperformance/performance_are kept; onlyoptimization_result_['algorithm'].problem(and['res']) is nowNone. Predictions and fitted rules are unchanged. A classifier still stores its training matrix inXandeval_performanceSamples that fire no rule: with
allow_unknown=False(the default) a sample whose association degrees are all 0 took the class of the first rule (the argmax of an all-zero row), had winning rule 0 inexplainable_predict, and counted as a win of that rule when the genetic search computed rule accuracies for pruning. It is now won by no rule (winning rule -1, association degree 0) and predicted as the most frequent class of the training data, both at prediction and in every evaluator of the genetic objective, andpredict_probagives it the training class distribution instead of a uniform one. Fitted rule bases keep that distribution inMasterRuleBase.class_priors;copyand pickling keep it, the text format ofpersistencedoes not, and a rule base without it falls back to consequent 0.allow_unknown=Truestill predicts -1 (or'Unknown'). Seeded fits on data with uncovered samples change
Removed#
Temporal fuzzy sets: the
temporalmodule (temporalFS,temporalFuzzyVariable,temporalMasterRuleBase,TemporalFuzzyRulesClassifier,eval_temporal_fuzzy_modeland theTMP_FUZZY_SETSandNEW_FUZZY_SETSaliases), theFUZZY_SETSmemberstemporal,temporal_t2andtemporal_gt2, and theutilshelpers that built temporal variables and split data by time (construct_conditional_frequencies,classify_temp,assign_time,create_tempVariables,create_multi_tempVariables,temporal_cutsandtemporal_assemble).evalRuleBaseloses itstime_momentsargument, soprecomputed_truthis now its fourth parameter. Objects pickled with temporal sets no longer load
Fixed#
Explained predictions:
explainable_predictreturned the largest rule firing strength inassociation_degreeinstead of the association degree of the winning rule (firing strength times its score or weight, ascompute_association_degreesreports). The confidence interval, which is scaled by that degree, changes with it. The degree is now always a(n_samples, 1)column; for interval type-2 and general type-2 rule bases it was an(n_samples, 2)array of interval boundsGenetic classifier: with partitions of different sizes, the term gene of rule slot
jwas bounded by the term count of featurej, although the slot may hold any feature. A feature with more terms than the firstnAntsfeatures could never use its extra terms. Every term gene is now bounded by the largest partition, and the decoders map a gene onto the terms of the feature the slot holds (see the next entry). With equal term counts the bounds, searches and results are bit-for-bit unchanged; with unequal counts the search space and so seeded results changeGenetic classifier: with partitions of different sizes, a term gene above the term count of the feature its slot holds was clipped to that feature’s last term, so under uniform sampling the last term of every smaller variable was over-represented (with genes 0 to 4, the last of three terms got 3 of 5 values and the last of four terms got 2 of 5, against 1 of 5 for the rest). A gene
gnow selects term(g * n) // Mof a variable withnterms, whereMis the largest term count: the map is order preserving, reaches every term, gives each termfloor(M / n)orceil(M / n)gene values and is the identity whenn == M. The object decoder, the array and population evaluators, the PyTorch objective andencode_rulebase(which now writes the first gene of each term) use it. With equal term counts the decoding, searches and results are bit-for-bit unchanged; with unequal counts seeded results change again before any release. A gene beyond the bound is still clipped to the last term
[3.3.1] - 2026-10-26#
Changed#
Packaging: the metadata declares the license as the SPDX expression
AGPL-3.0-or-laterand ships theLICENSEfile, replacing the deprecated license table and classifier. Building from source needs setuptools 77 or later
Fixed#
Pickling: genetic classifiers fitted with the pymoo backend load with
picklein a new process. They keep pymoo’s algorithm, whose problem is aPymooProblemWrapper, and that class was built only on first use, so loading failed withAttributeErroruntil something else had built it
[3.3.0] - 2026-10-02#
Added#
Pareto search:
BaseFuzzyRulesClassifier(algorithm='nsga2')runs pymoo’s NSGA-II on two objectives, the macro F1 with the class-coverage penalty and the share of conditions used, and keeps the Pareto front inpareto_front_.fitselects its most accurate solution andselect_pareto_solutionswitches to another. On 61 KEEL datasets, in a prototype comparison with the MCC objective, the most accurate NSGA-II solution had 46% fewer conditions and 37% fewer rules than the genetic algorithm’s, for 0.010 lower test accuracy. It needs the pymoo backend and the built-in loss, and also selects from candidate rules
Changed#
Genetic objective: the search maximizes the macro F1 of the pruned rule base on the training data instead of its Matthews correlation coefficient, minus two small penalties:
betatimes the share of classes without rules (default 0.05) andalphatimes the share of the possible antecedent conditions,nRules * nAnts, that the rule base uses (default 0.03).reparametrize_loss(alpha, beta)sets these two weights; the rule-length and effective-rule terms it used to add are gone. On the 43 KEEL datasets with at most 2,500 samples, optimizing macro F1 instead of MCC raised the mean test macro F1 by 0.020 and halved how often a class was left without rules, while the mean test MCC fell by 0.018. With the default penalties, rule bases on the same datasets had 21% fewer conditions and 14% fewer rules than without them, at the same test macro F1. Rule selection from mined candidates (fitwithcandidate_rules) optimizes the same objective and now prunes rules during the search. Seeded fits, fitted models andperformancediffer from earlier versions, and a rule base without rules scores-betainstead of 0Tournament selection: the pymoo backend runs tournaments of
tournament_sizecandidates (default 3). pymoo’s GA ignored the setting and always ran binary tournaments, so seeded fits of the classifier and of the regressor, which asks for tournaments of 3, change. Ties go to the first candidate of a tournament, whose candidates are drawn at random
Fixed#
The core concepts guide described a multi-objective search and a two-stage workflow through functions that do not exist; it now shows the objective,
reparametrize_lossand rule selection throughfitThe extending guide named a
new_lossmethod; it iscustomized_loss
[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