Example 15: ANFIS on the sinc surface¶
A grid ANFIS learns the two-dimensional sinc surface with Jang's hybrid rule, then exports to a Sugeno system.
Source¶
examples/15_anfis_sinc.py
"""Grid ANFIS learns the 2-D sinc surface with Jang's hybrid rule, then exports to Sugeno."""
import math
from bulanik.anfis import ANFIS
def sinc(t):
return 1.0 if t == 0 else math.sin(t) / t
# 11 x 11 grid over [-10, 10]^2, z = sinc(x) * sinc(y)
grid = [-10 + 2 * k for k in range(11)]
X = [[x, y] for x in grid for y in grid]
z = [sinc(x) * sinc(y) for x, y in X]
anfis = ANFIS(2, 4) # 16 rules, ranges taken from the data
history = anfis.fit(X, z, epochs=30, method="hybrid", lr=0.01)
final = history[-1]
print(f"epoch 1 RMSE {history[0]:.4f}")
print(f"final RMSE {final:.4f}")
assert final < 0.1 # prototype: 0.0926
# on this data, the training RMSE never gets worse after the first epoch
assert all(b <= a + 1e-9 for a, b in zip(history[1:], history[2:]))
# the trained network as a plain first-order Sugeno system (product AND)
fis = anfis.to_sugeno(["x", "y"], output_name="z")
same = fis.evaluate({"x": 1.5, "y": -2.5})["z"]
assert math.isclose(same, anfis.predict([[1.5, -2.5]])[0], rel_tol=0, abs_tol=1e-12)
print(f"Sugeno export z(1.5, -2.5) = {same:.4f} ({len(fis.rules)} rules)")
Output¶
Run when this page is built:
epoch 1 RMSE 0.0926
final RMSE 0.0926
Sugeno export z(1.5, -2.5) = 0.2037 (16 rules)
What to notice¶
- The hybrid rule solves the consequents by least squares and updates the premises by gradient descent.
-
to_sugenoexports the trained model as an ordinary SugenoFIS with one rule per combination of input terms (16 here). -
The least-squares step solves the consequents in epoch 1; the premises barely move at
lr=0.01, so the RMSE stays flat after that.
Go further¶
- Guide: ANFIS
- API:
bulanik.anfis
Run it yourself: python examples/15_anfis_sinc.py.