code: def create_default_config(
      features_config: ModelConfigDict,
      dataset_info: DatasetInfo,
      target_name: Union[str, List[str]],
      time_limit_s: Union[int, float],
      random_seed: int,
      imbalance_threshold: float = 0.9,
      backend: Backend = None,
  ) -> dict:
      """Returns auto_train configs for three available combiner models. Coordinates the following tasks:
  
      - extracts fields and generates list of FieldInfo objects
      - gets field metadata (i.e avg. words, total non-null entries)
      - builds input_features and output_features section of config
      - for imbalanced datasets, a preprocessing section is added to perform stratified sampling if the imbalance ratio
        is smaller than imbalance_threshold
      - for each combiner, adds default training, hyperopt
      - infers resource constraints and adds gpu and cpu resource allocation per
        trial
  
      # Inputs
      :param dataset_info: (str) filepath Dataset Info object.
      :param target_name: (str, List[str]) name of target feature
      :param time_limit_s: (int, float) total time allocated to auto_train. acts
                                      as the stopping parameter
      :param random_seed: (int, default: `42`) a random seed that will be used anywhere
                          there is a call to a random number generator, including
                          hyperparameter search sampling, as well as data splitting,
                          parameter initialization and training set shuffling
      :param imbalance_threshold: (float) maximum imbalance ratio (minority / majority) to perform stratified sampling
      :param backend: (Backend) backend to use for training.
  
      # Return
      :return: (dict) dictionaries contain auto train config files for all available
      combiner types
      """
      base_automl_config = load_yaml(BASE_AUTOML_CONFIG)
      base_automl_config.update(features_config)
  
      targets = convert_targets(target_name)
      features_metadata = get_field_metadata(
          dataset_info.fields, dataset_info.row_count, targets
      )
  
      # Handle expensive features for CPU
      resources = backend.get_available_resources()
      for ifeature in base_automl_config[INPUT_FEATURES]:
          if resources.gpus == 0:
              if ifeature[TYPE] == TEXT:
                  # When no GPUs are available, default to the embed encoder, which is fast enough for CPU
                  ifeature[ENCODER] = {"type": "embed"}
  
      # create set of all feature types appearing in the dataset
      feature_types = [
          [feat[TYPE] for feat in features]
          for features in features_config.values()
      ]
      feature_types = set(sum(feature_types, []))
  
      model_configs = {}
  
      # update hyperopt config
      experiment_resources = allocate_experiment_resources(resources)
      base_automl_config = merge_dict(
          base_automl_config,
          get_resource_aware_hyperopt_config(
              experiment_resources, time_limit_s, random_seed
          ),
      )
  
      # add preprocessing section if single output feature is imbalanced
      outputs_metadata = [
          f for f in features_metadata if f.mode == "output"
      ]
      if len(outputs_metadata) == 1:
          of_meta = outputs_metadata[0]
          is_categorical = of_meta.config.type in ["category", "binary"]
          is_imbalanced = of_meta.imbalance_ratio < imbalance_threshold
          if is_categorical and is_imbalanced:
              base_automl_config.update(
                  _get_stratify_split_config(of_meta)
              )
  
      model_configs["base_config"] = base_automl_config
  
      # read in all encoder configs
      for feat_type, default_configs in encoder_defaults.items():
          if feat_type in feature_types:
              if feat_type not in model_configs.keys():
                  model_configs[feat_type] = {}
              for (
                  encoder_name,
                  encoder_config_path,
              ) in default_configs.items():
                  model_configs[feat_type][encoder_name] = load_yaml(
                      encoder_config_path
                  )
  
      # read in all combiner configs
      model_configs[COMBINER] = {}
      for combiner_type, default_config in combiner_defaults.items():
          combiner_config = load_yaml(default_config)
          model_configs[COMBINER][combiner_type] = combiner_config
  
      return model_configs
  
imports: import logging
  import os
  from dataclasses import dataclass
  from typing import Any, Dict, List, Set, Union
  import dask.dataframe
  import numpy
  import pandas
  import yaml
  from dataclasses_json import dataclass_json, LetterCase
  from tqdm import tqdm
  from ludwig.api_annotations import DeveloperAPI
  from ludwig.backend import Backend
  from ludwig.constants import COLUMN, COMBINER, ENCODER, EXECUTOR, HYPEROPT, INPUT_FEATURES, PREPROCESSING, SCHEDULER, SEARCH_ALG, SPLIT, TEXT, TYPE
  from ludwig.types import ModelConfigDict
  from ludwig.utils.automl.data_source import DataSource, wrap_data_source
  from ludwig.utils.automl.field_info import FieldConfig, FieldInfo, FieldMetadata
  from ludwig.utils.automl.type_inference import infer_type, should_exclude
  from ludwig.utils.data_utils import load_yaml
  from ludwig.utils.misc_utils import merge_dict
  from ludwig.utils.system_utils import Resources
label_desc: Use image node_id 5 for calling a global function with example usage: create_default_config(features_config, dataset_info, target_name, time_limit_s, random_seed, imbalance_threshold, backend) and returns: model_configs