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, withpredict,predict_proba,score,aggregation="max"|"sum"and an explicit reject option (on_no_rule="none"). Learned from data withchi(Chi, Yuen & Pedrycz), and exposed to scikit-learn asChiClassifier/FuzzySystemClassifier. - Rule-base auditing (
fuzzytool.audit):auditfinds contradictions, duplicates, dead rules, unused terms, indistinguishable terms, holes in an input partition and gaps in coverage;pruneremoves the rules that carry no information;interpretabilityreports the readability metrics usually quoted alongside accuracy. Works on every engine. - A text syntax for rules (
fuzzytool.dsl):parse_ruleandsystem.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, withWITH <weight>and quoted names. - Shared engine behavior (
RuleBase): every engine now exposesfiring,explain,summary,input_variables,output_variablesandrule_from_text.explainmoved 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, siximplication_relationkinds,transitive_closureand 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_tskandcmeans_tskbuild 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/zmfare 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_COMPLEMENTSregistry withget_complement, and the non-standardsugeno_complement/yager_complement. - New defuzzifiers:
wtaver/height(weighted average) andcoa(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) andnie_tan(closed-form approximation), selectable asIT2Mamdani(reducer="eiasc"). Variableimprovements:shoulders=Truefor a complete partition whose outermost terms saturate at the edges of the universe, andfuzzify(x)returning the degree of every term.- Custom membership functions can now be serialized via
membership.register(andregister_factoryfor factory-built shapes). - ANFIS:
partition="cluster"(one rule per fuzzy c-means cluster; 42x faster with 24x fewer rules on a 5-input problem),ridgeregularization,tol/patienceearly stopping, a guard against an accidentally enormous grid partition, andto_tsk()to export a trained model as a plain, auditableTSKsystem. Tsukamoto.predictfor batch inference, andpredict/on_no_rule/complement/_specon 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, aloan_decisionexample, 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 termatoms 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_intervaltake new keyword-onlycomplementandcachearguments (both optional; existing calls are unaffected). Mamdani.predictnow chunks, processingchunk_size=4096samples per block by default, so a large batch no longer allocates an(n_samples, resolution)array in one go. Results are identical;chunk_size=Nonerestores the old behavior.- Serialization covers every engine — Mamdani, TSK, Tsukamoto,
FuzzyClassifier,IT2Mamdani,IT2TSK— and the file now records aformat_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_mfPython loop; the cluster partition defaults toridge=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 withcross_val_score,GridSearchCVandis_classifieron scikit-learn 1.6+. centroid_it2accepts 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 aWeakKeyDictionarykeyed by the membership function, matching the fix already applied toMamdani. s_hamacheroverflowed 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.typedmarker — the package now ships its inline type hints (PEP 561), so downstreammypy/pyrighttype-check againstfuzzytool.- Unified
on_no_rulepolicy onMamdani,TSKandTsukamoto: choose what a call returns when no rule fires —"nan","raise", or (Mamdani only)"mid"(midpoint of the output universe). Applied identically by__call__andpredict, and round-tripped throughsave/load. - Batch defuzzifiers
centroid_batch/bisector_batch(+get_batch_defuzzifier) infuzzytool.defuzz.
Changed¶
Mamdani.predictis 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__andTSK.predictare now consistent when no rule fires: both followon_no_rule(default"nan"). Previously__call__raised whilepredictreturnednan. Passon_no_rule="raise"to restore the old scalar behavior.Tsukamotolikewise defaults to"nan"instead of raising.Mamdani's consequent-shape cache is now aWeakKeyDictionarykeyed by the membership-function object: replaced terms drop out automatically (no unbounded growth) and there is no risk of anid()being reused after garbage collection.- Package metadata: development status promoted to Beta.
[0.5.1] - 2026-07-07¶
Fixed¶
sigmoidmembership function is now numerically stable at extreme arguments:expis only ever applied to non-positive values, so large inputs no longer trigger an overflowRuntimeWarning(they saturate cleanly to 0/1). Output is unchanged in the numerically safe range.
Changed¶
Mamdanicaches 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__/predictruns are faster; results are identical.- Internal cleanup: shared implication logic between
Mamdani.__call__andMamdani.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]):tunefits 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'sPsoResult.
Changed¶
- Shared membership-function tuning helpers (
sanitize_mf_params,tunable_terms,MF_PENALTY) moved tofuzzytool.integrations._utiland 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]):Fuzzifiertransformer (crisp → membership-degree features),WangMendelRegressor,FuzzySystemRegressor. - PyTorch (
[torch]):FuzzyLayer, a differentiable first-order TSKnn.Moduletrainable by autograd and composable into a network. - SciPy (
[scipy]):tune, fitting a system's membership-function parameters to data viascipy.optimize.least_squares. - Optuna (
[optuna]):suggest_inference_spec,suggest_anfis, and a ready-madetune_anfisstudy. - Joblib / Dask (
[parallel],[dask]):parallel_predict,multi_start_cmeans,dask_predict. - LLM agents (
[agents]):explain(crisp output + fired rules) andinference_tool(a LangChainStructuredTool). - 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) andfuzzytool.mcdm(fuzzy_topsis,fuzzy_ahp). - Rule learning:
wang_mendelgenerates a Mamdani rule base from data. - Tsukamoto inference (
fuzzytool.inference.Tsukamoto) with monotonic consequents; added invertibleramp_up/ramp_downmembership functions and aninverseonsigmoid. - Batch inference:
Mamdani.predict/TSK.predictevaluate array-valued inputs in a vectorized pass. - Serialization:
fz.save/fz.load(JSON) for Mamdani/TSK systems, plusto_dict/from_dicton 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.jsonfor 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, withfit/smoothfor 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_clustersanddatasets.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) andIT2TSKengines.- 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.