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=True on BaseFuzzyRulesClassifier (winning-rule and mixture inference, also with mixture_search) and BaseFuzzyRulesRegressor (and on FitRuleBase and FitRuleBaseRegression) lets a rule state x IS at least t or x IS at most t over the terms of a variable, ordered as listed from low to high, besides a single term. A variable with n terms offers the n single terms plus at least t_j and at most t_j for j = 1 ... n - 2 (3n - 4 conditions; the vacuous at least t_0 and the duplicates of a single term are not offered). The membership is the bounded sum min(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 and candidate_rules are 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 print IS 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_latex and the pattern_stability rule 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_conditions also accepts a collection of features (names or indexes) that get at least / at most while the others keep single terms, for example to leave a cyclic clock variable out. The new compound_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 as Condition(operator='any_of', terms=..., name=...) and round-trip through the rule and variable text and pickle. Same estimators; refused with candidate_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 is b_c + sum_r W[r, c] * firing_r and 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_mixture fits them for the rules of an existing model; mixture_scores, mixture_contributions and print_mixture (each rule with its weight per class, its strongest class and the biases) read them; predict_proba returns the softmax of the scores, the probabilities of a fitted model, not calibrated ones. mixture_search=True also 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 most mixture_prune_threshold is 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 the nRules budget 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 unchanged

  • Partitions from breakpoints: utils.construct_breakpoint_partition builds 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 terms

  • Pattern stability: rule-set stability diagnostics for classification rule bases. pattern_stabilizer.rule_set_stability runs the existing resampled fits, which must share their linguistic_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, given pi, the consensus rules selected in at least that share of the fits. The pure functions rule_keys, selection_frequencies, pairwise_jaccard, consensus_keys, check_shared_variables and rule_set_stability_summary work on any list of MasterRuleBase, and consensus_rule_base builds 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 unchanged

  • Pruning tolerance: MasterRuleBase.pruning_tolerance records the tolerance of the last purge_rules call, so a fitted or stored model says which dominance-score threshold produced its rules (None if it was never purged). Fitted classifiers carry their tolerance; copy and pickling keep it. The text format of persistence does not store it

  • Training sets too large for memory: BaseFuzzyRulesClassifier(batch_size=n) (also a fit argument) computes each candidate’s firing strengths for n training 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 streams

  • Growing training subset: BaseFuzzyRulesClassifier(initial_data_fraction=x) (also a fit argument) scores the first generation of the pymoo search on a share x of the training samples and grows it linearly, on stratified subsets that each hold the previous one, to all of them by full_data_at of 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 and performance/performance_ are kept; only optimization_result_['algorithm'].problem (and ['res']) is now None. Predictions and fitted rules are unchanged. A classifier still stores its training matrix in X and eval_performance

  • Samples 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 in explainable_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, and predict_proba gives it the training class distribution instead of a uniform one. Fitted rule bases keep that distribution in MasterRuleBase.class_priors; copy and pickling keep it, the text format of persistence does not, and a rule base without it falls back to consequent 0. allow_unknown=True still predicts -1 (or 'Unknown'). Seeded fits on data with uncovered samples change

Removed#

  • Temporal fuzzy sets: the temporal module (temporalFS, temporalFuzzyVariable, temporalMasterRuleBase, TemporalFuzzyRulesClassifier, eval_temporal_fuzzy_model and the TMP_FUZZY_SETS and NEW_FUZZY_SETS aliases), the FUZZY_SETS members temporal, temporal_t2 and temporal_gt2, and the utils helpers that built temporal variables and split data by time (construct_conditional_frequencies, classify_temp, assign_time, create_tempVariables, create_multi_tempVariables, temporal_cuts and temporal_assemble). evalRuleBase loses its time_moments argument, so precomputed_truth is now its fourth parameter. Objects pickled with temporal sets no longer load

Fixed#

  • Explained predictions: explainable_predict returned the largest rule firing strength in association_degree instead of the association degree of the winning rule (firing strength times its score or weight, as compute_association_degrees reports). 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 bounds

  • Genetic classifier: with partitions of different sizes, the term gene of rule slot j was bounded by the term count of feature j, although the slot may hold any feature. A feature with more terms than the first nAnts features 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 change

  • Genetic 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 g now selects term (g * n) // M of a variable with n terms, where M is the largest term count: the map is order preserving, reaches every term, gives each term floor(M / n) or ceil(M / n) gene values and is the identity when n == M. The object decoder, the array and population evaluators, the PyTorch objective and encode_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-later and ships the LICENSE file, 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 pickle in a new process. They keep pymoo’s algorithm, whose problem is a PymooProblemWrapper, and that class was built only on first use, so loading failed with AttributeError until 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 in pareto_front_. fit selects its most accurate solution and select_pareto_solution switches 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: beta times the share of classes without rules (default 0.05) and alpha times 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 (fit with candidate_rules) optimizes the same objective and now prunes rules during the search. Seeded fits, fitted models and performance differ from earlier versions, and a rule base without rules scores -beta instead of 0

  • Tournament selection: the pymoo backend runs tournaments of tournament_size candidates (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_loss and rule selection through fit

  • The extending guide named a new_loss method; it is customized_loss

[3.2.0] - 2026-09-16#

Changed#

  • Rule text without statistics loads: the WITH clause of a printed rule lists whichever of DS, ACC and WGHT the rule has, and load_fuzzy_rules accepts any subset of them, a missing WITH clause, and ignores a THEN clause, so rules printed before evaluation round-trip

  • RuleMineClassifier and RuleFineTuneClassifier take n_gen, pop_size, patience and random_state in their constructors, with the same fit-time overrides as BaseFuzzyRulesClassifier

  • Lazy package import: import ex_fuzzy no 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 milliseconds

  • Docstrings 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.py refreshes their outputs

  • Search settings are constructor parameters: n_gen, pop_size, patience, min_delta, random_state, var_prob, sbx_eta, mutation_eta and tournament_size can be given to BaseFuzzyRulesClassifier, so clone and GridSearchCV see them. Passing them to fit overrides them for that fit only, as before

  • ds_mode accepts the names 'dominance', 'unweighted' and 'optimized' besides 0, 1 and 2, and rejects anything else in the classifier, FitRuleBase and MasterRuleBase

  • explainable_predict returns an ExplainedPrediction named tuple with the fields prediction, winning_rule, association_degree and confidence_interval; it still unpacks as a four-tuple

  • Conformal 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 label

  • RuleMineClassifier passes its nAnts to the inner classifier

  • The runner parameter documents that threads disable the fit-local caches, so serial fits are usually faster

  • Rule 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.toml with requires-python >= 3.10, the AGPL license, and classifiers for Python 3.10 to 3.13; setup.py only builds the optional native FERL extension. CI tests Python 3.10 to 3.13 and runs the EvoX backend tests on CPU

  • Import 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.warn instead of printing; incoherent interval fuzzy sets, missing dominance scores, empty rule lists and temporal sets without a fixed time raise ValueError instead of AssertionError; FuzzyEvaluator.get_metric raises instead of returning an error string

  • Names: MasterRuleBase.compute_firing_strengths and BaseFuzzyRulesClassifier.reparametrize_loss are the spelled names; the former misspellings remain as deprecated aliases

  • Docs: 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 of ex_fuzzy/ex_fuzzy/, and the outer re-export shim is gone. Modules import each other with relative imports only, without try/except ImportError fallbacks, and the tests, benchmarks and demos import through the package. FUZZY_SETS uses the default enum equality and hashing again, since every module now exists once per process. Reinstall with pip install -e . after updating a checkout

  • Type-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_score and Pipeline work. fit returns the classifier and sets classes_ and n_features_in_. Labels are encoded as consequent indexes for the search and predict returns the labels the classifier was fitted with, so score works with string labels and integer labels need not be 0..n_classes-1. Samples with no firing rule predict -1 for numeric labels and 'Unknown' otherwise. Classifiers built from precomputed rules still predict consequent indexes. The backend parameter also accepts a backend instance

  • Prediction computes memberships and firing once: a MasterRuleBase evaluates 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 arrays

  • Rule evaluation computes firing once: the evalRuleBase weight, accuracy and metric methods share one firing computation per call instead of recomputing it for support, confidence and dominance. Results are unchanged

  • Rule identity: RuleSimple equality 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 changes ds_mode=2 searches whose candidates repeat an antecedent pattern in one class; the array evaluator applies the same rule

  • RuleMineClassifier and RuleFineTuneClassifier are scikit-learn estimators: constructor arguments are stored under their own names and the inner classifiers are built when fit is called, so clone and cross-validation work. fit sets classes_ and n_features_in_, and predict returns the fitted labels. The fl_classifier, fl_classifier1 and fl_classifier2 attributes remain available after fit

  • ConformalFuzzyClassifier takes the wrapped classifier as estimator (clf_or_nRules is still accepted), which get_params and clone see; clf remains as an alias. fit now also fits a wrapped classifier that has not been fitted yet

  • TemporalFuzzyRulesClassifier gained predict(X, time_moments), and its fit returns the classifier

Fixed#

  • FERL failed 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 of classes_

  • 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_type was calibrated with, so the entropy sets did not reach their coverage; prediction now uses the calibrated score type

  • Missing or infinite feature values were silently assigned class 0, because NaN firing strengths made argmax pick the first rule, and gave NaN probabilities. fit and the prediction methods now reject them with a ValueError naming the columns

  • Conformal calibration crashed with string labels and mis-indexed integer labels that do not start at 0

  • Categorical fuzzy sets now define domain and membership_parameters as None, so fuzzyVariable.domain() no longer raises for a categorical variable, and membership computation no longer relies on a swallowed exception to skip the domain clipping

  • load_fuzzy_rules parses the IF, IS, AND and WITH keywords as whole words, so variable and label names containing them (for example DISTANCE or WITHIN) load correctly, and rule text without Rules for headers loads as a single rule base instead of failing

  • multiclass_mine_rulebase pruned 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 built

  • RuleMineClassifier mined its candidate rules on freshly built partitions and ignored the linguistic_variables it was given; it now mines on the partitions it predicts with

  • BaseFuzzyRulesClassifier.score returned 0 for string labels because predict returned class indexes

  • General Type-2 rule bases with ds_mode=2 failed 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, FitRuleBaseRegression and ExploreRuleBases no longer subclass pymoo’s Problem; the PyMoo backend and the temporal classifier wrap them when they run. To pass one to pymoo directly, wrap it with evolutionary_backends.as_pymoo_problem

Fixed#

  • The batched population evaluator added the alpha size penalty when every surviving rule scored exactly the tolerance; the reference adds none

  • Pattern stability usage charts show “No variable usage” instead of failing when no variable is used

Removed#

  • The unused NetworkX rule-graph visualization and viz installation 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) from fuzzy_greedy_tree and reproduces its trees and predictions

  • FERL evidence: The "mixture" combination rule, now shared with DeepFERL through a common evidence module

  • FuzzyRulesClassifier: 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 fit arguments 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 enumeration

  • Fuzzy 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 status

  • EvoX 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.FERL estimator

  • FERL validation: split_mode="learned" with target_metric="purity" now raises ValueError instead of silently ignoring the learned splits, and an unknown target_metric is rejected

  • FERL evidence: An unknown rule in predict_ds and related methods now raises ValueError instead of silently using Dempster’s rule

  • Rule mining: rule_mining accepts NumPy arrays as well as DataFrames, reading columns by position, so RuleMineClassifier no longer requires a DataFrame

  • RuleFineTuneClassifier: Builds partitions before mining when none are given, and predicts with its second-stage model; both steps previously failed. fit returns the estimator for all rule-mining classifiers

  • Evolutionary 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