code: def to_categorical(
      features, n_categorical, invalid_frac, random_state
  ):
      """returns data in two formats: pandas (for LightGBM) and numpy (for FIL)
      LightGBM needs a DataFrame to recognize and fit on categorical columns.
      Second fp32 output is to test invalid categories for prediction only.
      """
      features = features.copy()  # avoid clobbering source matrix
      rng = np.random.default_rng(
          hash(random_state)
      )  # allow RandomState object
      # the main bottleneck (>80%) of to_categorical() is the pandas operations
      n_features = features.shape[1]
      # all categorical columns
      cat_cols = features[:, :n_categorical]
      # axis=1 means 0th dimension remains. Row-major FIL means 0th dimension is
      # the number of columns. We reduce within columns, across rows.
      cat_cols = cat_cols - cat_cols.min(
          axis=0, keepdims=True
      )  # range [0, ?]
      cat_cols /= cat_cols.max(axis=0, keepdims=True)  # range [0, 1]
      rough_n_categories = 100
      # round into rough_n_categories bins
      cat_cols = (cat_cols * rough_n_categories).astype(int)
  
      # mix categorical and numerical columns
      new_col_idx = rng.choice(
          n_features, n_features, replace=False, shuffle=True
      )
      df_cols = {}
      for icol in range(n_categorical):
          col = cat_cols[:, icol]
          df_cols[new_col_idx[icol]] = pd.Series(
              pd.Categorical(col, categories=np.unique(col))
          )
      # all numerical columns
      for icol in range(n_categorical, n_features):
          df_cols[new_col_idx[icol]] = pd.Series(features[:, icol])
      fit_df = pd.DataFrame(df_cols)
  
      # randomly inject invalid categories only into predict_matrix
      invalid_idx = rng.choice(
          a=cat_cols.size,
          size=ceil(cat_cols.size * invalid_frac),
          replace=False,
          shuffle=False,
      )
      cat_cols.flat[invalid_idx] += rough_n_categories
      # mix categorical and numerical columns
      predict_matrix = np.concatenate(
          [cat_cols, features[:, n_categorical:]], axis=1
      )
      predict_matrix[:, new_col_idx] = predict_matrix
  
      return fit_df, predict_matrix
  
imports: from sklearn.model_selection import train_test_split
  from sklearn.metrics import accuracy_score, mean_squared_error
  from sklearn.ensemble import GradientBoostingClassifier, GradientBoostingRegressor, RandomForestClassifier, RandomForestRegressor, ExtraTreesClassifier, ExtraTreesRegressor
  from sklearn.datasets import make_classification, make_regression
  from cuml.internals.import_utils import has_xgboost
  from cuml.testing.utils import array_equal, unit_param, quality_param, stress_param
  from cuml import ForestInference
  from math import ceil
  import os
  import pytest
  from cuml.internals.safe_imports import cpu_only_import
label_desc: Use image node_id 16 for calling a global function with example usage: to_categorical(features, n_categorical, invalid_frac, random_state) and returns: fit_df,  predict_matrix