class_docstr: Parameters
  ----------
  k: int, optional, default: 50
      The dimension of the user and item latent factors.
  
  n_epochs: int, optional, default: 50
      Maximum number of epochs for training.
  
  cnn_epochs: int, optional, default: 5
      Number of epochs for optimizing the CNN for each overall training epoch.
  
  cnn_bs: int, optional, default: 128
      Batch size for optimizing CNN.
      
  cnn_lr: float, optional, default: 0.001
      Learning rate for optimizing CNN.
  
  lambda_u: float, optional, default: 1.0
      The regularization hyper-parameter for user latent factor.
  
  lambda_v: float, optional, default: 100.0
      The regularization hyper-parameter for item latent factor.
  
  emb_dim: int, optional, default: 200
      The embedding size of each word. One word corresponds with [1 x emb_dim] vector in the embedding space
  
  max_len: int, optional, default 300
      The maximum length of item's document
  
  filter_sizes: list, optional, default: [3, 4, 5]
      The length of filters in convolutional layer
  
  num_filters: int, optional, default: 100
      The number of filters in convolutional layer
      
  hidden_dim: int, optional, default: 200
      The dimension of hidden layer after the pooling of all convolutional layers
  
  dropout_rate: float, optional, default: 0.2
      Dropout rate while training CNN
  
  give_item_weight: boolean, optional, default: True
      When True, each item will be weighted base on the number of user who have rated this item
  
  init_params: dict, optional, default: {'U':None, 'V':None, 'W': None}
      Initial U and V matrix and initial weight for embedding layer W
  
  trainable: boolean, optional, default: True
      When False, the model is not trained and Cornac assumes that the model already         pre-trained (U and V are not None).
  
  References
  ----------
  * Donghyun Kim1, Chanyoung Park1. ConvMF: Convolutional Matrix Factorization for Document Context-Aware Recommendation.     In :10th ACM Conference on Recommender Systems Pages 233-240
class_docstr_tok: ["Parameters","--","--","--","--","--","k",":","int",",","optional",",","default",":","50","The","dimension","of","the","user","and","item","latent","factors",".","n_epochs",":","int",",","optional",",","default",":","50","Maximum","number","of","epochs","for","training",".","cnn_epochs",":","int",",","optional",",","default",":","5","Number","of","epochs","for","optimizing","the","CNN","for","each","overall","training","epoch",".","cnn_bs",":","int",",","optional",",","default",":","128","Batch","size","for","optimizing","CNN",".","cnn_lr",":","float",",","optional",",","default",":","0.001","Learning","rate","for","optimizing","CNN",".","lambda_u",":","float",",","optional",",","default",":","1.0","The","regularization","hyper-parameter","for","user","latent","factor",".","lambda_v",":","float",",","optional",",","default",":","100.0","The","regularization","hyper-parameter","for","item","latent","factor",".","emb_dim",":","int",",","optional",",","default",":","200","The","embedding","size","of","each","word",".","One","word","corresponds","with","[","1","x","emb_dim","]","vector","in","the","embedding","space","max_len",":","int",",","optional",",","default","300","The","maximum","length","of","item","'s","document","filter_sizes",":","list",",","optional",",","default",":","[","3",",","4",",","5","]","The","length","of","filters","in","convolutional","layer","num_filters",":","int",",","optional",",","default",":","100","The","number","of","filters","in","convolutional","layer","hidden_dim",":","int",",","optional",",","default",":","200","The","dimension","of","hidden","layer","after","the","pooling","of","all","convolutional","layers","dropout_rate",":","float",",","optional",",","default",":","0.2","Dropout","rate","while","training","CNN","give_item_weight",":","boolean",",","optional",",","default",":","True","When","True",",","each","item","will","be","weighted","base","on","the","number","of","user","who","have","rated","this","item","init_params",":","dict",",","optional",",","default",":","{","'","U","'",":","None",",","'","V","'",":","None",",","'","W","'",":","None","}","Initial","U","and","V","matrix","and","initial","weight","for","embedding","layer","W","trainable",":","boolean",",","optional",",","default",":","True","When","False",",","the","model","is","not","trained","and","Cornac","assumes","that","the","model","already","pre-trained","(","U","and","V","are","not","None",")",".","References","--","--","--","--","--","*","Donghyun","Kim1",",","Chanyoung","Park1",".","ConvMF",":","Convolutional","Matrix","Factorization","for","Document","Context-Aware","Recommendation",".","In",":10th","ACM","Conference","on","Recommender","Systems","Pages","233-240"]
code: def _fit_convmf(self, train_set):
      user_data = self._build_data(train_set.matrix)
      item_data = self._build_data(train_set.matrix.T.tocsr())
  
      n_user = len(user_data[0])
      n_item = len(item_data[0])
  
      # R_user and R_item contain rating values
      R_user = user_data[1]
      R_item = item_data[1]
  
      if self.give_item_weight:
          item_weight = np.array(
              [math.sqrt(len(i)) for i in R_item], dtype=float
          )
          item_weight = (
              float(n_item) / item_weight.sum()
          ) * item_weight
      else:
          item_weight = np.ones(n_item, dtype=float)
  
      # Initialize cnn module
      import tensorflow.compat.v1 as tf
      from .convmf import CNN_module
  
      tf.disable_eager_execution()
  
      # less verbose TF
      os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"
      tf.logging.set_verbosity(tf.logging.ERROR)
  
      tf.set_random_seed(self.seed)
      cnn_module = CNN_module(
          output_dimension=self.k,
          dropout_rate=self.dropout_rate,
          emb_dim=self.emb_dim,
          max_len=self.max_len,
          filter_sizes=self.filter_sizes,
          num_filters=self.num_filters,
          hidden_dim=self.hidden_dim,
          seed=self.seed,
          init_W=self.W,
          learning_rate=self.cnn_lr,
      )
  
      config = tf.ConfigProto()
      config.gpu_options.allow_growth = True
      sess = tf.Session(config=config)
  
      sess.run(tf.global_variables_initializer())  # init variable
  
      document = train_set.item_text.batch_seq(
          np.arange(n_item), max_length=self.max_len
      )
  
      feed_dict = {cnn_module.model_input: document}
      theta = sess.run(cnn_module.model_output, feed_dict=feed_dict)
  
      endure = 3
      converge_threshold = 0.01
      history = 1e-50
      loss = 0
  
      for epoch in range(1, self.n_epochs + 1):
          if self.verbose:
              print("Epoch: {}/{}".format(epoch, self.n_epochs))
  
          tic = time.time()
  
          user_loss = 0.0
          for i in range(n_user):
              idx_item = user_data[0][i]
              V_i = self.V[idx_item]
              R_i = R_user[i]
  
              A = self.lambda_u * np.eye(self.k) + V_i.T.dot(V_i)
              B = (V_i * (np.tile(R_i, (self.k, 1)).T)).sum(0)
              self.U[i] = np.linalg.solve(A, B)
  
              user_loss += self.lambda_u * np.dot(self.U[i], self.U[i])
  
          item_loss = 0.0
          for j in range(n_item):
              idx_user = item_data[0][j]
              U_j = self.U[idx_user]
              R_j = R_item[j]
  
              A = self.lambda_v * item_weight[j] * np.eye(
                  self.k
              ) + U_j.T.dot(U_j)
              B = (U_j * (np.tile(R_j, (self.k, 1)).T)).sum(
                  0
              ) + self.lambda_v * item_weight[j] * theta[j]
              self.V[j] = np.linalg.solve(A, B)
  
              item_loss += np.square(R_j - U_j.dot(self.V[j])).sum()
  
          loop = trange(
              self.cnn_epochs,
              desc="Optimizing CNN",
              disable=not self.verbose,
          )
          for _ in loop:
              for batch_ids in train_set.item_iter(
                  batch_size=self.cnn_bs, shuffle=True
              ):
                  batch_seq = train_set.item_text.batch_seq(
                      batch_ids, max_length=self.max_len
                  )
                  feed_dict = {
                      cnn_module.model_input: batch_seq,
                      cnn_module.v: self.V[batch_ids],
                      cnn_module.sample_weight: item_weight[batch_ids],
                  }
  
                  sess.run([cnn_module.optimizer], feed_dict=feed_dict)
  
          feed_dict = {
              cnn_module.model_input: document,
              cnn_module.v: self.V,
              cnn_module.sample_weight: item_weight,
          }
          theta, cnn_loss = sess.run(
              [cnn_module.model_output, cnn_module.weighted_loss],
              feed_dict=feed_dict,
          )
  
          loss = 0.5 * (
              user_loss + item_loss + self.lambda_v * cnn_loss
          )
  
          toc = time.time()
          elapsed = toc - tic
          converge = abs((loss - history) / history)
  
          if self.verbose:
              print(
                  "Loss: %.5f Elapsed: %.4fs Converge: %.6f "
                  % (loss, elapsed, converge)
              )
  
          history = loss
          if converge < converge_threshold:
              endure -= 1
              if endure == 0:
                  break
  
      tf.reset_default_graph()
  
imports: import os
  import time
  import math
  import numpy
  from tqdm.auto import trange
  from ..recommender import Recommender
  from ..recommender import ANNMixin, MEASURE_DOT
  from ...exception import ScoreException
  from ...utils import get_rng
  from ...utils.init_utils import xavier_uniform
label_desc: Use image node_id 5 for calling the ConvMF obj's underlying member method code with example usage: obj._fit_convmf(train_set) without return types