class_docstr: This class defines the interface for any surrogate model which attempts to
  predict performance metrics from model configurations.
  
  Subclasses may decide to only predict some performance metrics.
class_docstr_tok: ["This","class","defines","the","interface","for","any","surrogate","model","which","attempts","to","predict","performance","metrics","from","model","configurations",".","Subclasses","may","decide","to","only","predict","some","performance","metrics","."]
docstr: Uses the provided data to fit a model which is able to predict the
  target variables from the input.
  
  Args:
      X: The input configurations.
      y: The performance values associated with the input configurations.
docstr_tok: ["Uses","the","provided","data","to","fit","a","model","which","is","able","to","predict","the","target","variables","from","the","input",".","Args",":","X",":","The","input","configurations",".","y",":","The","performance","values","associated","with","the","input","configurations","."]
code: def fit(self, X: list[Config[T]], y: list[Performance]) -> None:
      """
      Uses the provided data to fit a model which is able to predict the
      target variables from the input.
  
      Args:
          X: The input configurations.
          y: The performance values associated with the input configurations.
      """
      y_numpy = self.performance_transformer.fit_transform(y)
  
      # If we apply any normalization, we do so independently per dataset
      if self.output_normalization is not None:
          # Initialize the transformer
          if self.output_normalization == "quantile":
              transformer = QuantileTransformer()
          else:
              transformer = StandardScaler()
  
          # Assign indices according to datasets
          encoder = LabelEncoder()
          dataset_indices = encoder.fit_transform(
              [x.dataset.name() for x in X]
          )
  
          # Then, iterate over datasets and transform the objectives
          result = np.empty_like(y_numpy)
          for i in range(len(encoder.classes_)):
              mask = dataset_indices == i
              result[mask] = transformer.fit_transform(y_numpy[mask])
  
          # And eventually re-assign the result
          y_numpy = result
  
      self._fit(X, y_numpy)
  
imports: from __future__ import annotations
  from abc import ABC, abstractmethod
  from typing import Generic, List, Literal, Optional, TypeVar
  import numpy
  import numpy.typing
  from sklearn.preprocessing import LabelEncoder, QuantileTransformer, StandardScaler
  from tsbench.config import Config, EnsembleConfig, ModelConfig
  from tsbench.evaluations.metrics import Performance
  from tsbench.evaluations.tracking import Tracker
  from .transformers import PerformanceTransformer
label_desc: Use image node_id 4 for calling the Surrogate obj's underlying member method code with example usage: obj.fit(X, y) without return types