code: def target_encode(
      trn_series=None,
      tst_series=None,
      target=None,
      min_samples_leaf=1,
      smoothing=1,
      noise_level=0,
  ):
      """Smoothing is computed like in the following paper by Daniele Micci-Barreca (download link):
      http://helios.mm.di.uoa.gr/~rouvas/ssi/sigkdd/sigkdd.vol3.1/barreca.ps
  
      Parameters
      ----------
      trn_series: pd.Series
          Training categorical feature as a pd.Series
      tst_series: pd.Series
          Test categorical feature as a pd.Series
      target: pd.Series
          Target data as a pd.Series
      min_samples_leaf: Int
          Minimum samples to take category average into account
      smoothing: Int
          Smoothing effect to balance categorical average vs prior
      noise_level
          ...
  
      Returns
      -------
      ft_trn_series: pd.Series
          ...
      ft_tst_series: pd.Series
          ...
      """
      assert len(trn_series) == len(target)
      assert trn_series.name == tst_series.name
      temp = pd.concat([trn_series, target], axis=1)
  
      # Compute target mean
      averages = temp.groupby(by=trn_series.name)[target.name].agg(
          ["mean", "count"]
      )
  
      # Compute smoothing
      smoothing = 1 / (
          1
          + np.exp(-(averages["count"] - min_samples_leaf) / smoothing)
      )
  
      # Apply average function to all target data
      prior = target.mean()
  
      # The bigger the count the less full_avg is taken into account
      averages[target.name] = (
          prior * (1 - smoothing) + averages["mean"] * smoothing
      )
      averages.drop(["mean", "count"], axis=1, inplace=True)
  
      #################### Apply Averages to Train Series ####################
      # This section has been slightly modified from the original for clarity
      ft_trn_series = pd.merge(
          trn_series.to_frame(trn_series.name),
          averages.reset_index().rename(
              columns={"index": target.name, target.name: "average"}
          ),
          on=trn_series.name,
          how="left",
      )
      ft_trn_series = ft_trn_series["average"]
      ft_trn_series = ft_trn_series.rename(trn_series.name + "_mean")
      ft_trn_series = ft_trn_series.fillna(prior)
      ft_trn_series.index = (
          trn_series.index
      )  # Restore index after `pd.merge`
  
      #################### Apply Averages to Test Series ####################
      # This section has been slightly modified from the original for clarity
      ft_tst_series = pd.merge(
          tst_series.to_frame(tst_series.name),
          averages.reset_index().rename(
              columns={"index": target.name, target.name: "average"}
          ),
          on=tst_series.name,
          how="left",
      )
      ft_tst_series = ft_tst_series["average"]
      ft_tst_series = ft_tst_series.rename(trn_series.name + "_mean")
      ft_tst_series = ft_tst_series.fillna(prior)
      ft_tst_series.index = (
          tst_series.index
      )  # Restore index after `pd.merge`
  
      return add_noise(ft_trn_series, noise_level), add_noise(
          ft_tst_series, noise_level
      )
  
file_path: hyperparameter_hunter/examples/feature_engineering_examples/olivier_porto_seguro_kaggle.py
imports: from hyperparameter_hunter import Environment, CVExperiment, FeatureEngineer, EngineerStep
  import numpy
  import pandas
  from sklearn.model_selection import StratifiedKFold
  from sklearn.preprocessing import LabelEncoder
  from xgboost import XGBClassifier
label_desc: Use image node_id 5 for calling a global function with example usage: target_encode(trn_series, tst_series, target, min_samples_leaf, smoothing, noise_level) and returns: add_noise,  add_noise