code: def run_api_experiment(input_features, output_features, data_csv):
      """
      Helper method to avoid code repetition in running an experiment
      :param input_features: input schema
      :param output_features: output schema
      :param data_csv: path to data
      :return: None
      """
      config = {
          "input_features": input_features,
          "output_features": output_features,
          "combiner": {"type": "concat", "fc_size": 14},
          "training": {"epochs": 2},
      }
  
      model = LudwigModel(config)
      output_dir = None
  
      try:
          # Training with csv
          _, _, output_dir = model.train(
              dataset=data_csv,
              skip_save_processed_input=True,
              skip_save_progress=True,
              skip_save_unprocessed_output=True,
          )
          model.predict(dataset=data_csv)
  
          model_dir = os.path.join(output_dir, "model")
          loaded_model = LudwigModel.load(model_dir)
  
          # Necessary before call to get_weights() to materialize the weights
          loaded_model.predict(dataset=data_csv)
  
          model_weights = model.model.get_weights()
          loaded_weights = loaded_model.model.get_weights()
          for model_weight, loaded_weight in zip(
              model_weights, loaded_weights
          ):
              assert np.allclose(model_weight, loaded_weight)
      finally:
          # Remove results/intermediate data saved to disk
          shutil.rmtree(output_dir, ignore_errors=True)
  
      try:
          # Training with dataframe
          data_df = read_csv(data_csv)
          _, _, output_dir = model.train(
              dataset=data_df,
              skip_save_processed_input=True,
              skip_save_progress=True,
              skip_save_unprocessed_output=True,
          )
          model.predict(dataset=data_df)
      finally:
          shutil.rmtree(output_dir, ignore_errors=True)
  
imports: import multiprocessing
  import os
  import random
  import shutil
  import sys
  import traceback
  import unittest
  import uuid
  from distutils.util import strtobool
  import cloudpickle
  import numpy
  import pandas
  from ludwig.api import LudwigModel
  from ludwig.backend import LocalBackend
  from ludwig.constants import VECTOR, COLUMN, NAME, PROC_COLUMN
  from ludwig.data.dataset_synthesizer import DATETIME_FORMATS
  from ludwig.data.dataset_synthesizer import build_synthetic_dataset
  from ludwig.experiment import experiment_cli
  from ludwig.features.feature_utils import compute_feature_hash
  from ludwig.utils.data_utils import read_csv, replace_file_extension
label_desc: Use image node_id 22 for calling a global function with example usage: run_api_experiment(input_features, output_features, data_csv) without return types