Skip to content

Latest commit

 

History

History
566 lines (425 loc) · 16.4 KB

File metadata and controls

566 lines (425 loc) · 16.4 KB

Illustrative Example: Federated Fuzzy Regression Tree

This document provides a comprehensive step-by-step guide to executing a Federated Fuzzy Regression Tree (FRT) experiment using fedxai-lib in a distributed Docker environment. The example demonstrates training an interpretable regression model on weather data distributed across multiple client nodes.


Table of Contents

  1. Overview
  2. Dataset Description
  3. Environment Setup
  4. Dataset Preparation
  5. Docker Infrastructure Deployment
  6. Federation Execution
  7. Results and Model Interpretation
  8. Troubleshooting

Overview

Scenario

We will train a Federated Fuzzy Regression Tree to predict mean temperature based on various meteorological features from the Weather Izimir dataset. The dataset is partitioned horizontally across multiple client nodes, simulating a realistic federated learning scenario where data cannot leave its source.

Architecture

The federation consists of three types of nodes:

  • Director (1 node): Orchestrates the federation and aggregates client statistics
  • Clients (4 nodes): Each holds a private partition of the training/test data
  • Requester (1 node): Initiates federation requests and monitors execution

Learning Objective

Build an interpretable fuzzy regression tree that:

  • Maintains data privacy (raw data never leaves client nodes)
  • Provides explainable predictions through fuzzy rules
  • Implements obfuscation to prevent inference attacks

Dataset Description

Weather Izimir Dataset

The dataset contains meteorological measurements from Izimir, Turkey, with the following features:

Input Features:

  • Max_temperature - Maximum daily temperature (°C)
  • Min_temperature - Minimum daily temperature (°C)
  • Dewpoint - Dew point temperature (°C)
  • Precipitation - Precipitation amount (mm)
  • Sea_level_pressure - Sea level atmospheric pressure (hPa)
  • Standard_pressure - Standard atmospheric pressure (hPa)
  • Visibility - Visibility distance (km)
  • Wind_speed - Average wind speed (km/h)
  • Max_wind_speed - Maximum wind speed (km/h)

Target Variable:

  • Mean_temperature - Mean daily temperature (°C)

Data Partitioning

The dataset is partitioned horizontally into 4 client datasets:

datasets_splits/WeatherIzimir/
├── client_X_train_1.csv
├── client_y_train_1.csv
├── client_X_test_1.csv
├── client_y_test_1.csv
├── client_X_train_2.csv
├── client_y_train_2.csv
├── ... (clients 3, 4)

Each client receives approximately 25% of the data, ensuring IID (Independent and Identically Distributed) partitioning.


Environment Setup

Prerequisites

Ensure you have the following installed:

  • Docker (version 20.10+)
  • Docker Compose (version 1.29+)
  • Git

Directory Structure

fedxai-lib/
├── datasets_splits/WeatherIzimir/   # Client data partitions
├── models/                          # Output directory for trained models
├── Dockerfile.fedxai_lib            # Docker image for fedxai library
├── Dockerfile.requester             # Docker image for requester
├── docker-compose-director.yml      # Director configuration
├── docker-compose-clients.yml       # Clients configuration
└── docker-compose-requester.yml     # Requester configuration

Build Docker Images

For realistic federated scenarios, deploy the system using Docker containers distributed across multiple machines.

# Navigate to repository root
cd fedxai-lib

# Build fedxai library image (used by director and clients)
docker build --progress=plain -f Dockerfile.fedxai_lib -t fedxai .

# Build requester image
docker build --progress=plain -f Dockerfile.requester -t fedlang-requester .

Expected Output:

[+] Building 45.3s (12/12) FINISHED
Successfully tagged fedxai:latest
Successfully tagged fedlang-requester:latest

The repository includes three compose files:

  • docker-compose-director.yml - Runs the director (server/aggregator) node
  • docker-compose-clients.yml - Runs client nodes with their data partitions
  • docker-compose-requester.yml - Runs the requester node to initiate federations

Key environment variables:

Variable Description
FEDLANG_NODE_TYPE Node type: director, client, or requester
FEDLANG_NODE_NAME Unique node identifier (format: name@IP)
FEDLANG_COOKIE Erlang cookie for distributed authentication
FEDLANG_DIRECTOR_NAME Director node identifier for clients to connect
ERL_FLAGS Erlang runtime flags for configuring the Erlang node (e.g., -setcookie for authentication, distributed port configuration)

Dataset Preparation

If you don't already have the dataset partitions, generate them using the test script:

cd src
poetry run python tests/test_fed_frt_weather_izimir.py

This script:

  1. Loads the raw WeatherIzimir.csv dataset
  2. Normalizes features using RobustScaler and MinMaxScaler
  3. Partitions data into 4 client datasets as an example (see test files for implementation details on dataset partitioning)
  4. Saves partitions to datasets_splits/WeatherIzimir/

Verify data partitions exist:

ls -lh datasets_splits/WeatherIzimir/

Expected Output:

client_X_train_1.csv
client_y_train_1.csv
client_X_test_1.csv
client_y_test_1.csv
... (16 files total for 4 clients)

Docker Infrastructure Deployment

Network Architecture

The federation uses the following network configuration:

  • Director: 172.20.0.2:9000 (bridge network)
  • Clients: Host network mode with ports 9001-9004
  • Requester: 172.20.0.254 (bridge network)

Step 1: Configure Environment Variables

Edit the docker-compose files to match your network setup:

docker-compose-director.yml:

environment:
  - FEDLANG_NODE_NAME=director@172.16.2.185  # Director's external IP
  - FEDLANG_COOKIE=050df51e-1c75-433e-95c3-8e3e1926d6a6

docker-compose-clients.yml:

environment:
  - FEDLANG_NODE_NAME=client1@172.16.6.42  # Client host IP
  - FEDLANG_DIRECTOR_NAME=director@172.16.2.185  # Director's external IP
  - FEDLANG_COOKIE=050df51e-1c75-433e-95c3-8e3e1926d6a6

docker-compose-requester.yml:

environment:
  - FEDLANG_DIRECTOR_NAME=director@172.16.2.185  # Director's external IP
  - ERL_FLAGS: -setcookie 050df51e-1c75-433e-95c3-8e3e1926d6a6

Important:

  • Replace IP addresses with your actual machine IPs
  • Keep the same FEDLANG_COOKIE value across all nodes for authentication

Step 2: Create Shared Model Directory

# Create directory for model outputs (shared across containers)
sudo mkdir -p /models
sudo chmod 777 /models

Step 3: Launch Director Node

On the director machine:

docker compose -f docker-compose-director.yml up -d

Verify director is running:

docker logs director

Expected Output:

=INFO REPORT==== 18-Oct-2025::22:17:01.404054 ===
Starting node type: "director"
=INFO REPORT==== 18-Oct-2025::22:17:01.404170 ===
Fedlang director, start_link
=INFO REPORT==== 18-Oct-2025::22:17:01.404301 ===
Fedlang director, init
=PROGRESS REPORT==== 18-Oct-2025::22:17:01.404427 ===
    supervisor: {local,fedlang_sup}
    started: [{pid,<0.302.0>},
              {id,fedlang_director},
              {mfargs,{fedlang_director,start_link,[]}},
              {restart_type,permanent},
              {significant,false},
              {shutdown,5000},
              {child_type,worker}]

=PROGRESS REPORT==== 18-Oct-2025::22:17:01.404623 ===
    application: fedlang
    started_at: 'director@172.16.2.185'

Step 4: Launch Client Nodes

On client machine(s):

docker compose -f docker-compose-clients.yml up -d

Verify clients are running:

docker ps
docker logs client1
docker logs client2
docker logs client3
docker logs client4

Expected Output (per client):

=INFO REPORT==== 18-Oct-2025::22:25:58.015750 ===
Starting node type: "client"
=INFO REPORT==== 18-Oct-2025::22:25:58.015813 ===
Fedlang client, start_link
=INFO REPORT==== 18-Oct-2025::22:25:58.015883 ===
Fedlang client, init
=PROGRESS REPORT==== 18-Oct-2025::22:25:58.015986 ===
    supervisor: {local,inet_gethost_native_sup}
    started: [{pid,<0.304.0>},{mfa,{inet_gethost_native,init,[[]]}}]

=PROGRESS REPORT==== 18-Oct-2025::22:25:58.030063 ===
    supervisor: {local,fedlang_sup}
    started: [{pid,<0.302.0>},
              {id,fedlang_client},
              {mfargs,{fedlang_client,start_link,[]}},
              {restart_type,permanent},
              {significant,false},
              {shutdown,5000},
              {child_type,worker}]

=PROGRESS REPORT==== 18-Oct-2025::22:25:58.030220 ===
    application: fedlang
    started_at: 'client1@172.16.6.42'

Step 5: Launch Requester Node

On the requester machine:

docker compose -f docker-compose-requester.yml up -d

Verify requester is running:

docker logs requester

Federation Execution

Step 1: Access Requester Container

docker exec -it requester /bin/bash

You are now inside the requester container shell.

Step 2: Prepare Federation Configuration

Navigate to the scripts directory:

cd scripts
ls executions/

View the federation configuration:

cat executions/federated_frt_weather_izimir.json

Configuration Details:

The "algorithm" field specifies the algorithm identifier. For a complete list of all available algorithm identifiers and their hyperparameters, see Algorithm_Hyperparameters.md.

{
  "algorithm": "federated_frt",
  "parameters": {
    "gain_threshold": 0.0001,
    "max_number_rounds": 100,
    "num_fuzzy_sets": 5,
    "max_depth": null,
    "min_samples_split_ratio": 0.1,
    "min_num_clients": 20,
    "obfuscate": true,
    "features_names": [
      "Max_temperature", "Min_temperature", "Dewpoint",
      "Precipitation", "Sea_level_pressure", "Standard_pressure",
      "Visibility", "Wind_speed", "Max_wind_speed"
    ],
    "target": "Mean_temperature",
    "dataset_X_train": "/dataset/X_train.csv",
    "dataset_y_train": "/dataset/y_train.csv",
    "dataset_X_test": "/dataset/X_test.csv",
    "dataset_y_test": "/dataset/y_test.csv",
    "model_output_file": "/models/frt_weather_izimir.pickle"
  }
}

For detailed parameter specifications, see Algorithm_Hyperparameters.md.

Step 3: Execute Federation

Run the federation script:

./run_federation.sh ./executions/federated_frt_weather_izimir.json

Step 4: Monitor Execution

The federation execution proceeds through multiple stages. You can monitor the execution by checking the director node logs:

docker logs -f director

Example output from the director node:

=INFO REPORT==== 18-Oct-2025::22:28:30.974575 ===
Begin: Round=1, Step=2, Entity="#available_clients", Method="compute_rule_weights_step1"
=INFO REPORT==== 18-Oct-2025::22:28:31.180870 ===
End: Round=1, Step=2, Entity="#available_clients", Method="compute_rule_weights_step1"
=INFO REPORT==== 18-Oct-2025::22:28:31.181253 ===
Begin: Round=1, Step=3, Entity="#server", Method="compute_rule_error_stats"
=INFO REPORT==== 18-Oct-2025::22:28:31.182416 ===
End: Round=1, Step=3, Entity="#server", Method="compute_rule_error_stats"
=INFO REPORT==== 18-Oct-2025::22:28:31.182627 ===
Begin: Round=1, Step=4, Entity="#available_clients", Method="compute_weight_rules_step2"
=INFO REPORT==== 18-Oct-2025::22:28:31.214616 ===
End: Round=1, Step=4, Entity="#available_clients", Method="compute_weight_rules_step2"
=INFO REPORT==== 18-Oct-2025::22:28:31.214972 ===
Begin: Round=1, Step=5, Entity="#server", Method="compute_rule_weights"
=INFO REPORT==== 18-Oct-2025::22:28:31.217633 ===
End: Round=1, Step=5, Entity="#server", Method="compute_rule_weights"
=INFO REPORT==== 18-Oct-2025::22:28:31.217993 ===
Begin: Round=1, Step=1, Entity="#server", Method="save_model"
2025-10-18 22:28:31,218 [MainThread  ] [INFO ]  model_output_file = /models/frt_weather_izimir.pickle
=INFO REPORT==== 18-Oct-2025::22:28:31.226569 ===
End: Round=1, Step=1, Entity="#server", Method="save_model"
=INFO REPORT==== 18-Oct-2025::22:28:31.226855 ===
Begin: Round=1, Step=2, Entity="#available_clients", Method="save_model"
=INFO REPORT==== 18-Oct-2025::22:28:31.239358 ===
End: Round=1, Step=2, Entity="#available_clients", Method="save_model"
=INFO REPORT==== 18-Oct-2025::22:28:31.239746 ===
Notifying end client: "3b59b111-9ddd-48a4-ae99-42028801757a"
=INFO REPORT==== 18-Oct-2025::22:28:31.240053 ===
Notifying end client: "43bd4712-27cb-4e2f-8af1-318d2fca0309"
=INFO REPORT==== 18-Oct-2025::22:28:31.240238 ===
Notifying end client: "66870db7-b0c2-4092-a582-f23c30b4b448"
=INFO REPORT==== 18-Oct-2025::22:28:31.240591 ===
Notifying end client: "b01ef527-627c-49f6-b7cf-8d0cb32ec25b"
=INFO REPORT==== 18-Oct-2025::22:28:31.240918 ===
handle_info, incoming message {fl_end_str_run,
                                  "b2ad6fbc-1307-4f27-a2e3-8f15c0016f57"}

Step 5: Retrieve Trained Model

Exit the requester container:

exit

The trained model is now available on the host machine:

ls -lh /models/

Expected Output:

frt_weather_izimir.pickle        # Global federated model
frt_weather_izimir_client_0.pickle
frt_weather_izimir_client_1.pickle
... (client-specific models)

Results and Model Interpretation

Loading the Trained Model

import pickle

# Load the trained federated model
with open('/models/frt_weather_izimir.pickle', 'rb') as f:
    model = pickle.load(f)

# View model structure
print(f"Number of fuzzy rules: {len(model.get_rules())}")
print(f"Tree depth: {model.root_node.depth}")

Understanding Fuzzy Rules

The FRT model consists of interpretable fuzzy rules in the form:

IF Max_temperature is HIGH AND Dewpoint is MEDIUM
THEN Mean_temperature = 0.85 * Max_temperature + 0.12 * Dewpoint + 0.03
     (Weight: 0.92, Support: 0.15, Confidence: 0.88)

Making Predictions

import numpy as np

# Example input: [Max_temp, Min_temp, Dewpoint, Precip, Sea_press, Std_press, Vis, Wind, Max_wind]
input_sample = np.array([[25.5, 18.2, 15.3, 0.0, 1013.2, 1012.8, 10.0, 12.5, 20.3]])

# Predict
prediction, rule_id, num_active_rules = model.predict(input_sample)[0]

print(f"Predicted Mean Temperature: {prediction:.2f}°C")
print(f"Activated Rule ID: {rule_id}")
print(f"Number of Active Rules: {num_active_rules}")

Troubleshooting

Issue: Clients Cannot Connect to Director

Symptoms:

Error: Connection refused to director@172.16.2.185

Solutions:

  1. Verify director is running: docker logs director
  2. Check firewall rules allow ports 4369 and 9000
  3. Verify IP addresses in environment variables match actual machine IPs
  4. Ensure FEDLANG_COOKIE is identical across all nodes

Issue: Dataset Not Found

Symptoms:

FileNotFoundError: /dataset/X_train.csv not found

Solutions:

  1. Verify dataset partitions exist: ls datasets_splits/WeatherIzimir/
  2. Check volume mounts in docker-compose-clients.yml:
    volumes:
      - ./datasets_splits/WeatherIzimir/client_X_train_1.csv:/dataset/X_train.csv
  3. Ensure paths are relative to docker-compose file location

Issue: Federation Hangs During Execution

Symptoms:

  • Federation stops at a specific round without error

Solutions:

  1. Check client logs for errors: docker logs client1
  2. Verify all clients are connected: count active clients in director logs
  3. Increase network timeout: add -kernel net_ticktime 120 to ERL_FLAGS

Issue: Model File Not Saved

Symptoms:

ls /models/  # Empty directory

Solutions:

  1. Check volume mount exists: docker inspect director | grep models
  2. Verify permissions: ls -ld /models (should be writable)
  3. Check server logs for write errors: docker logs director

Additional Resources

For questions or issues, please contact the contributors or open an issue on GitHub.