class_docstr: Automagic DGL models from Graphistry Instances.
class_docstr_tok: ["Automagic","DGL","models","from","Graphistry","Instances","."]
docstr: Builds GNN model using (DGL)[https://www.dgl.ai/]
  
  Will auto-featurize, and if no explicit edges are found, automatically UMAP to produce implicit edges.
  ________________________________________________________________________________________________________________
  
  :param X_nodes: Which node dataframe columns to featurize. If None, will use all columns.
          If passing in explicit dataframe, will set them as attributes.
  :param X_edges: Which edge dataframe columns to featurize. If None, will use all columns.
          If passing in explicit dataframe, will set them as attributes.
  :param y_nodes: Optional target column from nodes dataframe.
  :param y_edges: Optional target column from edges dataframe
  :param weight_column: Optional Weight column if explicit edges table exists with said weights.
          Otherwise, weight_column is inhereted by UMAP.
  :param train_split: Randomly assigns a train and test mask according to the split value, default 80%.
  :param use_node_scaler: selects which scaling to use on featurized nodes dataframe. Default None
  :param use_edge_scaler: selects which scaling to use on featurized edges dataframe. Default None
  :param device: device to run model, default `cpu`, with `gpu` the other choice. Can be handled in outer scope.
  :param inplace: default, False, whether to return Graphistry instance in place or not.
docstr_tok: ["Builds","GNN","model","using","(","DGL",")","[","https",":","\/\/www.dgl.ai\/","]","Will","auto-featurize",",","and","if","no","explicit","edges","are","found",",","automatically","UMAP","to","produce","implicit","edges",".","________________________________________________________________________________________________________________",":","param","X_nodes",":","Which","node","dataframe","columns","to","featurize",".","If","None",",","will","use","all","columns",".","If","passing","in","explicit","dataframe",",","will","set","them","as","attributes",".",":","param","X_edges",":","Which","edge","dataframe","columns","to","featurize",".","If","None",",","will","use","all","columns",".","If","passing","in","explicit","dataframe",",","will","set","them","as","attributes",".",":","param","y_nodes",":","Optional","target","column","from","nodes","dataframe",".",":","param","y_edges",":","Optional","target","column","from","edges","dataframe",":","param","weight_column",":","Optional","Weight","column","if","explicit","edges","table","exists","with","said","weights",".","Otherwise",",","weight_column","is","inhereted","by","UMAP",".",":","param","train_split",":","Randomly","assigns","a","train","and","test","mask","according","to","the","split","value",",","default","80","%",".",":","param","use_node_scaler",":","selects","which","scaling","to","use","on","featurized","nodes","dataframe",".","Default","None",":","param","use_edge_scaler",":","selects","which","scaling","to","use","on","featurized","edges","dataframe",".","Default","None",":","param","device",":","device","to","run","model",",","default","`","cpu","`",",","with","`","gpu","`","the","other","choice",".","Can","be","handled","in","outer","scope",".",":","param","inplace",":","default",",","False",",","whether","to","return","Graphistry","instance","in","place","or","not","."]
code: def build_gnn(
      self,
      X_nodes: XSymbolic = None,
      X_edges: XSymbolic = None,
      y_nodes: YSymbolic = None,
      y_edges: YSymbolic = None,
      weight_column: Optional[str] = None,
      reuse_if_existing: bool = True,
      featurize_edges: bool = True,
      use_node_scaler: Optional[str] = None,
      use_node_scaler_target: Optional[str] = None,
      use_edge_scaler: Optional[str] = None,
      use_edge_scaler_target: Optional[str] = None,
      train_split: float = 0.8,
      device: str = "cpu",
      inplace: bool = False,
      *args,
      **kwargs,
  ):
      """
      Builds GNN model using (DGL)[https://www.dgl.ai/]
  
      Will auto-featurize, and if no explicit edges are found, automatically UMAP to produce implicit edges.
      ________________________________________________________________________________________________________________
  
      :param X_nodes: Which node dataframe columns to featurize. If None, will use all columns.
              If passing in explicit dataframe, will set them as attributes.
      :param X_edges: Which edge dataframe columns to featurize. If None, will use all columns.
              If passing in explicit dataframe, will set them as attributes.
      :param y_nodes: Optional target column from nodes dataframe.
      :param y_edges: Optional target column from edges dataframe
      :param weight_column: Optional Weight column if explicit edges table exists with said weights.
              Otherwise, weight_column is inhereted by UMAP.
      :param train_split: Randomly assigns a train and test mask according to the split value, default 80%.
      :param use_node_scaler: selects which scaling to use on featurized nodes dataframe. Default None
      :param use_edge_scaler: selects which scaling to use on featurized edges dataframe. Default None
      :param device: device to run model, default `cpu`, with `gpu` the other choice. Can be handled in outer scope.
      :param inplace: default, False, whether to return Graphistry instance in place or not.
  
      """
      if inplace:
          res = self
      else:
          res = self.bind()
  
      res.dgl_lazy_init(train_split=train_split, device=device)
  
      try:
          m = res.materialize_nodes()
      except Exception as e:
          logger.debug(e)
          logger.info(
              "No edges found, please call g.umap(...) to generate implicit edges"
          )
          raise
  
      X_nodes_resolved = resolve_X(m._nodes, X_nodes)
      y_nodes_resolved = resolve_y(m._nodes, y_nodes)
  
      # here we check if edges are from UMAP, at which point X_edges should be none:
      if list(res._edges.columns) == [
          "_src_implicit",
          "_dst_implicit",
          "_weight",
      ]:
          logger.debug(
              ">>> EDGES ARE FROM UMAP, discarding explicit mention of X_edges"
          )
          X_edges = None
  
      X_edges_resolved = resolve_X(res._edges, X_edges)
      y_edges_resolved = resolve_y(res._edges, y_edges)
  
      if hasattr(res, "_MASK"):
          if y_edges_resolved is not None:
              y_edges_resolved = y_edges_resolved[
                  res._MASK  # type: ignore
              ]  # automatically prune target using mask
              # note, edf, ndf, should both have unique indices
  
      # here we make node and edge features and add them to the DGL graph instance
      res = res._convert_edge_dataframe_to_DGL(weight_column, inplace)
  
      kwargs_nodes = self.convert_kwargs(
          X=X_nodes_resolved,
          y=y_nodes_resolved,
          use_scaler=use_node_scaler,
          use_scaler_target=use_node_scaler_target,
          reuse_if_existing=reuse_if_existing,
          *args,
          **kwargs,
      )
  
      res = res._featurize_nodes_to_dgl(res, **kwargs_nodes)
  
      kwargs_edges = self.convert_kwargs(
          X=X_edges_resolved,
          y=y_edges_resolved,
          use_scaler=use_edge_scaler,
          use_scaler_target=use_edge_scaler_target,
          reuse_if_existing=reuse_if_existing,
          *args,
          **kwargs,
      )
      if featurize_edges:
          res = res._featurize_edges_to_dgl(res, **kwargs_edges)
      if not inplace:
          return res
  
imports: from collections import Counter
  from typing import Dict, Optional, TYPE_CHECKING, Tuple
  import numpy
  import pandas
  from .None import constants
  from .feature_utils import FeatureEngine, FeatureMixin, resolve_feature_engine, XSymbolic, YSymbolic, resolve_X, resolve_y
  from .util import setup_logger
label_desc: Use image node_id 10 for calling the DGLGraphMixin obj's underlying member method code with example usage: obj.build_gnn(X_nodes, X_edges, y_nodes, y_edges, weight_column, reuse_if_existing, featurize_edges, use_node_scaler, use_node_scaler_target, use_edge_scaler, use_edge_scaler_target, train_split, device, inplace) and returns: res