class_docstr: Implements the per-arm version of the MovieLens Bandit environment.
  
  This environment implements the MovieLens 100K dataset, available at:
  https://www.kaggle.com/prajitdatta/movielens-100k-dataset
  
  This dataset contains 100K ratings from 943 users on 1682 items.
  This csv list of:
  user id | item id | rating | timestamp.
  This environment computes a low-rank matrix factorization (using SVD) of the
  data matrix `A`, such that: `A ~= U * Sigma * V^T`.
  
  The environment uses the rows of `U` as global (or user) features, and the
  rows of `V` as per-arm (or movie) features.
  
  The reward of recommending movie `v` to user `u` is `u * Sigma * v^T`.
class_docstr_tok: ["Implements","the","per-arm","version","of","the","MovieLens","Bandit","environment",".","This","environment","implements","the","MovieLens","100K","dataset",",","available","at",":","https",":","\/\/www.kaggle.com\/prajitdatta\/movielens-100k-dataset","This","dataset","contains","100K","ratings","from","943","users","on","1682","items",".","This","csv","list","of",":","user","id","|","item","id","|","rating","|","timestamp",".","This","environment","computes","a","low-rank","matrix","factorization","(","using","SVD",")","of","the","data","matrix","`","A","`",",","such","that",":","`","A","~=","U","*","Sigma","*","V^T","`",".","The","environment","uses","the","rows","of","`","U","`","as","global","(","or","user",")","features",",","and","the","rows","of","`","V","`","as","per-arm","(","or","movie",")","features",".","The","reward","of","recommending","movie","`","v","`","to","user","`","u","`","is","`","u","*","Sigma","*","v^T","`","."]
docstr: Initializes the Per-arm MovieLens Bandit environment.
  
  Args:
    data_dir: (string) Directory where the data lies (in text form).
    rank_k: (int) Which rank to use in the matrix factorization. This will
      also be the feature dimension of both the user and the movie features.
    batch_size: (int) Number of observations generated per call.
    num_actions: (int) How many movies to choose from per round.
    csv_delimiter: (string) The delimiter to use in loading the data csv file.
    name: (string) The name of this environment instance.
docstr_tok: ["Initializes","the","Per-arm","MovieLens","Bandit","environment",".","Args",":","data_dir",":","(","string",")","Directory","where","the","data","lies","(","in","text","form",")",".","rank_k",":","(","int",")","Which","rank","to","use","in","the","matrix","factorization",".","This","will","also","be","the","feature","dimension","of","both","the","user","and","the","movie","features",".","batch_size",":","(","int",")","Number","of","observations","generated","per","call",".","num_actions",":","(","int",")","How","many","movies","to","choose","from","per","round",".","csv_delimiter",":","(","string",")","The","delimiter","to","use","in","loading","the","data","csv","file",".","name",":","(","string",")","The","name","of","this","environment","instance","."]
code: def __init__(
      self,
      data_dir: Text,
      rank_k: int,
      batch_size: int = 1,
      num_actions: int = 50,
      csv_delimiter=",",
      name: Optional[Text] = "movielens_per_arm",
  ):
      """Initializes the Per-arm MovieLens Bandit environment.
  
      Args:
        data_dir: (string) Directory where the data lies (in text form).
        rank_k: (int) Which rank to use in the matrix factorization. This will
          also be the feature dimension of both the user and the movie features.
        batch_size: (int) Number of observations generated per call.
        num_actions: (int) How many movies to choose from per round.
        csv_delimiter: (string) The delimiter to use in loading the data csv file.
        name: (string) The name of this environment instance.
      """
      self._batch_size = batch_size
      self._context_dim = rank_k
      self._num_actions = num_actions
  
      # Compute the matrix factorization.
      self._data_matrix = dataset_utilities.load_movielens_data(
          data_dir, delimiter=csv_delimiter
      )
      self._num_users, self._num_movies = self._data_matrix.shape
  
      # Compute the SVD.
      u, s, vh = np.linalg.svd(self._data_matrix, full_matrices=False)
  
      # Keep only the largest singular values.
      self._u_hat = u[:, :rank_k].astype(np.float32)
      self._s_hat = s[:rank_k].astype(np.float32)
      self._v_hat = np.transpose(vh[:rank_k]).astype(np.float32)
  
      self._approx_ratings_matrix = np.matmul(
          self._u_hat * self._s_hat, np.transpose(self._v_hat)
      )
  
      self._action_spec = array_spec.BoundedArraySpec(
          shape=(),
          dtype=np.int32,
          minimum=0,
          maximum=num_actions - 1,
          name="action",
      )
      observation_spec = {
          GLOBAL_KEY: array_spec.ArraySpec(
              shape=[rank_k], dtype=np.float32
          ),
          PER_ARM_KEY: array_spec.ArraySpec(
              shape=[num_actions, rank_k], dtype=np.float32
          ),
      }
      self._time_step_spec = ts.time_step_spec(observation_spec)
  
      self._current_user_indices = np.zeros(batch_size, dtype=np.int32)
      self._previous_user_indices = np.zeros(batch_size, dtype=np.int32)
  
      self._current_movie_indices = np.zeros(
          [batch_size, num_actions], dtype=np.int32
      )
      self._previous_movie_indices = np.zeros(
          [batch_size, num_actions], dtype=np.int32
      )
  
      self._observation = {
          GLOBAL_KEY: np.zeros([batch_size, rank_k]),
          PER_ARM_KEY: np.zeros([batch_size, num_actions, rank_k]),
      }
  
      super(MovieLensPerArmPyEnvironment, self).__init__(
          observation_spec, self._action_spec, name=name
      )
  
imports: from __future__ import absolute_import
  import random
  from typing import Optional, Text
  import gin
  import numpy
  from tf_agents.bandits.environments import bandit_py_environment
  from tf_agents.bandits.environments import dataset_utilities
  from tf_agents.bandits.specs import utils
  from tf_agents.specs import array_spec
  from tf_agents.trajectories import time_step
label_desc: Use image node_id 1 to create a new MovieLensPerArmPyEnvironment object from inherited base classes: bandit_py_environment with example: obj = MovieLensPerArmPyEnvironment(data_dir, rank_k, batch_size, num_actions, csv_delimiter, name)