code: def get_model_matrix(
      g, kind: str, cols: Optional[Union[List, str]], umap, target
  ):
      """
          Allows for a single function to get the model matrix for both nodes and edges as well as targets, embeddings, and features
  
      Args:
              :g: graphistry graph
              :kind: 'nodes' or 'edges'
              :cols: list of columns to use for clustering given `g.featurize` has been run
              :umap: whether to use UMAP embeddings or features dataframe
              :target: whether to use the target dataframe or features dataframe
  
      Returns:
          pd.DataFrame: dataframe of model matrix given the inputs
      """
      assert kind in ["nodes", "edges"]
      assert (
          hasattr(g, "_node_encoder")
          if kind == "nodes"
          else hasattr(g, "_edge_encoder")
      )
  
      df = g.get_matrix(cols, kind=kind, target=target)
  
      if umap and cols is None and g._umap is not None:
          df = g._get_embedding(kind)
  
      # if g.engine_dbscan in [CUML]:
      df, _ = make_safe_gpu_dataframes(df, None, g.engine_dbscan)
      # print('\n df:', df.shape, df.columns)
      return df
  
imports: import logging
  import pandas
  import numpy
  from typing import Any, List, Union, TYPE_CHECKING, Tuple, Optional
  from typing_extensions import Literal
  from collections import Counter
  from graphistry.Plottable import Plottable
  from graphistry.constants import CUML, UMAP_LEARN, DBSCAN
  from graphistry.features import ModelDict
  from graphistry.feature_utils import get_matrix_by_column_parts
label_desc: Use image node_id 5 for calling a global function with example usage: get_model_matrix(g, kind, cols, umap, target) and returns: df