code: def negative_feedback_sampler(
      df,
      col_user=DEFAULT_USER_COL,
      col_item=DEFAULT_ITEM_COL,
      col_label=DEFAULT_LABEL_COL,
      col_feedback="feedback",
      ratio_neg_per_user=1,
      pos_value=1,
      neg_value=0,
      seed=42,
  ):
      """Utility function to sample negative feedback from user-item interaction dataset.
      This negative sampling function will take the user-item interaction data to create
      binarized feedback, i.e., 1 and 0 indicate positive and negative feedback,
      respectively.
  
      Negative sampling is used in the literature frequently to generate negative samples
      from a user-item interaction data.
  
      See for example the `neural collaborative filtering paper <https://www.comp.nus.edu.sg/~xiangnan/papers/ncf.pdf>`_.
  
      Args:
          df (pandas.DataFrame): input data that contains user-item tuples.
          col_user (str): user id column name.
          col_item (str): item id column name.
          col_label (str): label column name in df.
          col_feedback (str): feedback column name in the returned data frame; it is used for the generated column
              of positive and negative feedback.
          ratio_neg_per_user (int): ratio of negative feedback w.r.t to the number of positive feedback for each user.
              If the samples exceed the number of total possible negative feedback samples, it will be reduced to the
              number of all the possible samples.
          pos_value (float): value of positive feedback.
          neg_value (float): value of negative feedback.
          inplace (bool):
          seed (int): seed for the random state of the sampling function.
  
      Returns:
          pandas.DataFrame: Data with negative feedback.
  
      Examples:
          >>> import pandas as pd
          >>> df = pd.DataFrame({
              'userID': [1, 2, 3],
              'itemID': [1, 2, 3],
              'rating': [5, 5, 5]
          })
          >>> df_neg_sampled = negative_feedback_sampler(
              df, col_user='userID', col_item='itemID', ratio_neg_per_user=1
          )
          >>> df_neg_sampled
          userID  itemID  feedback
          1   1   1
          1   2   0
          2   2   1
          2   1   0
          3   3   1
          3   1   0
      """
      # Get all of the users and items.
      items = df[col_item].unique()
      rng = np.random.default_rng(seed=seed)
  
      def sample_items(user_df):
          # Sample negative items for the data frame restricted to a specific user
          n_u = len(user_df)
          neg_sample_size = max(round(n_u * ratio_neg_per_user), 1)
          # Draw (n_u + neg_sample_size) items and keep neg_sample_size of these
          # that are not already in user_df. This requires a set difference from items_sample
          # instead of items, which is more efficient when len(items) is large.
          sample_size = min(n_u + neg_sample_size, len(items))
          items_sample = rng.choice(items, sample_size, replace=False)
          new_items = np.setdiff1d(items_sample, user_df[col_item])[
              :neg_sample_size
          ]
          new_df = pd.DataFrame(
              data={
                  col_user: user_df.name,
                  col_item: new_items,
                  col_label: neg_value,
              }
          )
          return pd.concat([user_df, new_df], ignore_index=True)
  
      res_df = df.copy()
      res_df[col_label] = pos_value
      return (
          res_df.groupby(col_user)
          .apply(sample_items)
          .reset_index(drop=True)
          .rename(columns={col_label: col_feedback})
      )
  
imports: import logging
  import pandas
  import numpy
  from functools import lru_cache, wraps
  from recommenders.utils.constants import DEFAULT_USER_COL, DEFAULT_ITEM_COL, DEFAULT_RATING_COL, DEFAULT_LABEL_COL
label_desc: Use image node_id 3 for calling a global function with example usage: negative_feedback_sampler(df, col_user, col_item, col_label, col_feedback, ratio_neg_per_user, pos_value, neg_value, seed) and returns: res_df, pd