class_docstr: LightGCN model
  
  :Citation:
  
      He, Xiangnan, Kuan Deng, Xiang Wang, Yan Li, Yongdong Zhang, and Meng Wang.
      "LightGCN: Simplifying and Powering Graph Convolution Network for Recommendation." arXiv
      preprint arXiv:2002.02126, 2020.
docstr: Fit the model on self.data.train. If eval_epoch is not -1, evaluate the model on `self.data.test`
  every `eval_epoch` epoch to observe the training status.
docstr_tok: ["Fit","the","model","on","self.data.train",".","If","eval_epoch","is","not","-1",",","evaluate","the","model","on","`","self.data.test","`","every","`","eval_epoch","`","epoch","to","observe","the","training","status","."]
code: def fit(self):
      """Fit the model on self.data.train. If eval_epoch is not -1, evaluate the model on `self.data.test`
      every `eval_epoch` epoch to observe the training status.
  
      """
      for epoch in range(1, self.epochs + 1):
          train_start = time.time()
          loss, mf_loss, emb_loss = 0.0, 0.0, 0.0
          n_batch = self.data.train.shape[0] // self.batch_size + 1
          for idx in range(n_batch):
              users, pos_items, neg_items = self.data.train_loader(
                  self.batch_size
              )
              (
                  _,
                  batch_loss,
                  batch_mf_loss,
                  batch_emb_loss,
              ) = self.sess.run(
                  [self.opt, self.loss, self.mf_loss, self.emb_loss],
                  feed_dict={
                      self.users: users,
                      self.pos_items: pos_items,
                      self.neg_items: neg_items,
                  },
              )
              loss += batch_loss / n_batch
              mf_loss += batch_mf_loss / n_batch
              emb_loss += batch_emb_loss / n_batch
  
          if np.isnan(loss):
              print("ERROR: loss is nan.")
              sys.exit()
          train_end = time.time()
          train_time = train_end - train_start
  
          if self.save_model and epoch % self.save_epoch == 0:
              save_path_str = os.path.join(
                  self.model_dir, "epoch_" + str(epoch)
              )
              if not os.path.exists(save_path_str):
                  os.makedirs(save_path_str)
              checkpoint_path = self.saver.save(  # noqa: F841
                  sess=self.sess, save_path=save_path_str
              )
              print(
                  "Save model to path {0}".format(
                      os.path.abspath(save_path_str)
                  )
              )
  
          if self.eval_epoch == -1 or epoch % self.eval_epoch != 0:
              print(
                  "Epoch %d (train)%.1fs: train loss = %.5f = (mf)%.5f + (embed)%.5f"
                  % (epoch, train_time, loss, mf_loss, emb_loss)
              )
          else:
              eval_start = time.time()
              ret = self.run_eval()
              eval_end = time.time()
              eval_time = eval_end - eval_start
  
              print(
                  "Epoch %d (train)%.1fs + (eval)%.1fs: train loss = %.5f = (mf)%.5f + (embed)%.5f, %s"
                  % (
                      epoch,
                      train_time,
                      eval_time,
                      loss,
                      mf_loss,
                      emb_loss,
                      ", ".join(
                          metric + " = %.5f" % (r)
                          for metric, r in zip(self.metrics, ret)
                      ),
                  )
              )
  
imports: import tensorflow
  import time
  import os
  import sys
  import numpy
  import pandas
  from recommenders.evaluation.python_evaluation import map_at_k, ndcg_at_k, precision_at_k, recall_at_k
  from recommenders.utils.python_utils import get_top_k_scored_items
label_desc: Use image node_id 6 for calling the LightGCN obj's underlying member method code with example usage: obj.fit() without return types