class_docstr: A metric that trains and evaluates an sklearn model.
  
  The evaluation metric is the k-fold "score". The scoring function
  depends on the model type and task type (e.g. classification/regression),
  but higher scores are better.
  
  See sklearn documentation for supported parameters.
  
  In addition, this metric supports tuning the hidden_layer_size
  and the number of hidden layers (num_hidden_layers) of a NN model.
class_docstr_tok: ["A","metric","that","trains","and","evaluates","an","sklearn","model",".","The","evaluation","metric","is","the","k-fold","``","score","''",".","The","scoring","function","depends","on","the","model","type","and","task","type","(","e.g",".","classification\/regression",")",",","but","higher","scores","are","better",".","See","sklearn","documentation","for","supported","parameters",".","In","addition",",","this","metric","supports","tuning","the","hidden_layer_size","and","the","number","of","hidden","layers","(","num_hidden_layers",")","of","a","NN","model","."]
docstr: Train and evaluate model.
  
  Args:
      arm: An arm specifying the parameters to evaluate.
  
  Returns:
     A two-element tuple containing:
      - The average k-fold CV score
      - The SE of the mean k-fold CV score if observed_noise is True
          and 'nan' otherwise
docstr_tok: ["Train","and","evaluate","model",".","Args",":","arm",":","An","arm","specifying","the","parameters","to","evaluate",".","Returns",":","A","two-element","tuple","containing",":","-","The","average","k-fold","CV","score","-","The","SE","of","the","mean","k-fold","CV","score","if","observed_noise","is","True","and","'nan","'","otherwise"]
code: def train_eval(self, arm: Arm) -> Tuple[float, float]:
      """Train and evaluate model.
  
      Args:
          arm: An arm specifying the parameters to evaluate.
  
      Returns:
         A two-element tuple containing:
          - The average k-fold CV score
          - The SE of the mean k-fold CV score if observed_noise is True
              and 'nan' otherwise
      """
      data = _get_data(self.dataset)  # cached
      X, y = data["data"], data["target"]
      params: Dict[str, Any] = deepcopy(arm.parameters)
      if self.model_type == SklearnModelType.NN:
          hidden_layer_size = params.pop("hidden_layer_size", None)
          if hidden_layer_size is not None:
              hidden_layer_size = checked_cast(int, hidden_layer_size)
              num_hidden_layers = checked_cast(
                  int, params.pop("num_hidden_layers", 1)
              )
              params["hidden_layer_sizes"] = [
                  hidden_layer_size
              ] * num_hidden_layers
      model = self._model_cls(**params)
      cv_scores = cross_val_score(model, X, y, cv=self.num_folds)
      mean = cv_scores.mean()
      sem = (
          cv_scores.std() / sqrt(cv_scores.shape[0])
          if self.observed_noise
          else float("nan")
      )
      return mean, sem
  
imports: from __future__ import annotations
  from copy import deepcopy
  from enum import Enum
  from functools import lru_cache
  from math import sqrt
  from typing import Any, Dict, Tuple
  import numpy
  import pandas
  from ax.core.arm import Arm
  from ax.core.base_trial import BaseTrial
  from ax.core.data import Data
  from ax.core.metric import Metric, MetricFetchE, MetricFetchResult
  from ax.utils.common.result import Err, Ok
  from ax.utils.common.typeutils import checked_cast
  from sklearn import datasets
  from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor
  from sklearn.model_selection import cross_val_score
  from sklearn.neural_network import MLPClassifier, MLPRegressor
label_desc: Use image node_id 4 for calling the SklearnMetric obj's underlying member method code with example usage: obj.train_eval(arm) and returns: mean,  sem