Developer Guide¶
Welcome to the ANFIS Toolbox developer guide. This document is intended for contributors who want to understand the architecture, extend the library, or work on the documentation and examples. If you are looking for the user-facing API reference, consult the generated MkDocs site or the module docstrings.
Project Goals¶
- Provide a batteries-included Adaptive Neuro-Fuzzy Inference System (ANFIS) implementation in Python.
- Offer high-level estimators (
ANFISRegressor,ANFISClassifier) that feel familiar to scikit-learn users while remaining dependency-free. - Support a wide range of membership function families and training regimes.
- Ship with reproducible examples, thorough tests, and easy-to-read docs.
Repository Layout¶
anfis_toolbox/
├── model.py # Low-level ANFIS graph (layers, forward passes)
├── regressor.py # High-level regression estimator facade
├── classifier.py # High-level classification estimator facade
├── membership.py # Membership function implementations and helpers
├── builders.py # Utilities that assemble models from configuration
├── optim/ # Optimizer and trainer implementations
├── metrics.py # Regression and classification metric utilities
├── losses.py # Loss definitions shared by optimizers
└── estimator_utils.py # Mixins, validation helpers, sklearn-like machinery
docs/ # MkDocs pages and reference material
docs/examples/ # Notebook-based walkthroughs
tests/ # Pytest suite with full coverage
High-Level Architecture¶
- Estimators (
ANFISRegressor,ANFISClassifier) expose a drop-in API withfit,predict,predict_proba(classifier),evaluate, and serialization helpers (save,load). They orchestrate membership generation, rule configuration, optimizer instantiation, and evaluation. - Builders translate estimator configuration into the low-level model by creating membership functions, calculating rule combinations, and producing an object the trainers can consume.
- Low-level model (
model.ANFIS,model.TSKANFISClassifier) implements the forward pass, rule firing strengths, normalization, and consequent evaluation. - Optimizers (
optim.*) encapsulate training strategies such as Hybrid (OLS + gradient descent), Adam, RMSProp, SGD, and PSO. Each trainer accepts a low-level model along with data and optional validation splits. - Utilities provide common infrastructure:
estimator_utilsfor mixins and input validation,metricsfor reporting,lossesfor objective functions, andlogging_configfor opt-in training logs.
The diagram below illustrates the runtime flow:
User code -> ANFISRegressor.fit ------------------------------.
| |
v |
Membership config Optimizer selection |
| | |
v v |
builders.ANFISBuilder optim.<Trainer> |
| | |
'------> model.ANFIS <-------------'
|
v
Training loop
Implementation and Architecture¶
ANFIS Toolbox implements the flow above through a set of small, composable modules. The public estimators in
anfis_toolbox.regressor and anfis_toolbox.classifier act as façades that translate user-friendly configuration into the
lower-level computational graph defined in anfis_toolbox.model and anfis_toolbox.layers. Supporting modules such as
builders, config, membership, losses, and optim provide reusable building blocks that keep concerns separated.
Core execution pipeline (anfis_toolbox.model and anfis_toolbox.layers)¶
- Fuzzification sits in
MembershipLayer, which wraps concrete membership-function objects. The layer caches the raw inputs and per-function activations so that the backward pass can recover gradients without re-evaluating membership functions. - Rule evaluation is performed by
RuleLayer. It receives the membership lattice, expands (or filters) the Cartesian product of membership indices, and computes rule firing strengths using the configured T-norm (product). The layer also propagates derivatives back to the membership layer by reusing the cached activations. - Normalization is handled by
NormalizationLayer, which performs numerically stable weight normalisation and exposes a Jacobian-vector product in itsbackwardmethod so that trainers can work directly with batched gradients. - Consequents are implemented by
ConsequentLayer(regression) andClassificationConsequentLayer(classification). Both layers augment the input batch with biases, compute per-rule linear consequents, and aggregate them using the normalised firing strengths. The classification flavour maps the weighted outputs to logits, and integrates with the built-in softmax helper inmetrics.py. - Model orchestration happens in
TSKANFISandTSKANFISClassifier. Each model wires the layers, exposes forward and backward passes, persists gradient buffers, and implementsget_parameters,set_parameters, andupdate_parametersso optimizers can operate without needing to understand layer internals.
Builder and configuration layer (builders.py, config.py)¶
ANFISBuilderencapsulates membership-function synthesis. It centralises creation strategies (grid, FCM, random) and maps human-readable names ("gaussian","bell") to concrete membership classes. The builder also normalises explicit rule sets viaset_rulesand exposes abuild()factory that returns a fully wiredTSKANFISinstance.ANFISConfigprovides a serialisable description of inputs and training defaults. It can emit builders, write JSON configurations, and round-trip throughANFISModelManageralongside pickled models. This enables reproducible deployments or experiment tracking without shipping raw Python objects.- Membership families (e.g.
GaussianMF,PiMF,DiffSigmoidalMF) live undermembership.py. Each object exposes aparameters/gradientsinterface so the layers can mutate them generically during backpropagation.
Estimator orchestration (regressor.py, classifier.py, estimator_utils.py)¶
ANFISRegressor.fitandANFISClassifier.fitdelegate input validation and reshaping to helpers inestimator_utils, ensuring NumPy arrays, pandas DataFrames, and Python iterables are handled consistently.- During fitting, estimators resolve per-input overrides through
_resolve_input_specs, instantiate anANFISBuilder, build the low-level model, select a trainer based on string aliases or explicit objects, and finally calltrainer.fit(model, X, y, **kwargs). The resulting history dictionary is cached intraining_history_for downstream inspection. - Persistence relies on the estimator mixins:
save/loadmethods serialise the estimator and underlying model withpickle, andformat_estimator_reprproduces concise__repr__output that mirrors scikit-learn conventions. - Logging hooks are opt-in through
logging_config.enable_training_logs, so verbose fits emit trainer progress while remaining silent by default.
Training infrastructure (optim/)¶
BaseTrainerdefines the contract (fit,evaluate, metric tracking) and shared utilities like batching, progress reporting, and validation scheduling.- Gradient-based trainers (
HybridTrainer,HybridAdamTrainer,AdamTrainer,RMSPropTrainer,SGDTrainer) call the model'sforward,backward,update_parameters, andreset_gradientsmethods directly. Hybrid variants alternate between closed-form least-squares updates for consequents and gradient descent for membership parameters to accelerate convergence on regression tasks. PSOTrainerdiverges from gradient descent by optimising consequent coefficients with particle swarm optimisation while refreshing membership parameters less aggressively, making it suitable for noisy or non-differentiable objectives.- All trainers populate a
TrainingHistorymapping (defined inoptim.base) that captures per-epoch losses and optional validation metrics, facilitating visualisation or early-stopping criteria implemented outside the core package.
Variants and extension points¶
- Regression vs. classification:
ANFISRegressorwrapsTSKANFIS, using mean-squared-error-style losses by default and exposing regression metrics.ANFISClassifierwrapsTSKANFISClassifier, instantiates a multi-class consequent layer, and defaults to cross-entropy losses with probability calibration viapredict_proba. - Membership variants: Users can mix automatic generation (
n_mfs,mf_type,init,overlap,margin) with explicitMembershipFunctioninstances per feature. Builders preserve the order in which inputs are added so the resulting rule indices remain deterministic. - Rule customisation: Providing
rules=[(...)]to estimators or builders prunes the Cartesian-product rule set. TheRuleLayervalidates dimensionality and membership bounds so sparsified rule bases remain consistent. - Custom trainers and losses: Passing a subclass of
BaseTraineror a callableLossFunctionlets advanced users swap in bespoke optimisation strategies. Trainers may register additional callbacks or hooks (for example, to integrate withdocs/hooks/*when rendering docs) without patching the core model. - Configuration persistence:
ANFISModelManagerties trained models to the serialised configuration extracted from the membership catalogue, enabling reproducible evaluation environments and lightweight deployment artefacts.
UML overview¶
classDiagram
direction LR
class ANFISRegressor {
+fit(X, y)
+predict(X)
+evaluate(X, y)
+save(path)
+load(path)
}
class ANFISClassifier {
+fit(X, y)
+predict(X)
+predict_proba(X)
+evaluate(X, y)
}
class ANFISBuilder {
+add_input(name, min, max, n_mfs, mf_type)
+add_input_from_data(name, data, ...)
+set_rules(rules)
+build()
}
class TSKANFIS {
+forward(X)
+backward(dL)
+fit(X, y, trainer)
+get_parameters()
}
class TSKANFISClassifier {
+forward(X)
+backward(dL)
+predict_logits(X)
+get_parameters()
}
class MembershipLayer {
+forward(X)
+backward(gradients)
}
class RuleLayer {
+forward(mu)
+backward(dL)
}
class NormalizationLayer {
+forward(weights)
+backward(dL)
}
class ConsequentLayer {
+forward(X, w)
+backward(dL)
}
class ClassificationConsequentLayer {
+forward(X, w)
+backward(dL)
}
class BaseTrainer {
<<abstract>>
+fit(model, X, y)
}
class HybridTrainer
class HybridAdamTrainer
class AdamTrainer
class RMSPropTrainer
class SGDTrainer
class PSOTrainer
ANFISRegressor --> ANFISBuilder : configures
ANFISClassifier --> ANFISBuilder : configures
ANFISBuilder --> TSKANFIS : builds
ANFISBuilder --> TSKANFISClassifier : builds
TSKANFIS --> MembershipLayer : composes
TSKANFIS --> RuleLayer
TSKANFIS --> NormalizationLayer
TSKANFIS --> ConsequentLayer
TSKANFISClassifier --> MembershipLayer
TSKANFISClassifier --> RuleLayer
TSKANFISClassifier --> NormalizationLayer
TSKANFISClassifier --> ClassificationConsequentLayer
ANFISRegressor --> BaseTrainer : selects
ANFISClassifier --> BaseTrainer : selects
BaseTrainer <|-- HybridTrainer
BaseTrainer <|-- HybridAdamTrainer
BaseTrainer <|-- AdamTrainer
BaseTrainer <|-- RMSPropTrainer
BaseTrainer <|-- SGDTrainer
BaseTrainer <|-- PSOTrainer
Working With Estimators¶
- Initialization: Provide global defaults (
n_mfs,mf_type,init,overlap,margin) plus optionalinputs_configoverrides for each input.inputs_configvalues can be dictionaries with membership parameters or explicitMembershipFunctioninstances. - Rules: By default, all membership combinations form rules. Supply
rules=[(i1, i2, ...)]to restrict to a subset of combinations. - Optimizers: Pass
optimizer="adam"(default classifier) oroptimizer="hybrid"(default regressor). You can also supply instantiated trainers or custom subclasses ofBaseTrainer. - Training:
fitaccepts NumPy arrays, array-like objects, or pandas DataFrames. Usevalidation_data=(X_val, y_val)to monitor generalization. - Evaluation:
evaluatereturns a metrics dictionary and optionally prints a nicely formatted summary. Usereturn_dict=Falseto suppress the return value. - Persistence:
saveandloadrely onpickle. Saved estimators capture fitted membership functions, rules, and optimizer state, enabling reuse.
Membership Functions¶
Membership families live in membership.py. Key points:
- Each family subclasses
MembershipFunctionand implements__call__,derivative, and metadata accessors. - Many families accept parameters such as centers, widths, slopes, or plateaus.
- Builders automatically infer parameters using grid spacing, fuzzy C-means
clustering, or random sampling depending on
init. -
Provide explicit membership functions via
inputs_configto lock down shapes, e.g.:
Training Strategies¶
Optimizers live under anfis_toolbox/optim/ and share a common interface:
BaseTrainer.fit(model, X, y, **kwargs)drives epochs, batching, shuffling, and validation.- Hybrid trainers combine gradient descent with ordinary least squares rule consequent updates, delivering fast convergence on regression tasks.
- Adam, RMSProp, and SGD offer familiar gradient-based alternatives.
- PSO provides a population-based search when gradient information is noisy.
- Trainers expose hooks for learning rate, epochs, batch size, shuffle, and optional loss overrides.
Metrics and Evaluation¶
ANFISRegressor.evaluatereports MSE, RMSE, MAE, and R² viametrics.ANFISMetrics.regression_metrics.ANFISClassifier.evaluatereports accuracy, balanced accuracy, macro/micro precision/recall/F1, and the confusion matrix.- Metrics are returned as dictionaries to simplify logging or experiment tracking.
Examples and Documentation¶
- Explore the
docs/examples/notebooks for step-by-step tutorials covering regression, classification, time series, and membership customization. - The MkDocs site (
mkdocs.yml) assembles thedocs/directory into a hosted documentation portal. Runmake docsto build locally and serve viamkdocs serve.
Development Workflow¶
- Install dependencies:
make install - Run tests:
make test - Lint:
make lint - Format (optional):
make format - Docs preview:
make docs
Tests cover membership functions, optimizers, estimators, and integration with scikit-learn-like patterns. New features should include corresponding tests.
Contributing¶
- Fork the repository and create a feature branch.
- Keep pull requests focused; tie them to an issue when possible.
- Update or add documentation (including this guide) when behavior changes.
- Ensure
make testandmake lintpass before submitting. - Include demo snippets or notebooks if the feature benefits from examples.
Thanks for contributing to ANFIS Toolbox! If you have questions, open a discussion or issue on GitHub.