Table of Contents

    Experiment Tracking (MLflow, Weights & Biases)

    MLOps Fundamentals

    Experiment Tracking: MLflow and Weights & Biases

    Learn how to record, organize, compare, reproduce, and govern Machine Learning experiments using MLflow and Weights & Biases. Track parameters, metrics, code versions, datasets, artifacts, system information, model files, evaluation reports, and conclusions across the complete experimentation lifecycle.

    Introduction

    Machine Learning development is iterative. A team may test different algorithms, feature sets, data versions, hyperparameters, random seeds, preprocessing strategies, decision thresholds, and runtime environments before selecting a model.

    Without experiment tracking, results may be scattered across notebooks, terminal output, spreadsheets, screenshots, and filenames. It becomes difficult to determine which experiment produced a model, why one candidate was selected, or whether a historical result can be reproduced.

    Experiment tracking is the systematic recording of the inputs, configuration, execution context, outputs, metrics, artifacts, and conclusions associated with each Machine Learning run.

    MLflow and Weights & Biases, commonly abbreviated as W&B, provide experiment-tracking capabilities. Both can organize runs, log parameters and metrics, preserve artifacts, compare results, and improve collaboration, although their interfaces, deployment options, integrations, and broader platform capabilities differ.

    Core principle: Every important result should be connected to the exact code, data, configuration, environment, and artifacts that produced it.

    Learning Objectives

    By the End of This Lesson

    • Define Machine Learning experiment tracking
    • Explain why manual experiment records are unreliable
    • Distinguish experiments, runs, parameters, metrics, tags, and artifacts
    • Identify the information required for reproducibility
    • Design a consistent experiment-naming strategy
    • Track source-code and dataset versions
    • Track training configuration and random states
    • Log scalar metrics and metric history
    • Log model files, reports, plots, and schemas
    • Track experiments with MLflow
    • Use MLflow manual logging
    • Use MLflow autologging
    • Track experiments using Weights & Biases
    • Use W&B Artifacts for versioned outputs
    • Compare multiple experimental runs
    • Track cross-validation and threshold-selection results
    • Understand hyperparameter sweeps
    • Integrate experiment tracking with ML pipelines and CI/CD
    • Protect sensitive experiment data
    • Create an experiment-tracking readiness checklist

    Prerequisites

    Recommended Knowledge

    • Python programming
    • pandas and NumPy
    • scikit-learn fundamentals
    • Model training and evaluation
    • Train-validation-test separation
    • Hyperparameters and model parameters
    • Git fundamentals
    • Saving and loading models
    • ML pipelines
    • Model version control

    Required Packages

    • MLflow
    • Weights & Biases
    • pandas
    • NumPy
    • scikit-learn
    • Matplotlib
    • Joblib
    python -m pip install mlflow wandb pandas numpy scikit-learn matplotlib joblib
    Access requirement: Use only approved experiment-tracking servers, projects, workspaces, authentication methods, storage locations, and data. Do not upload confidential information to an external service without authorization.

    What Is a Machine Learning Experiment?

    A Machine Learning experiment is a structured investigation that tests a defined hypothesis by changing one or more controlled inputs and measuring the resulting behavior.

    Experiment Structure
    Hypothesis + Data + Configuration + Execution → Evidence → Conclusion
    Experiment Element Example
    Question Does class weighting improve recall without unacceptable precision loss?
    Controlled Change Class-weight configuration
    Fixed Inputs Dataset version, split, features, and evaluation protocol
    Measured Outputs Precision, recall, F1, calibration, and latency
    Conclusion Evidence-based decision to accept, reject, or investigate further
    Experiment principle: Begin with a clear question. Logging many runs without a defined hypothesis creates records but may not create useful evidence.

    What Is Experiment Tracking?

    Experiment tracking creates a searchable history of model-development runs and connects every result to the inputs and artifacts that produced it.

    Tracked Information Purpose
    Run Identifier Uniquely identifies one execution
    Parameters Records configuration selected before or during training
    Metrics Records measured model and system behavior
    Tags Adds searchable descriptive metadata
    Artifacts Preserves model files, reports, plots, schemas, and outputs
    Code Version Identifies the source revision used by the run
    Data Version Identifies the training and evaluation information
    Environment Identifies dependencies, runtime, and hardware context
    Status Records whether the run completed, failed, or was canceled
    Conclusion Explains the interpretation and next decision

    Why Experiment Tracking Matters

    Practical Benefits

    • Preserves experiment history
    • Supports reproducibility
    • Enables run comparison
    • Prevents repeated failed experiments
    • Supports collaboration
    • Connects metrics with exact configurations
    • Preserves generated artifacts
    • Improves model-selection evidence
    • Supports audit and governance
    • Provides lineage for model registration
    • Supports incident investigation
    • Improves handover between teams
    Weak Process Record the best accuracy in a spreadsheet without preserving the data split, code version, model configuration, or artifact.
    Tracked Process Record the actual parameters, metrics, dataset versions, source revision, environment, artifacts, and conclusion for every relevant run.

    Core Tracking Concepts

    Concept Meaning
    Project or Experiment A logical collection of related runs
    Run One execution of training, evaluation, or analysis code
    Parameter A configuration value associated with a run
    Metric A measured numerical value
    Metric Step The iteration, epoch, or time point associated with a metric
    Tag A descriptive searchable value
    Artifact A file or directory produced or used by a run
    Configuration The complete set of values controlling execution
    Lineage The relationship among code, data, runs, metrics, and artifacts

    Parameters vs Metrics

    Parameters

    • Control experiment execution
    • Usually selected before training
    • Examples include learning rate and tree depth
    • Support filtering and comparison

    Metrics

    • Measure experiment results
    • Calculated from training or evaluation
    • Examples include F1 and validation loss
    • May be logged once or over multiple steps
    Tracked Value Classification
    Learning Rate Parameter
    Maximum Tree Depth Parameter
    Random State Parameter
    Validation F1 Metric
    Training Loss by Epoch Metric History
    Model Type Parameter or Tag
    Source Revision Tag or System Metadata

    Experiment Artifacts

    Useful Artifacts

    • Saved model pipeline
    • Model metadata
    • Input and output schemas
    • Data-validation report
    • Evaluation report
    • Confusion matrix
    • ROC and precision-recall plots
    • Calibration plot
    • Feature-importance report
    • Error-analysis table
    • Model card
    • Dependency manifest
    • Representative prediction samples
    Artifact principle: Store artifacts needed to understand, verify, compare, reproduce, or operationalize the run. Avoid uploading unnecessary raw or sensitive data.

    Reproducibility Record

    Reproducible Experiment
    Code Version + Data Version + Configuration + Environment + Random State → Traceable Result

    Record

    • Git commit identifier
    • Training-data version
    • Validation-data version
    • Test-data version
    • Feature-definition version
    • Configuration version
    • Dependency versions
    • Container-image digest where applicable
    • Random seeds
    • Hardware or accelerator type where relevant
    • Model checksum

    Create a Shared Training Function

    The following training function is used in the MLflow and W&B examples so that both platforms track equivalent model behavior.

    from sklearn.compose import ColumnTransformer
    from sklearn.impute import SimpleImputer
    from sklearn.linear_model import LogisticRegression
    from sklearn.pipeline import Pipeline
    from sklearn.preprocessing import OneHotEncoder
    from sklearn.preprocessing import StandardScaler
    
    
    def create_model_pipeline(
        numerical_features,
        categorical_features,
        regularization_strength,
        random_state
    ):
        numerical_pipeline = Pipeline(
            steps=[
                (
                    "imputer",
                    SimpleImputer(
                        strategy="median"
                    )
                ),
                (
                    "scaler",
                    StandardScaler()
                )
            ]
        )
    
        categorical_pipeline = Pipeline(
            steps=[
                (
                    "imputer",
                    SimpleImputer(
                        strategy="most_frequent"
                    )
                ),
                (
                    "encoder",
                    OneHotEncoder(
                        handle_unknown="ignore"
                    )
                )
            ]
        )
    
        preprocessor = ColumnTransformer(
            transformers=[
                (
                    "numerical",
                    numerical_pipeline,
                    numerical_features
                ),
                (
                    "categorical",
                    categorical_pipeline,
                    categorical_features
                )
            ]
        )
    
        return Pipeline(
            steps=[
                (
                    "preprocessor",
                    preprocessor
                ),
                (
                    "classifier",
                    LogisticRegression(
                        C=regularization_strength,
                        class_weight="balanced",
                        max_iter=2000,
                        random_state=random_state
                    )
                )
            ]
        )

    Create an Evaluation Function

    from sklearn.metrics import accuracy_score
    from sklearn.metrics import average_precision_score
    from sklearn.metrics import f1_score
    from sklearn.metrics import precision_score
    from sklearn.metrics import recall_score
    from sklearn.metrics import roc_auc_score
    
    
    def calculate_metrics(
        true_labels,
        probabilities,
        decision_threshold
    ):
        predictions = (
            probabilities
            >=
            decision_threshold
        ).astype(
            int
        )
    
        return {
            "accuracy": float(
                accuracy_score(
                    true_labels,
                    predictions
                )
            ),
            "precision": float(
                precision_score(
                    true_labels,
                    predictions,
                    zero_division=0
                )
            ),
            "recall": float(
                recall_score(
                    true_labels,
                    predictions,
                    zero_division=0
                )
            ),
            "f1": float(
                f1_score(
                    true_labels,
                    predictions,
                    zero_division=0
                )
            ),
            "roc_auc": float(
                roc_auc_score(
                    true_labels,
                    probabilities
                )
            ),
            "average_precision": float(
                average_precision_score(
                    true_labels,
                    probabilities
                )
            )
        }
    Metric rule: Log values calculated from the identified evaluation dataset. Never populate experiment dashboards with invented metrics.

    MLflow Tracking Concepts

    MLflow Concept Purpose
    Tracking URI Identifies the tracking-server or storage location
    Experiment Groups related runs
    Run Represents one tracked execution
    Parameter Stores a run configuration value
    Metric Stores a numerical result, optionally over steps
    Tag Stores searchable descriptive metadata
    Artifact Stores an output file or directory
    Logged Model Represents a tracked trained-model artifact
    Model Registry Manages registered model versions and lifecycle metadata

    Configure MLflow Tracking

    import mlflow
    
    
    mlflow.set_tracking_uri(
        "http://127.0.0.1:5000"
    )
    
    
    mlflow.set_experiment(
        "customer-churn-experiments"
    )
    Tracking URI: Replace the local address with an approved tracking environment where team sharing, authentication, persistence, and access control are required.

    Start a Local MLflow Server

    mlflow server \
      --host 127.0.0.1 \
      --port 5000
    Local-development scope: A local server is useful for learning. A shared environment requires approved authentication, authorization, networking, persistent storage, backup, encryption, and operational ownership.

    Track an Experiment with MLflow

    import mlflow
    import mlflow.sklearn
    
    
    regularization_strength = 1.0
    
    decision_threshold = 0.60
    
    random_state = 42
    
    
    with mlflow.start_run(
        run_name="logistic-regression-balanced"
    ) as run:
    
        mlflow.log_params(
            {
                "algorithm": (
                    "logistic-regression"
                ),
                "regularization_strength": (
                    regularization_strength
                ),
                "class_weight": "balanced",
                "decision_threshold": (
                    decision_threshold
                ),
                "random_state": random_state
            }
        )
    
        mlflow.set_tags(
            {
                "project": "customer-churn",
                "task": "binary-classification",
                "code_version": (
                    "replace-with-source-revision"
                ),
                "training_data_version": (
                    "replace-with-data-version"
                ),
                "feature_definition_version": (
                    "1.0.0"
                ),
                "run_purpose": (
                    "evaluate-class-weighting"
                )
            }
        )
    
        model_pipeline = create_model_pipeline(
            numerical_features=(
                numerical_features
            ),
            categorical_features=(
                categorical_features
            ),
            regularization_strength=(
                regularization_strength
            ),
            random_state=random_state
        )
    
        model_pipeline.fit(
            training_features,
            training_labels
        )
    
        validation_probabilities = (
            model_pipeline.predict_proba(
                validation_features
            )[:, 1]
        )
    
        validation_metrics = (
            calculate_metrics(
                true_labels=validation_labels,
                probabilities=(
                    validation_probabilities
                ),
                decision_threshold=(
                    decision_threshold
                )
            )
        )
    
        mlflow.log_metrics(
            validation_metrics
        )
    
        mlflow.sklearn.log_model(
            sk_model=model_pipeline,
            name="model"
        )
    
        run_id = run.info.run_id
    
    
    print(
        run_id
    )

    Log Evaluation Artifacts with MLflow

    import json
    from pathlib import Path
    
    
    artifact_directory = Path(
        "experiment-artifacts"
    )
    
    
    artifact_directory.mkdir(
        parents=True,
        exist_ok=True
    )
    
    
    metrics_path = (
        artifact_directory
        / "validation_metrics.json"
    )
    
    
    with open(
        metrics_path,
        "w",
        encoding="utf-8"
    ) as metrics_file:
    
        json.dump(
            validation_metrics,
            metrics_file,
            indent=4
        )
    
    
    mlflow.log_artifact(
        str(
            metrics_path
        ),
        artifact_path="evaluation"
    )
    Artifact organization: Use logical artifact paths such as evaluation, schemas, plots, and model-card so reviewers can find evidence quickly.

    Log an Input Example and Signature

    from mlflow.models import infer_signature
    
    
    input_example = (
        validation_features.head(
            3
        )
    )
    
    
    model_signature = infer_signature(
        input_example,
        model_pipeline.predict_proba(
            input_example
        )
    )
    
    
    mlflow.sklearn.log_model(
        sk_model=model_pipeline,
        name="model-with-signature",
        signature=model_signature,
        input_example=input_example
    )
    Privacy caution: Use approved synthetic, anonymized, or otherwise authorized input examples. An input example becomes part of the tracked model artifacts.

    MLflow Autologging

    MLflow autologging can automatically capture supported parameters, metrics, models, and related metadata from compatible libraries.

    import mlflow
    import mlflow.sklearn
    
    
    mlflow.sklearn.autolog(
        log_input_examples=True,
        log_model_signatures=True,
        log_models=True
    )
    
    
    with mlflow.start_run(
        run_name="autologged-logistic-regression"
    ):
    
        model_pipeline = create_model_pipeline(
            numerical_features=(
                numerical_features
            ),
            categorical_features=(
                categorical_features
            ),
            regularization_strength=1.0,
            random_state=42
        )
    
        model_pipeline.fit(
            training_features,
            training_labels
        )
    Autologging review: Inspect what the selected integration records. Add project-specific data versions, purpose, threshold, group metrics, and governance metadata explicitly when they are not captured automatically.

    Log Metrics Over Time

    with mlflow.start_run(
        run_name="iterative-training"
    ):
    
        for epoch in range(
            number_of_epochs
        ):
            training_loss = (
                calculate_training_loss(
                    epoch
                )
            )
    
            validation_loss = (
                calculate_validation_loss(
                    epoch
                )
            )
    
            mlflow.log_metric(
                "training_loss",
                float(
                    training_loss
                ),
                step=epoch
            )
    
            mlflow.log_metric(
                "validation_loss",
                float(
                    validation_loss
                ),
                step=epoch
            )
    Step logging: Metric history can reveal convergence, instability, divergence, and overfitting patterns that a final metric alone may hide.

    Search MLflow Runs

    experiment = (
        mlflow.get_experiment_by_name(
            "customer-churn-experiments"
        )
    )
    
    
    runs = mlflow.search_runs(
        experiment_ids=[
            experiment.experiment_id
        ],
        filter_string=(
            "tags.task = "
            "'binary-classification'"
        ),
        order_by=[
            "metrics.f1 DESC"
        ],
        max_results=20
    )
    
    
    print(
        runs[
            [
                "run_id",
                "params.algorithm",
                "params.regularization_strength",
                "metrics.precision",
                "metrics.recall",
                "metrics.f1"
            ]
        ]
    )
    Comparison caution: Compare runs only when their datasets, split strategy, metric definitions, target, and evaluation conditions are compatible.

    Load a Model from an MLflow Run

    import mlflow.pyfunc
    
    
    model_uri = (
        f"runs:/{run_id}/model"
    )
    
    
    tracked_model = mlflow.pyfunc.load_model(
        model_uri
    )
    
    
    predictions = tracked_model.predict(
        inference_frame
    )

    Weights & Biases Tracking Concepts

    W&B Concept Purpose
    Entity Represents a user or team scope
    Project Groups related runs
    Run Represents one tracked execution
    Config Stores hyperparameters and execution settings
    Summary Stores final or important result values
    History Stores metrics over time
    Artifact Versions datasets, models, and other files
    Table Stores structured data for analysis and visualization
    Sweep Coordinates hyperparameter-search runs
    Report Presents analyses and comparisons collaboratively

    Authenticate Weights & Biases

    wandb login
    Credential rule: Use an approved authentication method and secret store. Do not place API keys directly in notebooks, scripts, Dockerfiles, or source control.

    Track an Experiment with W&B

    import wandb
    
    
    configuration = {
        "algorithm": "logistic-regression",
        "regularization_strength": 1.0,
        "class_weight": "balanced",
        "decision_threshold": 0.60,
        "random_state": 42,
        "training_data_version": (
            "replace-with-data-version"
        ),
        "feature_definition_version": "1.0.0"
    }
    
    
    with wandb.init(
        entity="replace-with-approved-entity",
        project="customer-churn-experiments",
        name="logistic-regression-balanced",
        config=configuration,
        tags=[
            "binary-classification",
            "candidate",
            "scikit-learn"
        ],
        notes=(
            "Evaluate class weighting using "
            "the approved validation protocol."
        ),
        job_type="training"
    ) as run:
    
        model_pipeline = create_model_pipeline(
            numerical_features=(
                numerical_features
            ),
            categorical_features=(
                categorical_features
            ),
            regularization_strength=(
                run.config[
                    "regularization_strength"
                ]
            ),
            random_state=(
                run.config[
                    "random_state"
                ]
            )
        )
    
        model_pipeline.fit(
            training_features,
            training_labels
        )
    
        validation_probabilities = (
            model_pipeline.predict_proba(
                validation_features
            )[:, 1]
        )
    
        validation_metrics = (
            calculate_metrics(
                true_labels=validation_labels,
                probabilities=(
                    validation_probabilities
                ),
                decision_threshold=(
                    run.config[
                        "decision_threshold"
                    ]
                )
            )
        )
    
        run.log(
            validation_metrics
        )
    
        run.summary[
            "code_version"
        ] = "replace-with-source-revision"
    
        run.summary[
            "validation_status"
        ] = "completed"

    Log Training History with W&B

    with wandb.init(
        entity="replace-with-approved-entity",
        project="neural-network-experiments",
        config={
            "epochs": number_of_epochs,
            "learning_rate": learning_rate
        }
    ) as run:
    
        for epoch in range(
            run.config[
                "epochs"
            ]
        ):
            training_loss = (
                calculate_training_loss(
                    epoch
                )
            )
    
            validation_loss = (
                calculate_validation_loss(
                    epoch
                )
            )
    
            run.log(
                {
                    "epoch": epoch,
                    "training_loss": float(
                        training_loss
                    ),
                    "validation_loss": float(
                        validation_loss
                    )
                }
            )

    Log a Model as a W&B Artifact

    from pathlib import Path
    
    import joblib
    import wandb
    
    
    artifact_directory = Path(
        "experiment-artifacts"
    )
    
    
    artifact_directory.mkdir(
        parents=True,
        exist_ok=True
    )
    
    
    model_path = (
        artifact_directory
        / "customer_churn_pipeline.joblib"
    )
    
    
    joblib.dump(
        model_pipeline,
        model_path
    )
    
    
    model_artifact = wandb.Artifact(
        name="customer-churn-classifier",
        type="model",
        description=(
            "Candidate customer-churn "
            "classification pipeline"
        ),
        metadata={
            "code_version": (
                "replace-with-source-revision"
            ),
            "training_data_version": (
                "replace-with-data-version"
            ),
            "decision_threshold": 0.60,
            "validation_metrics": (
                validation_metrics
            )
        }
    )
    
    
    model_artifact.add_file(
        str(
            model_path
        )
    )
    
    
    run.log_artifact(
        model_artifact
    )
    Artifact requirement: Attach only measured metadata. Do not embed credentials, raw confidential data, or unsupported claims in artifact metadata.

    Track a Dataset as a W&B Artifact

    dataset_artifact = wandb.Artifact(
        name="customer-churn-training-data",
        type="dataset",
        description=(
            "Approved training-data reference "
            "for the churn model"
        ),
        metadata={
            "schema_version": "1.0.0",
            "data_version": (
                "replace-with-data-version"
            ),
            "row_count": int(
                training_features.shape[0]
            ),
            "column_count": int(
                training_features.shape[1]
            )
        }
    )
    
    
    dataset_artifact.add_file(
        "data/training.parquet"
    )
    
    
    run.log_artifact(
        dataset_artifact
    )
    Data-governance rule: Upload a dataset only when the selected W&B environment is approved for that data. Otherwise, log a controlled immutable reference, schema, checksum, and version.

    Log Prediction Samples with a W&B Table

    prediction_table = wandb.Table(
        columns=[
            "record_id",
            "true_label",
            "probability",
            "predicted_label"
        ]
    )
    
    
    for (
        record_id,
        true_label,
        probability
    ) in zip(
        approved_record_identifiers,
        validation_labels,
        validation_probabilities
    ):
        predicted_label = int(
            probability
            >=
            decision_threshold
        )
    
        prediction_table.add_data(
            record_id,
            int(
                true_label
            ),
            float(
                probability
            ),
            predicted_label
        )
    
    
    run.log(
        {
            "validation_predictions": (
                prediction_table
            )
        }
    )
    Privacy caution: Use approved non-sensitive record identifiers. Do not add direct personal identifiers or unnecessary features to experiment tables.

    MLflow vs Weights & Biases

    Area MLflow Weights & Biases
    Core Tracking Unit Run grouped within an experiment Run grouped within a project and entity
    Configuration Parameters and tags Run configuration, tags, notes, and summary
    Metric History Metrics logged with steps or timestamps Run history logged over training steps
    Artifacts General artifacts and logged models Versioned Artifacts with metadata and lineage
    Model Lifecycle Model Registry and logged-model capabilities Model Artifacts and registry-related workflows
    Autologging Supported framework integrations Framework integrations and callbacks
    Visualization Tracking interfaces and run comparison Interactive dashboards, tables, charts, and reports
    Deployment Choice Local, self-managed, or managed integrations depending on setup Available deployment options depend on the selected W&B service configuration
    Selection principle: Evaluate security, hosting, integrations, model lifecycle, visualization, collaboration, governance, cost, portability, and team workflow before selecting a platform.

    What Should You Compare Across Runs?

    Comparison Area Examples
    Data Dataset version, date range, sample count, target rate, and schema
    Features Feature set, transformations, missing-value logic, and availability
    Model Algorithm, architecture, hyperparameters, and initialization
    Quality Precision, recall, F1, calibration, loss, and error analysis
    Groups Metrics across relevant populations and operating segments
    Runtime Duration, CPU, memory, accelerator, and artifact size
    Serving Latency, throughput, startup, memory, and schema compatibility
    Governance Intended use, limitations, approval status, and owner

    Compare Only Compatible Runs

    Confirm Before Ranking Runs

    • The target definition is identical
    • The evaluation dataset is identical or appropriately comparable
    • The split strategy is compatible
    • Metric definitions are identical
    • The positive class is consistent
    • The threshold-selection procedure is consistent
    • Preprocessing semantics are compatible
    • Label maturity is comparable
    • Data leakage has been prevented
    • Relevant operating constraints are comparable
    Invalid Comparison Select the run with the highest F1 even though the runs used different validation populations and thresholds.
    Valid Comparison Compare runs under a shared evaluation protocol and inspect multiple quality, operational, and responsible-use measures.

    Create a Run-Comparison Table

    import pandas as pd
    
    
    def create_run_comparison(
        run_records
    ):
        comparison = pd.DataFrame(
            run_records
        )
    
        required_columns = [
            "run_id",
            "algorithm",
            "data_version",
            "precision",
            "recall",
            "f1",
            "roc_auc",
            "decision_threshold"
        ]
    
        missing_columns = (
            set(required_columns)
            -
            set(comparison.columns)
        )
    
        if missing_columns:
    
            raise ValueError(
                "Missing comparison columns: "
                f"{sorted(missing_columns)}"
            )
    
        return comparison.sort_values(
            by=[
                "f1",
                "recall"
            ],
            ascending=[
                False,
                False
            ]
        )
    Ranking caution: Sorting a comparison table is not automatic model approval. Review error costs, calibration, relevant groups, latency, resources, limitations, and intended use.

    Track a Confusion Matrix

    import matplotlib.pyplot as plt
    from sklearn.metrics import ConfusionMatrixDisplay
    
    
    predicted_labels = (
        validation_probabilities
        >=
        decision_threshold
    ).astype(
        int
    )
    
    
    display = (
        ConfusionMatrixDisplay
        .from_predictions(
            validation_labels,
            predicted_labels
        )
    )
    
    
    figure_path = (
        artifact_directory
        / "confusion_matrix.png"
    )
    
    
    plt.savefig(
        figure_path,
        bbox_inches="tight"
    )
    
    
    plt.close()
    mlflow.log_artifact(
        str(
            figure_path
        ),
        artifact_path="plots"
    )
    run.log(
        {
            "confusion_matrix": (
                wandb.Image(
                    str(
                        figure_path
                    )
                )
            )
        }
    )

    Track Threshold Selection

    A classification threshold can materially change precision, recall, selection rate, and business impact. Track threshold evaluation separately from model training.

    import pandas as pd
    
    
    threshold_rows = []
    
    
    for threshold in [
        0.30,
        0.40,
        0.50,
        0.60,
        0.70
    ]:
        metrics = calculate_metrics(
            true_labels=validation_labels,
            probabilities=(
                validation_probabilities
            ),
            decision_threshold=threshold
        )
    
        threshold_rows.append(
            {
                "threshold": threshold,
                **metrics
            }
        )
    
    
    threshold_report = pd.DataFrame(
        threshold_rows
    )
    
    
    threshold_report.to_csv(
        artifact_directory
        / "threshold_analysis.csv",
        index=False
    )
    Threshold rule: Select thresholds using validation data and approved business criteria. Do not optimize the threshold repeatedly on the final test set.

    Track Cross-Validation Results

    from sklearn.model_selection import cross_validate
    
    
    cross_validation_results = cross_validate(
        estimator=model_pipeline,
        X=training_features,
        y=training_labels,
        cv=5,
        scoring=[
            "precision",
            "recall",
            "f1",
            "roc_auc"
        ],
        return_train_score=False
    )
    
    
    cross_validation_summary = {
        metric_name: float(
            values.mean()
        )
        for metric_name, values in (
            cross_validation_results.items()
        )
        if metric_name.startswith(
            "test_"
        )
    }
    mlflow.log_metrics(
        cross_validation_summary
    )
    run.log(
        cross_validation_summary
    )
    Validation-detail principle: Preserve fold-level results as an artifact when variation across folds is important. A mean alone can hide instability.

    Hyperparameter Sweeps

    A hyperparameter sweep coordinates multiple runs over a defined search space. Each trial should use the same approved evaluation protocol.

    method: random
    
    metric:
      name: validation_f1
      goal: maximize
    
    parameters:
      regularization_strength:
        distribution: log_uniform_values
        min: 0.001
        max: 10.0
    
      class_weight:
        values:
          - balanced
          - null
    
      decision_threshold:
        values:
          - 0.4
          - 0.5
          - 0.6
    Search-space caution: This configuration illustrates structure. Define the actual search space based on model behavior, compute budget, validation design, and approved decision criteria.

    W&B Sweep Training Function

    import wandb
    
    
    def train_sweep_candidate():
    
        with wandb.init() as run:
    
            model_pipeline = (
                create_model_pipeline(
                    numerical_features=(
                        numerical_features
                    ),
                    categorical_features=(
                        categorical_features
                    ),
                    regularization_strength=(
                        run.config[
                            "regularization_strength"
                        ]
                    ),
                    random_state=42
                )
            )
    
            model_pipeline.set_params(
                classifier__class_weight=(
                    run.config[
                        "class_weight"
                    ]
                )
            )
    
            model_pipeline.fit(
                training_features,
                training_labels
            )
    
            probabilities = (
                model_pipeline.predict_proba(
                    validation_features
                )[:, 1]
            )
    
            metrics = calculate_metrics(
                true_labels=validation_labels,
                probabilities=probabilities,
                decision_threshold=(
                    run.config[
                        "decision_threshold"
                    ]
                )
            )
    
            run.log(
                {
                    f"validation_{key}": value
                    for key, value in metrics.items()
                }
            )
    Sweep result: The best sweep trial is still a candidate. It requires independent evaluation and must not be approved using the same data repeatedly used to select it.

    Automatic Logging vs Explicit Logging

    Area Automatic Logging Explicit Logging
    Setup Requires less logging code Requires deliberate calls
    Coverage Captures supported framework information Captures project-specific evidence
    Consistency Can standardize common framework values Depends on implementation discipline
    Control Limited to integration behavior and options Provides direct control over names and content
    Governance Metadata Usually requires additional explicit tracking Can record intended use, owner, and approval directly
    Recommended approach: Use autologging for supported technical information and explicit logging for data versions, hypotheses, thresholds, business context, governance, and conclusions.

    Naming and Tagging Strategy

    Field Example Pattern
    Experiment or Project customer-churn-training
    Run Name logistic-balanced-c1-threshold06
    Task Tag binary-classification
    Purpose Tag threshold-comparison
    Data Tag data-version-2026-01
    Status Tag experimental or candidate
    Owner Tag Approved team or service identity
    Naming principle: Keep names concise and searchable. Store detailed context in tags, configuration, notes, metadata, and reports.

    Team Collaboration

    Collaboration Practices

    • Use shared projects or experiments
    • Standardize metric and parameter names
    • Assign experiment owners
    • Record hypotheses and conclusions
    • Link runs to work items or pull requests
    • Use tags for task and lifecycle status
    • Create reusable comparison reports
    • Document failed experiments
    • Restrict access according to project sensitivity
    • Archive obsolete runs according to policy
    Failed-run value: A failed or unsuccessful experiment can prevent repeated effort when its configuration, error, and conclusion are documented clearly.

    Connect Runs to Source Control

    git rev-parse HEAD
    import subprocess
    
    
    def get_git_commit():
    
        result = subprocess.run(
            [
                "git",
                "rev-parse",
                "HEAD"
            ],
            check=True,
            capture_output=True,
            text=True
        )
    
        return result.stdout.strip()
    
    
    source_revision = get_git_commit()
    mlflow.set_tag(
        "code_version",
        source_revision
    )
    run.summary[
        "code_version"
    ] = source_revision
    Repository-state caution: A commit identifier does not capture uncommitted local changes. Run controlled experiments from a clean, traceable source state.

    Connect Runs to Data Versions

    data_metadata = {
        "training_data_version": (
            "replace-with-training-version"
        ),
        "validation_data_version": (
            "replace-with-validation-version"
        ),
        "test_data_version": (
            "replace-with-test-version"
        ),
        "schema_version": "1.0.0",
        "feature_definition_version": "1.0.0"
    }
    mlflow.set_tags(
        data_metadata
    )
    for key, value in data_metadata.items():
    
        run.summary[
            key
        ] = value

    Record Experiment Conclusions

    {
        "hypothesis": "Class weighting may improve recall.",
        "controlled_change": "classifier class_weight",
        "evaluation_protocol": "approved validation split",
        "result_summary": "Populate from calculated experiment evidence.",
        "decision": "accept, reject, or investigate",
        "limitations": [
            "Populate observed limitations",
            "Do not infer from unmeasured behavior"
        ],
        "next_action": "Populate the approved next step"
    }
    Conclusion principle: Experiment tracking should preserve why a run was performed and what the evidence means, not only its numerical outputs.

    Track Model-Selection Evidence

    Selection Area Evidence to Track
    Baseline Metrics and configuration of the meaningful baseline
    Candidate Metrics and configuration of the proposed model
    Error Analysis Important false positives, false negatives, or residuals
    Calibration Probability reliability and Brier score where relevant
    Group Performance Approved segment-level metrics with sufficient sample sizes
    Operational Performance Latency, memory, throughput, and artifact size
    Limitations Known unsupported data and operating conditions
    Selection Reason Why the candidate is preferred for the intended use

    Integrate Tracking with an ML Pipeline

    Tracked Pipeline Flow
    Start Run → Log Inputs → Train → Log Metrics → Log Artifacts → Record Conclusion → Close Run

    Pipeline Integration Requirements

    • One traceable run identity
    • Pipeline-run identifier
    • Component or child-run relationships
    • Data and code versions
    • Step-specific metrics
    • Final model artifact
    • Evaluation and quality-gate reports
    • Failure status and diagnostics
    • Registry relationship

    Integrate Tracking with CI/CD

    CI/CD Metadata

    • Build identifier
    • Source revision
    • Branch or release reference
    • Pipeline definition version
    • Runner environment
    • Model artifact checksum
    • Container-image digest
    • Quality-gate result
    • Approval status
    • Deployment environment
    ci_metadata = {
        "ci_build_id": (
            environment_build_id
        ),
        "source_revision": (
            source_revision
        ),
        "pipeline_version": "1.0.0",
        "release_status": "candidate"
    }
    
    
    mlflow.set_tags(
        ci_metadata
    )
    Separation principle: Experiment tracking records evidence. The CI/CD quality gates and approval workflow decide whether an artifact may progress.

    Security and Privacy

    Required Controls

    • Use authenticated access
    • Apply project-level authorization
    • Use approved storage locations
    • Encrypt tracking information
    • Keep credentials outside source code
    • Do not log access tokens or passwords
    • Minimize personal and confidential information
    • Review sample predictions before logging them
    • Restrict artifact download access
    • Define retention and deletion policies
    • Audit administrative activity
    • Separate experiment and production permissions
    Unsafe Logging Upload complete raw customer datasets, direct identifiers, access tokens, and unrestricted prediction records for convenience.
    Controlled Logging Record authorized versions, checksums, aggregates, approved samples, and only the information required for reproduction and evaluation.

    Tracking-Server Architecture

    Shared Tracking Flow
    Training Jobs → Tracking API → Metadata Store + Artifact Store → Authorized Users
    Architecture Area Responsibility
    Tracking Client Logs run metadata, metrics, tags, and artifacts
    Tracking Service Receives and presents tracking information
    Metadata Store Stores experiments, runs, parameters, metrics, and tags
    Artifact Store Stores model files, reports, plots, and larger outputs
    Identity Layer Controls who may log, read, modify, or administer records
    Backup and Recovery Protects experiment and artifact history

    Retention and Run Hygiene

    Run-Hygiene Practices

    • Use consistent project and experiment names
    • Tag temporary and smoke-test runs
    • Mark failed runs clearly
    • Record conclusions before closing significant work
    • Remove duplicate artifacts according to policy
    • Archive obsolete experiments
    • Preserve approved and production-related runs
    • Apply retention according to legal and privacy requirements
    • Do not delete evidence related to active incidents
    Retention principle: Keep enough history for reproducibility, comparison, governance, incident response, and rollback without retaining unnecessary or sensitive information indefinitely.

    Responsible Experiment Tracking

    Responsible-AI Evidence

    • Intended and prohibited uses
    • Data authorization and limitations
    • Target definition
    • Prediction-time assumptions
    • Relevant group-level metrics
    • Error analysis
    • Calibration evidence
    • Known model limitations
    • Human-oversight requirements
    • Approval status
    • Model-card artifact
    • Fallback and rollback requirements
    Responsible tracking: Preserve the evidence required to understand not only how well a model performed, but also where it may be used and where it should not be used.

    Common Experiment-Tracking Mistakes

    Mistake Log only the final accuracy.
    Correction Track data, configuration, relevant metrics, artifacts, code, environment, and conclusions.
    Mistake Compare runs evaluated on different datasets as if they were directly equivalent.
    Correction Confirm evaluation compatibility before ranking or selecting runs.
    Mistake Use run names as the only identity.
    Correction Use immutable run identifiers and treat names as readable labels.
    Mistake Log metrics without recording the decision threshold.
    Correction Record the threshold and threshold-selection protocol for classification decisions.
    Mistake Upload sensitive datasets or prediction samples without review.
    Correction Log approved references, metadata, aggregates, or minimized samples.
    Mistake Depend entirely on autologging.
    Correction Add project-specific purpose, data versions, thresholds, limitations, group metrics, and conclusions explicitly.
    Mistake Select the run with the highest single metric automatically.
    Correction Review multiple metrics, error types, calibration, groups, operational requirements, and intended use.
    Mistake Track successful runs but delete all failed runs immediately.
    Correction Preserve useful failure diagnostics and conclusions according to the retention policy.

    Recommended Experiment-Tracking Workflow

    1

    Define the Hypothesis

    State the question, controlled change, expected result, and evaluation protocol.

    2

    Identify the Inputs

    Record code, data, features, configuration, environment, and random-state versions.

    3

    Start a Tracked Run

    Create a run under the correct project or experiment and assign a meaningful name and purpose.

    4

    Log Parameters and Tags

    Record model configuration, data references, ownership, lifecycle status, and intended use.

    5

    Train the Candidate

    Execute the reproducible training workflow and capture runtime information.

    6

    Log Measured Metrics

    Record validation metrics, metric history, threshold evidence, and relevant group results.

    7

    Log Artifacts

    Preserve the model, evaluation reports, plots, schemas, metadata, and model card.

    8

    Compare Compatible Runs

    Review quality, errors, calibration, stability, latency, resources, and limitations.

    9

    Record the Conclusion

    Document whether the hypothesis was supported and what action should follow.

    10

    Register or Reject

    Submit a suitable candidate to the controlled model-lifecycle workflow or preserve the reason for rejection.

    Hands-On Practice

    1

    Create an Experiment Plan

    Define a hypothesis, controlled change, fixed inputs, evaluation metrics, and acceptance criteria.

    2

    Track a Run with MLflow

    Log parameters, calculated validation metrics, tags, model artifact, input example, and model signature.

    3

    Use MLflow Autologging

    Compare the automatically captured information with your project-specific tracking requirements.

    4

    Track the Same Run with W&B

    Log equivalent configuration, metrics, tags, notes, and model artifacts.

    5

    Create a Run Comparison

    Compare compatible models using multiple quality and operational measures.

    6

    Track Threshold Analysis

    Log validation results for several thresholds without using the final test set.

    7

    Track an Artifact

    Version a model or approved dataset reference with metadata and lineage.

    8

    Audit Reproducibility

    Confirm that the selected run identifies its code, data, features, configuration, environment, metrics, and artifacts.

    Knowledge Check

    1

    What is experiment tracking?

    Explain how it records and organizes run inputs, settings, metrics, artifacts, context, and conclusions.

    2

    What is the difference between an experiment and a run?

    Explain that an experiment or project groups related work, while a run represents one execution.

    3

    What is the difference between a parameter and a metric?

    Explain configuration inputs compared with measured outputs.

    4

    What is an experiment artifact?

    Explain saved models, reports, plots, schemas, tables, and other run outputs.

    5

    What does MLflow Tracking record?

    Explain runs, parameters, code versions, metrics, tags, output files, and logged models.

    6

    What does a W&B Run contain?

    Explain configuration, metric history, summary values, tags, notes, tables, and artifacts.

    7

    Why is autologging not always enough?

    Explain project-specific data versions, hypotheses, thresholds, limitations, governance, and conclusions.

    8

    Why should only compatible runs be compared?

    Explain differences in datasets, targets, metrics, splits, thresholds, and label maturity.

    9

    Why track failed experiments?

    Explain troubleshooting, prevention of repeated work, and preservation of useful conclusions.

    10

    Does the best tracked metric automatically identify the production model?

    Explain the need for independent testing, error analysis, calibration, group evaluation, operational checks, security, governance, and approval.

    Experiment-Tracking Readiness Checklist

    Confirm Before Team Adoption

    • Approved tracking infrastructure is selected
    • Authentication and authorization are configured
    • Project and experiment naming standards are documented
    • Run-naming standards are documented
    • Metric names and definitions are standardized
    • Parameter names are standardized
    • Required tags are defined
    • Every run receives an immutable identifier
    • The source-code revision is recorded
    • Training and evaluation data versions are recorded
    • Feature-definition versions are recorded
    • Random states are recorded where applicable
    • Environment versions are recorded
    • Decision thresholds are recorded
    • Actual evaluation metrics are logged
    • Metric history is logged where useful
    • Artifacts are organized consistently
    • Input examples are reviewed for privacy
    • Model signatures or schemas are tracked
    • Failed runs preserve useful diagnostics
    • Experiment conclusions are documented
    • Only compatible runs are compared
    • Hyperparameter searches use an approved validation protocol
    • The final test set remains independent
    • Sensitive data is minimized
    • Credentials are kept out of code and logs
    • Artifact access is restricted
    • Retention and deletion policies are defined
    • Tracked candidates flow into a controlled registry process
    • Experiment history is backed up where required

    Lesson Summary

    Tracking Area Main Outcome
    Experiment Groups related investigations
    Run Represents one tracked execution
    Parameter Records a configuration value
    Metric Records measured model or system behavior
    Metric History Tracks behavior over epochs, steps, or time
    Tag Adds searchable descriptive context
    Artifact Preserves models, reports, plots, schemas, and outputs
    MLflow Tracking Logs experiments, runs, parameters, metrics, tags, and artifacts
    MLflow Autologging Automatically captures supported framework information
    W&B Experiments Tracks configuration, metric history, summaries, and system information
    W&B Artifacts Versions datasets, models, and other experiment outputs
    Run Comparison Supports evidence-based candidate analysis
    Source and Data Lineage Supports reproducibility and investigation
    Security Protects credentials, data, artifacts, and project access
    Governance Preserves hypotheses, limitations, ownership, conclusions, and approval evidence

    Key Takeaway

    Experiment tracking creates an organized and reproducible history of Machine Learning development. Each run should identify the question being tested, the code and data versions, feature definitions, configuration, random state, environment, calculated metrics, generated artifacts, and final conclusion. MLflow provides tracking APIs and interfaces for runs, parameters, metrics, tags, artifacts, logged models, and model lifecycle workflows. Weights & Biases provides run configuration, metric history, dashboards, tables, reports, artifacts, and hyperparameter-sweep workflows. Neither platform replaces sound experiment design. Reliable model selection still requires compatible evaluation conditions, independent testing, error analysis, calibration, relevant group evaluation, operational testing, security review, governance, and controlled approval.

    Get Machine Learning updates by email

    Short, practical lessons and course updates from Rumman Ansari. No spam.