Skip to content

Changelog

All notable changes to this project are documented here. The format is based on Keep a Changelog and the project adheres to Semantic Versioning.

[Unreleased]

[0.7.0] - 2026-08-19

A large release: fuzzy classification, rule-base auditing, a text rule syntax, the classical relation/measure layer, faster inference, and a scatter partition for ANFIS.

Added

  • Fuzzy classification (fuzzytool.classify): FuzzyClassifier, a rule base with class-label consequents and per-rule certainty factors, with predict, predict_proba, score, aggregation="max"|"sum" and an explicit reject option (on_no_rule="none"). Learned from data with chi (Chi, Yuen & Pedrycz), and exposed to scikit-learn as ChiClassifier / FuzzySystemClassifier.
  • Rule-base auditing (fuzzytool.audit): audit finds contradictions, duplicates, dead rules, unused terms, indistinguishable terms, holes in an input partition and gaps in coverage; prune removes the rules that carry no information; interpretability reports the readability metrics usually quoted alongside accuracy. Works on every engine.
  • A text syntax for rules (fuzzytool.dsl): parse_rule and system.rule_from_text("IF score IS poor OR dti IS high THEN premium IS high"), covering Mamdani, TSK (constant and affine consequents) and classifier consequents, with WITH <weight> and quoted names.
  • Shared engine behavior (RuleBase): every engine now exposes firing, explain, summary, input_variables, output_variables and rule_from_text. explain moved from the agents integration into the core (the integration now delegates to it) and additionally reports each rule's index and share of the total firing.
  • Fuzzy relations (fuzzytool.relations): cartesian, compose, cri (compositional rule of inference), projection, cylindrical_extension, inverse, union, intersection, six implication_relation kinds, transitive_closure and the relation-property predicates.
  • Measures on fuzzy sets (fuzzytool.measures): descriptors (support, core, alpha_cut, height, cardinality), distances (hamming, euclidean, minkowski), similarity and inclusion (jaccard, dice, subsethood, consistency) and fuzziness (fuzzy_entropy, index_of_fuzziness).
  • Scatter-partition rule learning: subtractive_clustering (Chiu), chiu_tsk and cmeans_tsk build a complete TSK system whose rule count follows the data rather than the number of inputs.
  • New membership shapes for MATLAB-toolbox parity: smf, zmf, pimf, gauss2, singleton. smf/zmf are monotonic, so they work as Tsukamoto consequents.
  • New connectives: Einstein, Hamacher, drastic and nilpotent t-/s-norms, plus the parametric Yager, Dombi and Frank families.
  • The complement (NOT) is now pluggable, like the other connectives: complement= on every engine, a _COMPLEMENTS registry with get_complement, and the non-standard sugeno_complement / yager_complement.
  • New defuzzifiers: wtaver / height (weighted average) and coa (center of the largest contiguous area, which never answers from the valley between two disjoint humps).
  • Faster type reduction: eiasc (exact, same interval as Karnik-Mendel, 6-12x faster at realistic rule-base sizes) and nie_tan (closed-form approximation), selectable as IT2Mamdani(reducer="eiasc").
  • Variable improvements: shoulders=True for a complete partition whose outermost terms saturate at the edges of the universe, and fuzzify(x) returning the degree of every term.
  • Custom membership functions can now be serialized via membership.register (and register_factory for factory-built shapes).
  • ANFIS: partition="cluster" (one rule per fuzzy c-means cluster; 42x faster with 24x fewer rules on a 5-input problem), ridge regularization, tol/patience early stopping, a guard against an accidentally enormous grid partition, and to_tsk() to export a trained model as a plain, auditable TSK system.
  • Tsukamoto.predict for batch inference, and predict / on_no_rule / complement / _spec on the interval type-2 engines.
  • wang_mendel(..., use_weights=True) weights each rule by its degree.
  • A reproducible benchmark suite (benchmarks/benchmark.py), property-based tests with Hypothesis, a loan_decision example, and guide pages for classification, auditing, rules-as-text, measures/relations and performance.

Changed

  • Antecedent evaluation is memoized per call. A rule base repeats the same variable is term atoms across many rules; each is now evaluated once per call and shared. On a 125-rule system this cut membership evaluations from 375 to 15 and made scalar inference ~8x faster. Antecedent.eval / eval_interval take new keyword-only complement and cache arguments (both optional; existing calls are unaffected).
  • Mamdani.predict now chunks, processing chunk_size=4096 samples per block by default, so a large batch no longer allocates an (n_samples, resolution) array in one go. Results are identical; chunk_size=None restores the old behavior.
  • Serialization covers every engine — Mamdani, TSK, Tsukamoto, FuzzyClassifier, IT2Mamdani, IT2TSK — and the file now records a format_version, so a file from a newer, incompatible release is rejected with a clear error instead of being misread. Files without the field are read as version 1.
  • ANFIS's premise gradient is accumulated with a single scatter-add instead of a p × n_mf Python loop; the cluster partition defaults to ridge=1e-6, without which its (necessarily overlapping) rules make the least-squares solve ill-conditioned. The grid partition keeps Jang's unregularized solve.
  • The scikit-learn estimators now provide __sklearn_tags__, so they work with cross_val_score, GridSearchCV and is_classifier on scikit-learn 1.6+.
  • centroid_it2 accepts a plain type-1 membership function, so type-1 and IT2 consequents mix as freely as antecedents already did.

Fixed

  • The interval type-2 consequent-centroid cache was keyed by id(variable), which could return a stale centroid after the variable was collected and the id reused. It is now a WeakKeyDictionary keyed by the membership function, matching the fix already applied to Mamdani.
  • s_hamacher overflowed to 2.0 for degrees a hair below 1 (found by the new property-based tests); both Hamacher connectives now guard the removable singularity with a tolerance.

[0.6.0] - 2026-07-28

Added

  • py.typed marker — the package now ships its inline type hints (PEP 561), so downstream mypy / pyright type-check against fuzzytool.
  • Unified on_no_rule policy on Mamdani, TSK and Tsukamoto: choose what a call returns when no rule fires — "nan", "raise", or (Mamdani only) "mid" (midpoint of the output universe). Applied identically by __call__ and predict, and round-tripped through save/load.
  • Batch defuzzifiers centroid_batch / bisector_batch (+ get_batch_defuzzifier) in fuzzytool.defuzz.

Changed

  • Mamdani.predict is now vectorized: when the defuzzifier has a batch form (centroid/bisector, the common cases) the per-sample Python loop is replaced by a single vectorized call. Results are unchanged.
  • TSK.__call__ and TSK.predict are now consistent when no rule fires: both follow on_no_rule (default "nan"). Previously __call__ raised while predict returned nan. Pass on_no_rule="raise" to restore the old scalar behavior. Tsukamoto likewise defaults to "nan" instead of raising.
  • Mamdani's consequent-shape cache is now a WeakKeyDictionary keyed by the membership-function object: replaced terms drop out automatically (no unbounded growth) and there is no risk of an id() being reused after garbage collection.
  • Package metadata: development status promoted to Beta.

[0.5.1] - 2026-07-07

Fixed

  • sigmoid membership function is now numerically stable at extreme arguments: exp is only ever applied to non-positive values, so large inputs no longer trigger an overflow RuntimeWarning (they saturate cleanly to 0/1). Output is unchanged in the numerically safe range.

Changed

  • Mamdani caches consequent set shapes across inference calls. A consequent term's membership over its output universe depends only on (term, universe), not on the inputs, so it is now memoized (keyed by the membership-function identity, which auto-invalidates when a term is replaced). Repeated __call__/predict runs are faster; results are identical.
  • Internal cleanup: shared implication logic between Mamdani.__call__ and Mamdani.predict, and a single mid-universe fallback helper across the defuzzifiers.

[0.5.0] - 2026-06-28

Added

  • General type-2 (GT2) fuzzy sets via the zSlices / alpha-plane representation (fuzzytool.type2.general):
  • GeneralType2MF — a GT2 set as a stack of IT2 z-slices; also exposes the overall FOU (lower/upper), so it can stand in for its IT2 footprint.
  • Constructors gt2_from_it2, gt2_gauss_uncertain_mean, gt2_scale (triangular secondary membership peaking at the principal MF).
  • GeneralType2Mamdani — inference as a z-weighted stack of IT2 Mamdani runs, reusing the Karnik-Mendel machinery.
  • centroid_gt2 — zSlices type reduction of a single GT2 set.

[0.4.0] - 2026-06-28

Added

  • turboswarm integration (fuzzytool.integrations.turboswarm, extra [turboswarm]): tune fits a system's built-in membership-function parameters to data with the sibling library's gradient-free, global Particle Swarm Optimization — the metaheuristic counterpart of the SciPy least-squares tuner. Returns turboswarm's PsoResult.

Changed

  • Shared membership-function tuning helpers (sanitize_mf_params, tunable_terms, MF_PENALTY) moved to fuzzytool.integrations._util and reused by both the SciPy and turboswarm tuners.

[0.3.0] - 2026-06-27

Added

  • Ecosystem integrations under fuzzytool.integrations.* — each behind its own extra and importing its dependency only on use, so the core stays pure NumPy:
  • pandas ([pandas]): predict_df, rules_dataframe, memberships_dataframe, components_dataframe.
  • scikit-learn ([sklearn]): Fuzzifier transformer (crisp → membership-degree features), WangMendelRegressor, FuzzySystemRegressor.
  • PyTorch ([torch]): FuzzyLayer, a differentiable first-order TSK nn.Module trainable by autograd and composable into a network.
  • SciPy ([scipy]): tune, fitting a system's membership-function parameters to data via scipy.optimize.least_squares.
  • Optuna ([optuna]): suggest_inference_spec, suggest_anfis, and a ready-made tune_anfis study.
  • Joblib / Dask ([parallel], [dask]): parallel_predict, multi_start_cmeans, dask_predict.
  • LLM agents ([agents]): explain (crisp output + fired rules) and inference_tool (a LangChain StructuredTool).
  • Tutorials section (investment-risk advisor, ANFIS, Fuzzy TOPSIS, clustering) and an Integrations guide page; rendered plots and computed results embedded throughout the docs.

[0.2.0] - 2026-06-24

Added

  • Fuzzy numbers & MCDM: fuzzytool.fuzzynum (triangular/trapezoidal numbers with arithmetic, alpha-cuts, centroid, distance, ranking) and fuzzytool.mcdm (fuzzy_topsis, fuzzy_ahp).
  • Rule learning: wang_mendel generates a Mamdani rule base from data.
  • Tsukamoto inference (fuzzytool.inference.Tsukamoto) with monotonic consequents; added invertible ramp_up / ramp_down membership functions and an inverse on sigmoid.
  • Batch inference: Mamdani.predict / TSK.predict evaluate array-valued inputs in a vectorized pass.
  • Serialization: fz.save / fz.load (JSON) for Mamdani/TSK systems, plus to_dict/from_dict on membership functions and variables.
  • scikit-learn compatibility: ANFIS.get_params / set_params.

[0.1.0] - 2026-06-24

Added

  • Core membership functions: triangular, trapezoidal, gaussian, generalized bell, sigmoid (fuzzytool.membership).
  • T-norms and s-norms (min/prod/Łukasiewicz, max/probor/Łukasiewicz), resolved by name (fuzzytool.norms).
  • Variable (linguistic variable) with auto-generated or explicit terms, and an operator-based rule-antecedent expression tree (&, |, ~).
  • Mamdani inference with configurable implication/aggregation and defuzzification (centroid, bisector, MOM/SOM/LOM).
  • Takagi-Sugeno (TSK) inference (zero- and first-order, plus callable consequents).
  • fuzzytool.viz: membership-function plots and 2-input control surfaces.
  • fuzzytool.datasets.credit_risk: the flagship example system.
  • Example notebooks (notebooks/): quickstart, interval type-2, clustering, and ANFIS/F-transform — committed executed.
  • Documentation (MkDocs Material), CI, a comparison page vs scikit-fuzzy, a citing/releasing page, and .zenodo.json for DOI archival.
  • ANFIS (fuzzytool.anfis.ANFIS): a trainable first-order Sugeno system over a grid partition, fit with Jang's hybrid scheme (least-squares consequents + gradient-descent premises). fit / predict / history_.
  • F-transform (fuzzytool.ftransform.FTransform): direct and inverse fuzzy transform over a triangular partition of unity, with fit / smooth for denoising and compression.
  • Fuzzy clustering (fuzzytool.cluster):
  • fuzzy_cmeans (Bezdek FCM), gustafson_kessel (adaptive Mahalanobis norm), possibilistic_cmeans (typicalities); all seeded for reproducibility.
  • Validity metrics: partition_coefficient, partition_entropy, xie_beni.
  • viz.plot_clusters and datasets.make_blobs.
  • Interval type-2 (IT2) support (fuzzytool.type2):
  • IT2 membership functions with a footprint of uncertainty: it2 (explicit LMF/UMF), it2_scale (height), it2_gauss_uncertain_mean, it2_gauss_uncertain_std.
  • Interval-valued antecedent evaluation (Antecedent.eval_interval); type-1 and IT2 terms can be mixed in one rule.
  • IT2Mamdani (center-of-sets type reduction) and IT2TSK engines.
  • Karnik-Mendel type reduction: km_endpoint, karnik_mendel, centroid_it2.
  • viz.plot_it2_variable (shaded FOU); datasets.credit_risk_it2.
  • Test suite covering every module.