class_docstr: RippleNet is an knowledge enhanced matrix factorization model.
  The original interaction matrix of :math:`n_{users} \times n_{items}`
  and related knowledge graph is set as model input,
  we carefully design the data interface and use ripple set to train and test efficiently.
  We just implement the model following the original author with a pointwise training mode.
class_docstr_tok: ["RippleNet","is","an","knowledge","enhanced","matrix","factorization","model",".","The","original","interaction","matrix","of",":","math",":","`","n_","{","users","}","\\times","n_","{","items","}","`","and","related","knowledge","graph","is","set","as","model","input",",","we","carefully","design","the","data","interface","and","use","ripple","set","to","train","and","test","efficiently",".","We","just","implement","the","model","following","the","original","author","with","a","pointwise","training","mode","."]
docstr: Get the normalized interaction matrix of users and items according to A_values.
  Get the ripple hop-wise ripple set for every user, w.r.t. their interaction history
  
  Returns:
      ripple_set (dict)
docstr_tok: ["Get","the","normalized","interaction","matrix","of","users","and","items","according","to","A_values",".","Get","the","ripple","hop-wise","ripple","set","for","every","user",",","w.r.t",".","their","interaction","history","Returns",":","ripple_set","(","dict",")"]
code: def _build_ripple_set(self):
      r"""Get the normalized interaction matrix of users and items according to A_values.
      Get the ripple hop-wise ripple set for every user, w.r.t. their interaction history
  
      Returns:
          ripple_set (dict)
      """
      ripple_set = collections.defaultdict(list)
      n_padding = 0
      for user in self.user_dict:
          for h in range(self.n_hop):
              memories_h = []
              memories_r = []
              memories_t = []
  
              if h == 0:
                  tails_of_last_hop = self.user_dict[user]
              else:
                  tails_of_last_hop = ripple_set[user][-1][2]
  
              for entity in tails_of_last_hop:
                  if entity not in self.kg:
                      continue
                  for tail_and_relation in self.kg[entity]:
                      memories_h.append(entity)
                      memories_r.append(tail_and_relation[1])
                      memories_t.append(tail_and_relation[0])
  
              # if the current ripple set of the given user is empty,
              # we simply copy the ripple set of the last hop here
              if len(memories_h) == 0:
                  if h == 0:
                      # self.logger.info("user {} without 1-hop kg facts, fill with padding".format(user))
                      # raise AssertionError("User without facts in 1st hop")
                      n_padding += 1
                      memories_h = [0 for _ in range(self.n_memory)]
                      memories_r = [0 for _ in range(self.n_memory)]
                      memories_t = [0 for _ in range(self.n_memory)]
                      memories_h = torch.LongTensor(memories_h).to(
                          self.device
                      )
                      memories_r = torch.LongTensor(memories_r).to(
                          self.device
                      )
                      memories_t = torch.LongTensor(memories_t).to(
                          self.device
                      )
                      ripple_set[user].append(
                          (memories_h, memories_r, memories_t)
                      )
                  else:
                      ripple_set[user].append(ripple_set[user][-1])
              else:
                  # sample a fixed-size 1-hop memory for each user
                  replace = len(memories_h) < self.n_memory
                  indices = np.random.choice(
                      len(memories_h),
                      size=self.n_memory,
                      replace=replace,
                  )
                  memories_h = [memories_h[i] for i in indices]
                  memories_r = [memories_r[i] for i in indices]
                  memories_t = [memories_t[i] for i in indices]
                  memories_h = torch.LongTensor(memories_h).to(
                      self.device
                  )
                  memories_r = torch.LongTensor(memories_r).to(
                      self.device
                  )
                  memories_t = torch.LongTensor(memories_t).to(
                      self.device
                  )
                  ripple_set[user].append(
                      (memories_h, memories_r, memories_t)
                  )
      self.logger.info(
          "{} among {} users are padded".format(
              n_padding, len(self.user_dict)
          )
      )
      return ripple_set
  
file_path: RecBole/recbole/model/knowledge_aware_recommender/ripplenet.py
imports: import collections
  import numpy
  import torch
  import torch.nn
  from recbole.model.abstract_recommender import KnowledgeRecommender
  from recbole.model.init import xavier_normal_initialization
  from recbole.model.loss import BPRLoss, EmbLoss
  from recbole.utils import InputType
label_desc: Use image node_id 2 for calling the RippleNet obj's underlying member method code with example usage: obj._build_ripple_set() and returns: ripple_set