A first model with ANFIS Toolbox
Every block on this page can be run here: press [run]. They share one
Python session, so run them in order. On your own machine the only
difference is how the library gets installed:
pip install anfis-toolbox
Regression
The target is a bowl, , sampled at 200 random points. It is a good first test because no single linear model fits it, but a handful of local linear models, blended smoothly, do.
import micropip
await micropip.install("anfis-toolbox") # browser only
import numpy as np
from anfis_toolbox import ANFISRegressor
rng = np.random.default_rng(0)
X = rng.uniform(-2, 2, (200, 2))
y = X[:, 0] ** 2 + X[:, 1] ** 2
model = ANFISRegressor()
model.fit(X, y)
print("R2 on the training data:", round(model.score(X, y), 4))
print("f(1, 1) and f(0, 0):", model.predict(np.array([[1.0, 1.0], [0.0, 0.0]])).round(3))
The true values at those two points are 2 and 0. With the defaults the model gets close to both, and an near 1.
That is the whole workflow: build the estimator, fit, then predict or
score. The names and the shapes of the arrays are the ones scikit-learn
uses.
Classification
Two clouds of points, one around and one around :
import micropip
await micropip.install("anfis-toolbox") # browser only
import numpy as np
from anfis_toolbox import ANFISClassifier
rng = np.random.default_rng(0)
X = np.r_[rng.normal(-1, 0.3, (50, 2)), rng.normal(1, 0.3, (50, 2))]
y = np.r_[np.zeros(50, int), np.ones(50, int)]
clf = ANFISClassifier(epochs=200, learning_rate=0.05, random_state=0)
clf.fit(X, y)
print("accuracy:", clf.score(X, y))
print("class of (-1, -1) and (1, 1):", clf.predict(np.array([[-1.0, -1.0], [1.0, 1.0]])))
The classifier is trained by gradient descent alone, so it is more sensitive to its settings than the regressor. Three arguments do the work here:
| Argument | Why it is set |
|---|---|
epochs |
more passes over the data than the default |
learning_rate |
a larger step, so those passes get somewhere |
random_state |
fixes the random starting point, so the run is repeatable |
Warning
With every argument left at its default, this same example sometimes ends
far from a good answer, depending on the random start. If a classifier
scores poorly, raise epochs and learning_rate before concluding that
the model does not fit the data.
What you can change
The fuzzy sets. The library has thirteen membership function families. Smooth ones, such as Gaussian and bell shapes, are the usual choice because their gradients are well behaved. Triangular and trapezoidal shapes are easier to explain to someone outside the field.
| Family | Class |
|---|---|
| Gaussian, two-sided Gaussian | GaussianMF, Gaussian2MF |
| Bell | BellMF |
| Triangular, trapezoidal | TriangularMF, TrapezoidalMF |
| Sigmoidal and combinations | SigmoidalMF, DiffSigmoidalMF, ProdSigmoidalMF |
| S and Z shapes | SShapedMF, LinSShapedMF, ZShapedMF, LinZShapedMF |
| Pi shape | PiMF |
The trainer. Training is separate from the model, so the same network can be fitted in different ways.
| Trainer | In short |
|---|---|
| Hybrid SGD + OLS | gradient descent on the premises, least squares on the consequents |
| Hybrid Adam + OLS | the same, with Adam doing the gradient part |
| SGD, Adam, RMSProp | gradient descent on every parameter |
| PSO | particle swarm: a population-based search, no gradients |
Why the hybrid versions are the default choice is explained in How ANFIS works.
Where the fuzzy sets start. They can be placed on a grid, at random, or by fuzzy c-means clustering of the data.
The exact arguments for all three are in the documentation.
When to reach for something else
ANFIS builds its rules from combinations of fuzzy sets, one membership per input in every rule. That scales well to a handful of inputs and badly to hundreds. For wide data, see highFIS.