Learning API Reference¶
The fuzzy_systems.learning module provides algorithms for automatic rule generation and system optimization:
- WangMendelLearning: Automatic rule generation from data (single-pass algorithm)
- ANFIS: Adaptive Neuro-Fuzzy Inference System (gradient-based learning)
- MamdaniLearning: Mamdani system optimization with gradients and metaheuristics
- Metaheuristics: PSO, Differential Evolution, Genetic Algorithms
WangMendelLearning¶
Automatic fuzzy rule generation using the Wang-Mendel algorithm (1992).
Reference: Wang, L. X., & Mendel, J. M. (1992). "Generating fuzzy rules by learning from examples." IEEE Transactions on Systems, Man, and Cybernetics, 22(6), 1414-1427.
Algorithm Steps¶
- Partition variable domains (use existing MFs)
- Generate candidate rules from each data sample
- Assign degree to each rule based on membership strengths
- Resolve conflicts (keep rule with highest degree)
- Create final fuzzy system with learned rules
Constructor¶
Parameters:
system(MamdaniSystem): Pre-configured system with variables and terms (NO rules yet)X(ndarray): Input data, shape(n_samples, n_features)y(ndarray): Output data, shape(n_samples,)or(n_samples, n_outputs)task(str):'auto'(detect),'regression', or'classification'(default:'auto')scale_classification(bool): Scale classification outputs to [0, 1] (default:True)verbose_init(bool): Print initialization info (default:False)
Example:
import numpy as np
from fuzzy_systems import MamdaniSystem
from fuzzy_systems.learning import WangMendelLearning
# Prepare data
X_train = np.random.uniform(0, 10, (100, 2))
y_train = np.sin(X_train[:, 0]) + np.cos(X_train[:, 1])
# Create base system (with variables and terms, NO rules)
system = MamdaniSystem()
system.add_input('x1', (0, 10))
system.add_input('x2', (0, 10))
system.add_output('y', (-2, 2))
# Add partitions (e.g., 5 terms per variable)
for var in ['x1', 'x2']:
for i in range(5):
center = i * 2.5
system.add_term(var, f'term_{i}', 'triangular',
(max(0, center-2.5), center, min(10, center+2.5)))
# Similar for output
for i in range(5):
center = -2 + i * 1.0
system.add_term('y', f'out_{i}', 'triangular',
(max(-2, center-1), center, min(2, center+1)))
# Learn rules from data
wm = WangMendelLearning(system, X_train, y_train)
wm.fit(verbose=True)
Methods¶
.fit(verbose=False)¶
Generate fuzzy rules from the training data.
Parameters:
- verbose (bool): Print progress information (default: False)
Returns: MamdaniSystem - The trained fuzzy system
Example:
Output (verbose=True):
🔄 Wang-Mendel Algorithm Starting...
✓ Generated 100 candidate rules
✓ Resolved 23 conflicts
✓ Final rule base: 77 rules
✅ Wang-Mendel training complete!
.predict(X)¶
Predict outputs for new inputs.
Parameters:
- X (ndarray): Input data, shape (n_samples, n_features)
Returns: ndarray - Predicted outputs
For Regression:
For Classification:
.predict_proba(X) (Classification only)¶
Predict class probabilities.
Parameters:
- X (ndarray): Input data
Returns: ndarray - Probability matrix, shape (n_samples, n_classes)
Example:
.get_training_stats()¶
Get statistics about the training process.
Returns: dict - Training statistics:
{
'candidate_rules': 100, # Rules generated from data
'final_rules': 77, # Rules after conflict resolution
'conflicts_resolved': 23, # Number of conflicts
'task': 'regression' # Task type
}
Example:
stats = wm.get_training_stats()
print(f"Generated {stats['candidate_rules']} rules")
print(f"Final: {stats['final_rules']} rules")
Complete Example: Regression¶
import numpy as np
from fuzzy_systems import MamdaniSystem
from fuzzy_systems.learning import WangMendelLearning
# Generate nonlinear data
X_train = np.linspace(0, 2*np.pi, 50).reshape(-1, 1)
y_train = np.sin(X_train) + 0.1*X_train
# Create system with 11 partitions
system = MamdaniSystem()
system.add_input('x', (0, 2*np.pi))
system.add_output('y', (-2, 2))
# Add 11 triangular terms to input and output
n_terms = 11
for i in range(n_terms):
# Input terms
center_x = i * (2*np.pi) / (n_terms - 1)
width = (2*np.pi) / (n_terms - 1)
system.add_term('x', f'x_{i}', 'triangular',
(max(0, center_x - width),
center_x,
min(2*np.pi, center_x + width)))
# Output terms
center_y = -2 + i * 4 / (n_terms - 1)
width_y = 4 / (n_terms - 1)
system.add_term('y', f'y_{i}', 'triangular',
(max(-2, center_y - width_y),
center_y,
min(2, center_y + width_y)))
# Train Wang-Mendel
wm = WangMendelLearning(system, X_train, y_train)
wm.fit(verbose=True)
# Predict
X_test = np.linspace(0, 2*np.pi, 200).reshape(-1, 1)
y_pred = wm.predict(X_test)
# Evaluate
from sklearn.metrics import mean_squared_error, r2_score
y_true = np.sin(X_test) + 0.1*X_test
mse = mean_squared_error(y_true, y_pred)
r2 = r2_score(y_true, y_pred)
print(f"MSE: {mse:.4f}")
print(f"R²: {r2:.4f}")
Complete Example: Classification¶
import numpy as np
from sklearn.datasets import load_iris
from sklearn.preprocessing import OneHotEncoder
from sklearn.model_selection import train_test_split
from fuzzy_systems import MamdaniSystem
from fuzzy_systems.learning import WangMendelLearning
# Load Iris dataset
iris = load_iris()
X = iris.data[:, [2, 3]] # Use petal length and width
y = iris.target
# One-hot encode targets
encoder = OneHotEncoder(sparse_output=False)
y_onehot = encoder.fit_transform(y.reshape(-1, 1))
# Split data
X_train, X_test, y_train, y_test = train_test_split(
X, y_onehot, test_size=0.3, random_state=42
)
# Create system with 3 terms per input, 1 output per class
system = MamdaniSystem()
system.add_input('petal_length', (X[:, 0].min(), X[:, 0].max()))
system.add_input('petal_width', (X[:, 1].min(), X[:, 1].max()))
# Add 3 binary outputs (one per class)
for i in range(3):
system.add_output(f'class_{i}', (0, 1))
# Add terms (3 per variable)
for var in ['petal_length', 'petal_width']:
universe = system.input_variables[var].universe
for i in range(3):
center = universe[0] + i * (universe[1] - universe[0]) / 2
width = (universe[1] - universe[0]) / 3
system.add_term(var, f'term_{i}', 'triangular',
(max(universe[0], center - width),
center,
min(universe[1], center + width)))
# Add output terms (2 per class: 0 and 1)
for i in range(3):
system.add_term(f'class_{i}', 'no', 'triangular', (0, 0, 0.5))
system.add_term(f'class_{i}', 'yes', 'triangular', (0.5, 1, 1))
# Train
wm = WangMendelLearning(system, X_train, y_train, task='classification')
wm.fit(verbose=True)
# Predict
y_pred_classes = wm.predict(X_test)
y_pred_proba = wm.predict_proba(X_test)
# Evaluate
from sklearn.metrics import accuracy_score, classification_report
y_test_classes = y_test.argmax(axis=1)
accuracy = accuracy_score(y_test_classes, y_pred_classes)
print(f"Accuracy: {accuracy:.2%}")
print("\nClassification Report:")
print(classification_report(y_test_classes, y_pred_classes,
target_names=iris.target_names))
ANFIS¶
Adaptive Neuro-Fuzzy Inference System with gradient-based learning.
Constructor¶
Parameters:
n_inputs(int): Number of input variablesn_terms(int): Number of membership functions per inputn_outputs(int): Number of outputs (default:1)mf_type(str): Membership function type:'gaussian','bell'(default:'gaussian')
Example:
Methods¶
.fit(X, y, epochs=100, learning_rate=0.01, batch_size=None, validation_split=0.0, early_stopping=False, patience=10, lyapunov_check=True, verbose=True)¶
Train ANFIS using gradient descent with backpropagation.
Parameters:
X(ndarray): Input data, shape(n_samples, n_inputs)y(ndarray): Output data, shape(n_samples, n_outputs)or(n_samples,)epochs(int): Number of training epochs (default:100)learning_rate(float): Learning rate (default:0.01)batch_size(int, optional): Batch size for mini-batch gradient descent. If None, uses full batchvalidation_split(float): Fraction of data for validation (default:0.0)early_stopping(bool): Stop if validation loss doesn't improve (default:False)patience(int): Epochs to wait before early stopping (default:10)lyapunov_check(bool): Monitor Lyapunov stability (default:True)verbose(bool): Print training progress (default:True)
Returns: dict - Training history
Example:
history = anfis.fit(
X_train, y_train,
epochs=50,
learning_rate=0.01,
validation_split=0.2,
early_stopping=True,
verbose=True
)
Output (verbose=True):
Epoch 10/50 - Loss: 0.0234 - Val Loss: 0.0251 - Lyapunov: 0.98
Epoch 20/50 - Loss: 0.0156 - Val Loss: 0.0178 - Lyapunov: 0.99
...
✅ Training complete!
.predict(X)¶
Predict outputs for new inputs.
Parameters:
- X (ndarray): Input data, shape (n_samples, n_inputs)
Returns: ndarray - Predictions, shape (n_samples, n_outputs)
Example:
.get_training_history()¶
Get complete training history.
Returns: dict - History with keys:
{
'epochs': [1, 2, 3, ...],
'loss': [0.5, 0.3, 0.2, ...],
'val_loss': [0.6, 0.4, 0.25, ...], # If validation_split > 0
'lyapunov': [0.95, 0.97, 0.99, ...] # If lyapunov_check=True
}
Example:
history = anfis.get_training_history()
import matplotlib.pyplot as plt
plt.plot(history['epochs'], history['loss'], label='Training')
plt.plot(history['epochs'], history['val_loss'], label='Validation')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.show()
Complete Example: ANFIS Regression¶
import numpy as np
from fuzzy_systems.learning import ANFIS
# Generate data
X_train = np.random.uniform(0, 10, (200, 2))
y_train = np.sin(X_train[:, 0]) + np.cos(X_train[:, 1])
X_test = np.random.uniform(0, 10, (50, 2))
y_true = np.sin(X_test[:, 0]) + np.cos(X_test[:, 1])
# Create and train ANFIS
anfis = ANFIS(n_inputs=2, n_terms=5, n_outputs=1, mf_type='gaussian')
history = anfis.fit(
X_train, y_train,
epochs=100,
learning_rate=0.01,
validation_split=0.2,
early_stopping=True,
patience=10,
verbose=True
)
# Predict
y_pred = anfis.predict(X_test)
# Evaluate
from sklearn.metrics import mean_squared_error, r2_score
mse = mean_squared_error(y_true, y_pred)
r2 = r2_score(y_true, y_pred)
print(f"MSE: {mse:.4f}")
print(f"R²: {r2:.4f}")
# Plot training curve
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 4))
plt.subplot(1, 2, 1)
plt.plot(history['epochs'], history['loss'], label='Train')
plt.plot(history['epochs'], history['val_loss'], label='Validation')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.title('Learning Curve')
plt.subplot(1, 2, 2)
plt.plot(history['epochs'], history['lyapunov'])
plt.xlabel('Epoch')
plt.ylabel('Lyapunov Stability')
plt.title('Stability Monitoring')
plt.tight_layout()
plt.show()
MamdaniLearning¶
Optimize Mamdani systems using gradients or metaheuristics.
Constructor¶
Parameters:
system(MamdaniSystem, optional): Existing Mamdani system to optimizeX(ndarray, optional): Training input datay(ndarray, optional): Training output data
Example:
from fuzzy_systems.learning import MamdaniLearning
# Create from existing system
learner = MamdaniLearning.from_mamdani(system, X_train, y_train)
# Or create new
learner = MamdaniLearning()
# ... configure ...
Class Methods¶
.from_mamdani(system, X, y)¶
Create MamdaniLearning from existing MamdaniSystem.
Parameters:
- system (MamdaniSystem): Existing fuzzy system
- X (ndarray): Training inputs
- y (ndarray): Training outputs
Returns: MamdaniLearning - Learner instance
Example:
Methods¶
.fit(X, y, method='gradient', epochs=100, learning_rate=0.01, **kwargs)¶
Optimize the fuzzy system.
Parameters:
X(ndarray): Training input datay(ndarray): Training output datamethod(str): Optimization method:'gradient': Gradient descent'pso': Particle Swarm Optimization'de': Differential Evolution'ga': Genetic Algorithm
epochs(int): Number of iterations (default:100)learning_rate(float): Learning rate for gradient (default:0.01)**kwargs: Method-specific parameters
Gradient-specific kwargs:
- batch_size (int): Batch size for mini-batch
- momentum (float): Momentum factor
PSO-specific kwargs:
- n_particles (int): Number of particles (default: 30)
- inertia (float): Inertia weight (default: 0.7)
- cognitive (float): Cognitive parameter (default: 1.5)
- social (float): Social parameter (default: 1.5)
DE-specific kwargs:
- population_size (int): Population size (default: 50)
- mutation_factor (float): Mutation factor F (default: 0.8)
- crossover_prob (float): Crossover probability (default: 0.9)
GA-specific kwargs:
- population_size (int): Population size (default: 50)
- mutation_rate (float): Mutation rate (default: 0.1)
- crossover_rate (float): Crossover rate (default: 0.8)
Example:
# Gradient descent
learner.fit(X_train, y_train, method='gradient',
epochs=100, learning_rate=0.01)
# PSO
learner.fit(X_train, y_train, method='pso',
epochs=50, n_particles=30)
# Differential Evolution
learner.fit(X_train, y_train, method='de',
epochs=100, population_size=50)
.predict(X)¶
Predict outputs using the optimized system.
Parameters:
- X (ndarray): Input data
Returns: ndarray - Predictions
.to_mamdani()¶
Convert back to MamdaniSystem.
Returns: MamdaniSystem - Optimized fuzzy system
Example:
Complete Example: Optimization with PSO¶
import numpy as np
from fuzzy_systems import MamdaniSystem
from fuzzy_systems.learning import MamdaniLearning
# Generate data
X_train = np.linspace(-5, 5, 100).reshape(-1, 1)
y_train = -2 * X_train + 5 + np.random.normal(0, 0.5, X_train.shape)
# Create initial system
system = MamdaniSystem()
system.add_input('x', (-5, 5))
system.add_output('y', (-15, 15))
# Add terms with suboptimal initial parameters
system.add_term('x', 'low', 'triangular', (-5, -2, 1))
system.add_term('x', 'high', 'triangular', (-1, 2, 5))
system.add_term('y', 'low', 'triangular', (-15, -7, 1))
system.add_term('y', 'high', 'triangular', (-1, 7, 15))
# Initial rules
system.add_rules([('low', 'high'), ('high', 'low')])
# Create learner
learner = MamdaniLearning.from_mamdani(system, X_train, y_train)
# Optimize with PSO
history = learner.fit(
X_train, y_train,
method='pso',
epochs=100,
n_particles=30,
verbose=True
)
# Predict
y_pred = learner.predict(X_train)
# Evaluate
from sklearn.metrics import mean_squared_error
mse = mean_squared_error(y_train, y_pred)
print(f"MSE after optimization: {mse:.4f}")
# Get optimized system
optimized_system = learner.to_mamdani()
optimized_system.save('optimized_system.pkl')
Metaheuristics¶
Direct access to optimization algorithms.
PSO¶
Particle Swarm Optimization.
from fuzzy_systems.learning import PSO
optimizer = PSO(
objective_func,
bounds,
n_particles=30,
max_iter=100,
inertia=0.7,
cognitive=1.5,
social=1.5
)
best_params, best_cost = optimizer.optimize()
DE¶
Differential Evolution.
from fuzzy_systems.learning import DE
optimizer = DE(
objective_func,
bounds,
population_size=50,
max_iter=100,
mutation_factor=0.8,
crossover_prob=0.9
)
best_params, best_cost = optimizer.optimize()
GA¶
Genetic Algorithm.
from fuzzy_systems.learning import GA
optimizer = GA(
objective_func,
bounds,
population_size=50,
max_iter=100,
mutation_rate=0.1,
crossover_rate=0.8
)
best_params, best_cost = optimizer.optimize()
Comparison Table¶
| Method | Type | Speed | Accuracy | Best For |
|---|---|---|---|---|
| Wang-Mendel | Rule generation | ⚡⚡⚡ Fast | ⭐⭐ Good | Quick prototyping, interpretable rules |
| ANFIS | Neuro-fuzzy | ⚡⚡ Medium | ⭐⭐⭐ Excellent | Precise approximation, differentiable problems |
| MamdaniLearning (Gradient) | Gradient | ⚡⚡ Medium | ⭐⭐⭐ Excellent | Fine-tuning existing systems |
| MamdaniLearning (PSO) | Metaheuristic | ⚡ Slow | ⭐⭐⭐ Excellent | Non-differentiable, global search |
| MamdaniLearning (DE) | Metaheuristic | ⚡ Slow | ⭐⭐⭐ Excellent | Robust optimization, fewer parameters |
| MamdaniLearning (GA) | Metaheuristic | ⚡ Slow | ⭐⭐ Good | Discrete/combinatorial optimization |
See Also¶
- Core API - Fuzzy sets and operators
- Inference API - Mamdani and Sugeno systems
- Dynamics API - Dynamic fuzzy systems
- User Guide: Learning - Detailed tutorials
- Examples - Interactive notebooks