code: def shap_strategy(draw):
      task = draw(st.sampled_from(["regression", "classification"]))
  
      n_estimators = draw(st.integers(1, 16))
      n_samples = draw(st.integers(2, 100))
      n_features = draw(st.integers(2, 100))
      learner = draw(st.sampled_from(["xgb", "rf", "skl_rf", "lgbm"]))
      supports_categorical = learner in ["xgb", "lgbm"]
      supports_nan = learner in ["xgb", "lgbm"]
      if task == "classification":
          n_targets = draw(st.integers(2, 5))
      else:
          n_targets = 1
      n_targets = min(n_targets, n_features)
      n_targets = min(n_targets, n_samples)
  
      has_categoricals = draw(st.booleans()) and supports_categorical
      dtype = draw(st.sampled_from([np.float32, np.float64]))
      if has_categoricals:
          n_categorical = draw(st.integers(1, n_features))
      else:
          n_categorical = 0
  
      has_nan = not has_categoricals and supports_nan
  
      # Filter issues and invalid examples here
      if task == "classification" and learner == "rf":
          # No way to predict_proba with RandomForestClassifier
          # trained on 64-bit data
          # https://github.com/rapidsai/cuml/issues/4663
          assume(dtype == np.float32)
      if task == "regression" and learner == "skl_rf":
          # multi-output regression not working
          # https://github.com/dmlc/treelite/issues/375
          assume(n_targets == 1)
  
      # treelite considers a binary classification model to have
      # n_classes=1, which produces an unexpected output shape
      # in the shap values
      if task == "classification" and learner == "skl_rf":
          assume(n_targets > 2)
  
      # ensure we get some variation in test datasets
      dataset_seed = draw(st.integers(1, 5))
      if task == "classification":
          X, y = make_classification_with_categorical(
              n_samples=n_samples,
              n_features=n_features,
              n_categorical=n_categorical,
              n_informative=n_features,
              n_redundant=0,
              n_repeated=0,
              random_state=dataset_seed,
              n_classes=n_targets,
              numeric_dtype=dtype,
          )
      else:
          X, y = make_regression_with_categorical(
              n_samples=n_samples,
              n_features=n_features,
              n_categorical=n_categorical,
              n_informative=n_features,
              random_state=dataset_seed,
              numeric_dtype=dtype,
              n_targets=n_targets,
          )
  
      if has_nan:
          # set about half the first column to nan
          X.iloc[
              np.random.randint(0, n_samples, n_samples // 2), 0
          ] = np.nan
  
      assert (
          len(X.select_dtypes(include="category").columns)
          == n_categorical
      )
  
      model, preds = learn_model(
          draw, X, y, task, learner, n_estimators, n_targets
      )
  
      # convert any DataFrame categorical columns to numeric
      return X.astype(dtype), y.astype(dtype), model, preds
  
imports: from cuml.testing.utils import as_type
  import cuml
  from cuml.ensemble import RandomForestClassifier
  from cuml.ensemble import RandomForestRegressor
  from cuml.common.exceptions import NotFittedError
  from cuml.internals.import_utils import has_sklearn
  from cuml.internals.import_utils import has_lightgbm, has_shap
  from cuml.explainer.tree_shap import TreeExplainer
  from hypothesis import given, settings, assume, HealthCheck, strategies
  from cuml.internals.safe_imports import gpu_only_import
  import json
  import pytest
  import treelite
  from cuml.internals.safe_imports import cpu_only_import
label_desc: Use image node_id 18 for calling a global function with example usage: shap_strategy(draw) and returns: X,  y,  model,  preds