code: def historical_item_novelty(
      train_df,
      reco_df,
      col_user=DEFAULT_USER_COL,
      col_item=DEFAULT_ITEM_COL,
  ):
      """Calculate novelty for each item. Novelty is computed as the minus logarithm of
      (number of interactions with item / total number of interactions). The definition of the metric
      is based on the following reference using the choice model (eqs. 1 and 6):
  
      :Citation:
  
          P. Castells, S. Vargas, and J. Wang, Novelty and diversity metrics for recommender systems:
          choice, discovery and relevance, ECIR 2011
  
      The novelty of an item can be defined relative to a set of observed events on the set of all items.
      These can be events of user choice (item "is picked" by a random user) or user discovery
      (item "is known" to a random user). The above definition of novelty reflects a factor of item popularity.
      High novelty values correspond to long-tail items in the density function, that few users have interacted
      with and low novelty values correspond to popular head items.
  
      Args:
          train_df (pandas.DataFrame): Data set with historical data for users and items they
                  have interacted with; contains col_user, col_item. Assumed to not contain any duplicate rows.
                  Interaction here follows the *item choice model* from Castells et al.
          reco_df (pandas.DataFrame): Recommender's prediction output, containing col_user, col_item,
                  col_relevance (optional). Assumed to not contain any duplicate user-item pairs.
          col_user (str): User id column name.
          col_item (str): Item id column name.
  
      Returns:
          pandas.DataFrame: A dataframe with the following columns: col_item, item_novelty.
      """
  
      n_records = train_df.shape[0]
      item_count = pd.DataFrame(
          {"count": train_df.groupby([col_item]).size()}
      ).reset_index()
      item_count["item_novelty"] = -np.log2(
          item_count["count"] / n_records
      )
      df_item_novelty = (
          item_count[[col_item, "item_novelty"]]
          .sort_values(col_item)
          .reset_index(drop=True)
      )
  
      return df_item_novelty
  
imports: import numpy
  import pandas
  from functools import wraps
  from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score, explained_variance_score, roc_auc_score, log_loss
  from recommenders.utils.constants import DEFAULT_USER_COL, DEFAULT_ITEM_COL, DEFAULT_RATING_COL, DEFAULT_PREDICTION_COL, DEFAULT_RELEVANCE_COL, DEFAULT_SIMILARITY_COL, DEFAULT_ITEM_FEATURES_COL, DEFAULT_ITEM_SIM_MEASURE, DEFAULT_K, DEFAULT_THRESHOLD
  from recommenders.datasets.pandas_df_utils import has_columns, has_same_base_dtype, lru_cache_df
label_desc: Use image node_id 26 for calling a global function with example usage: historical_item_novelty(train_df, reco_df, col_user, col_item) and returns: df_item_novelty