code: def pf_(self, X, k, max_iter=1, init_params=None):
      # data preparation
      X = sp.csc_matrix(X, dtype=np.float64)
      M = X.copy()
      M.data = np.full(len(M.data), 1)
      n = X.shape[0]
      d = X.shape[1]
      eps = 0.000000001
  
      # Hyper-parameters setting
      a = 0.3
  
      # Parameter initialization
  
      # shape gamma_uk matrix (dgCMatrix)
      if init_params["G_s"] is None:
          G_s = np.random.gamma(50, scale=0.3 / 50, size=n * k).reshape(
              n, k
          )
      else:
          G_s = init_params["G_s"]
      G_s = sp.csc_matrix(G_s, dtype=np.float64)
  
      ## rate gamma_uk matrix (dgCMatrix)
      if init_params["G_r"] is None:
          G_r = np.random.gamma(50, scale=0.3 / 50, size=n * k).reshape(
              n, k
          )
      else:
          G_r = init_params["G_r"]
      G_r = sp.csc_matrix(G_r, dtype=np.float64)
  
      # shape lamda_ik matrix (dgCMatrix)
      if init_params["L_s"] is None:
          L_s = np.random.gamma(50, scale=0.3 / 50, size=d * k).reshape(
              d, k
          )
      else:
          L_s = init_params["L_s"]
      L_s = sp.csc_matrix(L_s, dtype=np.float64)
  
      ## rate lamda_ik matrix (dgCMatrix)
      if init_params["L_r"] is None:
          L_r = np.random.gamma(50, scale=0.3 / 50, size=d * k).reshape(
              d, k
          )
      else:
          L_r = init_params["L_r"]
      L_r = sp.csc_matrix(L_r, dtype=np.float64)
  
      # need to be computed only once as Lr and Ls don't change here
      logL_r = L_r.copy()
      logL_r.data = np.log(logL_r.data)
      digaL_s = L_s.copy()
      digaL_s.data = sc.special.digamma(digaL_s.data)
  
      Lb = digaL_s - logL_r
      Lb.data = np.exp(Lb.data)
  
      del logL_r
      del digaL_s
  
      Lb = Lb.todense()
  
      # Learning
      for iter_ in range(1, max_iter + 1):
          ## Update multinomiale parameter, no need to store phi only compute the sufficient stats
          logG_r = G_r.copy()
          logG_r.data = np.log(logG_r.data)
          digaG_s = G_s.copy()
          digaG_s.data = sc.special.digamma(digaG_s.data)
  
          Lt = digaG_s - logG_r
          Lt.data = np.exp(Lt.data)
  
          del logG_r
          del digaG_s
  
          Lt = Lt.todense()
  
          ## Update user related parameters
          G_s = a + np.multiply(Lt, ((X / (Lt * Lb.T + eps)) * Lb))
          G_r = np.repeat(np.sum(L_s / L_r, 0), n, axis=0) + a
  
          G_s = sp.csc_matrix(G_s)
          G_r = sp.csc_matrix(G_r)
  
      Tk = np.repeat(np.sum(G_s / G_r, 0), self.batch_size, axis=0)
      Zik = np.multiply(Lb, ((X.T / (Lb * Lt.T + eps)) * Lt))
      # End of learning
  
      res = {
          "Z": G_s / G_r,
          "W": L_s / L_r,
          "G_s": G_s,
          "G_r": G_r,
          "L_s": L_s,
          "L_r": L_r,
          "Lt": Lt,
          "Lb": Lb,
          "Zik": np.array(Zik, dtype="float32"),
          "Tk": np.array(Tk, dtype="float32"),
      }
  
      return res
  
file_path: cornac/cornac/models/pcrl/pcrl.py
imports: import numpy
  import scipy.sparse
  import scipy
  import tensorflow
label_desc: Use image node_id 11 for calling the PCRL_ obj's underlying member method code with example usage: obj.pf_(X, k, max_iter, init_params) and returns: res