class_docstr: Bert4Rec data pre-processer to get the masked sequences for each user
  
  Args:
      raw_data (pd.DataFrame): the raw dataframe
      min_rating (int): minimum valid rating
      min_uc (int): minimum user ratings count
      min_sc (int): minimum item count for each valid use
      name (str): dataset for experiment, current support ml-1m, ml-20m, random
      max_len (int): max length of the Bert embedding dimensio
      mask_prob (float): probability of the mask
      dupe_factor (int): number of duplication while generating the random masked seqs
  
  Returns:
      Dict[str, Any]
  
  Example::
  
      raw_data = get_raw_dataframe(
          "random", 5, 40, 200, 4, None
      )
      df = Bert4RecPreprocsser(
          raw_data,
          4,
          5,
          0,
          "random",
          4,
          0.2,
          1,
      ).get_processed_dataframes()
class_docstr_tok: ["Bert4Rec","data","pre-processer","to","get","the","masked","sequences","for","each","user","Args",":","raw_data","(","pd.DataFrame",")",":","the","raw","dataframe","min_rating","(","int",")",":","minimum","valid","rating","min_uc","(","int",")",":","minimum","user","ratings","count","min_sc","(","int",")",":","minimum","item","count","for","each","valid","use","name","(","str",")",":","dataset","for","experiment",",","current","support","ml-1m",",","ml-20m",",","random","max_len","(","int",")",":","max","length","of","the","Bert","embedding","dimensio","mask_prob","(","float",")",":","probability","of","the","mask","dupe_factor","(","int",")",":","number","of","duplication","while","generating","the","random","masked","seqs","Returns",":","Dict","[","str",",","Any","]","Example",":",":","raw_data","=","get_raw_dataframe","(","``","random","''",",","5",",","40",",","200",",","4",",","None",")","df","=","Bert4RecPreprocsser","(","raw_data",",","4",",","5",",","0",",","``","random","''",",","4",",","0.2",",","1",",",")",".get_processed_dataframes","(",")"]
code: def _generate_negative_samples(
      self,
      df: Dict[str, Any],
  ) -> Dict[str, Any]:
      # follow the paper, no negative samples in training set
      # 100 negative samples in test set, 2 for random to save time
      test_set_sample_size = 100 if self.name != "random" else 10
  
      if self.name == "random":
          # use pure random to save time for random dataframe
          test_negative_samples = {}
          for user in range(self.user_count):
              seen = set(df["train"][user])
              seen.update(df["val"][user])
              seen.update(df["test"][user])
              test_negative_samples[user] = []
              for _ in range(test_set_sample_size):
                  t = np.random.randint(1, self.item_count + 1)
                  while t in seen:
                      t = np.random.randint(1, self.item_count + 1)
                  test_negative_samples[user].append(t)
      else:
          # use popularity random sampling align with paper
          popularity = Counter()
          for user in range(self.user_count):
              popularity.update(df["train"][user])
              popularity.update(df["val"][user])
              popularity.update(df["test"][user])
          (items_list, freq) = zip(*popularity.items())
          freq_sum = sum(freq)
          prob = [float(i) / freq_sum for i in freq]
          test_negative_samples = {}
          min_size = test_set_sample_size
          print("Sampling negative items")
          for user in range(self.user_count):
              seen = set(df["train"][user])
              seen.update(df["val"][user])
              seen.update(df["test"][user])
              samples = []
              while len(samples) < test_set_sample_size:
                  sampled_ids = np.random.choice(
                      items_list,
                      test_set_sample_size * 2,
                      replace=False,
                      p=prob,
                  )
                  sampled_ids = [
                      x for x in sampled_ids if x not in seen
                  ]
                  samples.extend(sampled_ids[:])
              min_size = (
                  min_size if min_size < len(samples) else len(samples)
              )
              test_negative_samples[user] = samples
          if min_size == 0:
              raise RuntimeError(
                  "we sampled 0 negative samples for a user, please increase the data size"
              )
          test_negative_samples = {
              key: value[:min_size]
              for key, value in test_negative_samples.items()
          }
      df["test_negative_samples"] = test_negative_samples
      return df
  
imports: import random
  from collections import Counter
  from pathlib import Path
  from typing import Any, Dict, List, Optional, Tuple
  import numpy
  import pandas
label_desc: Use image node_id 7 for calling the Bert4RecPreprocsser obj's underlying member method code with example usage: obj._generate_negative_samples(df) and returns: df