Source code for stream.utils.benchmarking

from inspect import signature
from typing import Any, Callable, Dict, List, Optional

import numpy as np

from .dataset import TMDataset

__all__ = ["benchmarking"]


[docs]def benchmarking( models: List[Any], num_topics: int, metrics: List[Callable[..., Any]], model_args: Optional[List[Dict[str, Any]]] = None, metric_args: List[Dict[str, Any]] = None, dataset: TMDataset = None, embedding_model_name: str = "all-MiniLM-L6-v2", ) -> Dict[str, Dict[str, float]]: """ Benchmark multiple models against specified metrics. Initialization parameters for models are handled dynamically to accommodate different model requirements. Parameters: - models : List of model instances to benchmark. - num_topics : Integer specifying the number of topics for models that require it. - metrics : List of metric functions to evaluate the models. - model_args : Optional list of dictionaries with initialization parameters for each model. - metric_args : List of dictionaries containing arguments for each metric function. - dataset : The dataset to train the models on. - embedding_model_name : Default embedding model name, used if applicable. Returns: - A dictionary mapping model names to another dictionary of metric names and their corresponding scores. """ if model_args is None: model_args = [{}] * len(models) if metric_args is None: metric_args = [{}] * len(metrics) results = {} metric_instances = [] for metric, m_args in zip(metrics, metric_args): try: # Ensure n_topics is included in metric arguments if the metric requires it metric_params = signature(metric).parameters if "n_topics" in metric_params: m_args.setdefault("n_topics", num_topics) if "dataset" in metric_params: m_args.setdefault("dataset", dataset) if "measure" in metric_params: m_args.setdefault("measure", "u_mass") # Initialize metric with specific arguments filtered_m_args = {k: v for k, v in m_args.items() if k in metric_params} metric_instances.append(metric(**filtered_m_args)) except Exception as e: print(f"Error processing metric {metric.__name__}: {e}") for model, args in zip(models, model_args): results[str(model).split(".")[-2]] = {} # Ensure num_topics is included in the arguments args.setdefault("num_topics", num_topics) # Set default embedding model name if necessary and applicable if ( "embedding_model_name" in signature(model).parameters and "embedding_model_name" not in args ): args["embedding_model_name"] = embedding_model_name elif "bert_model" in signature(model).parameters and "bert_model" not in args: args["bert_model"] = embedding_model_name if str(model).split(".")[-2] == "som": m = int(np.sqrt(num_topics)) n = int(np.sqrt(num_topics)) args.setdefault("m", m) args.setdefault("n", n) print(m, n) # Initialize model with specific arguments, using only keys that exist in model's constructor model_init_params = signature(model).parameters filtered_args = {k: v for k, v in args.items() if k in model_init_params} initialized_model = model(**filtered_args) output = initialized_model.train_model(dataset) for metric_instance in metric_instances: score = metric_instance.score(output) results[str(model).split(".")[-2]][ str(metric_instance).split(".")[-1].split(" ")[0] ] = score return results