DEV Community

TS
TS

Posted on

cell-03-COUNTRY TARGET ENCODING

# ============================================================
# COUNTRY TARGET ENCODING
# ============================================================

def fit_country_target_encoding(country_series, y):

    temp = pd.DataFrame({
        "Country": country_series,
        "Target": np.asarray(y)
    })

    global_mean = temp["Target"].mean()

    country_means = (
        temp.groupby("Country")["Target"].mean()
    )

    return country_means, global_mean


def apply_country_target_encoding(
    country_series,
    country_means,
    global_mean
):
    return (
        pd.Series(country_series)
        .map(country_means)
        .fillna(global_mean)
        .to_numpy()
    )

Enter fullscreen mode Exit fullscreen mode

Cell Purpose

This part of the notebook defines two functions for Country Target Encoding:

  1. fit_country_target_encoding()learns the country-to-PCF mapping.
  2. apply_country_target_encoding()applies that learned mapping to another dataset.

Think of it simply as:

Training data
     ↓
fit_country_target_encoding()
     ↓
Country → Mean PCF mapping
     ↓
apply_country_target_encoding()
     ↓
Numerical country feature
Enter fullscreen mode Exit fullscreen mode

The important distinction is:

Fit = learn the mapping. Apply = use the mapping.


Function 1 — fit_country_target_encoding()

def fit_country_target_encoding(country_series, y):
Enter fullscreen mode Exit fullscreen mode

What does this line do?

This defines a function named:

fit_country_target_encoding
Enter fullscreen mode Exit fullscreen mode

It takes two inputs:

country_series → Country values
y              → PCF target values
Enter fullscreen mode Exit fullscreen mode

For example:

Country        PCF
Germany        20
USA            40
Germany        30
UK             10
Enter fullscreen mode Exit fullscreen mode

Here:

country_series
Enter fullscreen mode Exit fullscreen mode

contains:

Germany
USA
Germany
UK
Enter fullscreen mode Exit fullscreen mode

and:

y
Enter fullscreen mode Exit fullscreen mode

contains:

20
40
30
10
Enter fullscreen mode Exit fullscreen mode

Presentation

“This function takes the country feature and the corresponding PCF target values as inputs and learns a target-encoding mapping.”


Creating the temporary DataFrame

temp = pd.DataFrame({
    "Country": country_series,
    "Target": np.asarray(y)
})
Enter fullscreen mode Exit fullscreen mode

This creates a temporary dataframe with two columns:

Country
Target
Enter fullscreen mode Exit fullscreen mode

For example:

Country Target
Germany 20
USA 40
Germany 30
UK 10

Why create this dataframe?

Because it makes it easy to calculate the target mean for each country using:

groupby()
Enter fullscreen mode Exit fullscreen mode

What does np.asarray(y) do?

It converts y into a NumPy array.

For example:

y
↓
[20, 40, 30, 10]
Enter fullscreen mode Exit fullscreen mode

This makes sure the target is in a suitable array format for constructing the dataframe.

Presentation

“I create a temporary dataframe containing country and its corresponding target values. I convert the target to a NumPy array to ensure a consistent numerical array representation.”


Calculating the global mean

global_mean = temp["Target"].mean()
Enter fullscreen mode Exit fullscreen mode

This calculates the overall average PCF across all observations.

Using the example:

20 + 40 + 30 + 10
----------------- = 25
        4
Enter fullscreen mode Exit fullscreen mode

So:

global_mean = 25
Enter fullscreen mode Exit fullscreen mode

Why do we need the global mean?

It acts as a fallback value when a country does not have a learned country-specific mean.

For example, if later we encounter:

France
Enter fullscreen mode Exit fullscreen mode

but France wasn't present in the mapping, we can use:

global_mean = 25
Enter fullscreen mode Exit fullscreen mode

instead.

Presentation

“I calculate the overall target mean, which will later be used as a fallback when an unseen country does not have a country-specific encoding.”


Calculating country-specific means

country_means = (
    temp.groupby("Country")["Target"].mean()
)
Enter fullscreen mode Exit fullscreen mode

This is the main target-encoding operation.

First:

temp.groupby("Country")
Enter fullscreen mode Exit fullscreen mode

groups all observations according to country.

Then:

["Target"]
Enter fullscreen mode Exit fullscreen mode

selects the PCF target values.

Finally:

.mean()
Enter fullscreen mode Exit fullscreen mode

calculates the average PCF for each country.

For example:

Country Target values Mean
Germany 20, 30 25
USA 40 40
UK 10 10

So country_means becomes approximately:

Germany → 25
USA     → 40
UK      → 10
Enter fullscreen mode Exit fullscreen mode

This is the mapping that will be used later.

Presentation

“Here I group the observations by country and calculate the mean PCF for each country. This creates the numerical mapping used for target encoding.”


Returning the results

return country_means, global_mean
Enter fullscreen mode Exit fullscreen mode

The function returns two outputs:

1. country_means
2. global_mean
Enter fullscreen mode Exit fullscreen mode

So conceptually:

country_means:
Germany → 25
USA     → 40
UK      → 10

global_mean:
25
Enter fullscreen mode Exit fullscreen mode

Presentation

“The function returns both the country-specific means and the overall mean, because I need the country mapping for known countries and the global mean as a fallback for unseen countries.”


Complete Function 1

def fit_country_target_encoding(country_series, y):

    temp = pd.DataFrame({
        "Country": country_series,
        "Target": np.asarray(y)
    })

    global_mean = temp["Target"].mean()

    country_means = (
        temp.groupby("Country")["Target"].mean()
    )

    return country_means, global_mean
Enter fullscreen mode Exit fullscreen mode

Simple way to remember it

Country + PCF
     ↓
Temporary DataFrame
     ↓
Calculate overall PCF mean
     ↓
Calculate PCF mean per country
     ↓
Return both
Enter fullscreen mode Exit fullscreen mode

Function 2 — apply_country_target_encoding()

def apply_country_target_encoding(
    country_series,
    country_means,
    global_mean
):
Enter fullscreen mode Exit fullscreen mode

What does this function do?

This function does not learn a new mapping.

It takes the mapping created by the previous function and applies it to country values.

Inputs:

country_series → countries that need encoding
country_means  → learned country → mean PCF mapping
global_mean    → fallback value
Enter fullscreen mode Exit fullscreen mode

Important distinction

Function 1:

learns

Function 2:

applies

This distinction is very important in your viva.


Converting country to Series

pd.Series(country_series)
Enter fullscreen mode Exit fullscreen mode

This ensures country_series is treated as a pandas Series.

For example:

Germany
USA
UK
France
Enter fullscreen mode Exit fullscreen mode

becomes a pandas Series that can use .map().


Mapping country to target mean

.map(country_means)
Enter fullscreen mode Exit fullscreen mode

This looks up each country in the previously learned mapping.

Suppose:

country_means:

Germany → 25
USA     → 40
UK      → 10
Enter fullscreen mode Exit fullscreen mode

And the new data contains:

Germany
USA
UK
Germany
Enter fullscreen mode Exit fullscreen mode

After .map(country_means):

25
40
10
25
Enter fullscreen mode Exit fullscreen mode

So the categorical country values have now been converted into numerical values.

Presentation

“I use the learned country-to-mean mapping to convert each country into a numerical target-encoded value.”


Handling unseen countries

.fillna(global_mean)
Enter fullscreen mode Exit fullscreen mode

Suppose the new data contains:

France
Enter fullscreen mode Exit fullscreen mode

but France wasn't present in the learned mapping.

Then:

.map(country_means)
Enter fullscreen mode Exit fullscreen mode

produces:

NaN
Enter fullscreen mode Exit fullscreen mode

Instead of keeping NaN, we replace it with:

global_mean
Enter fullscreen mode Exit fullscreen mode

For example:

France → 25
Enter fullscreen mode Exit fullscreen mode

if the global mean is 25.

Why?

Because the model still needs a numerical feature.

Presentation

“If a country is not present in the learned mapping, the mapping returns NaN. I replace that with the overall training mean so unseen categories can still be represented numerically.”


Convert to NumPy array

.to_numpy()
Enter fullscreen mode Exit fullscreen mode

This converts the pandas Series into a NumPy array.

For example:

Pandas Series
     ↓
NumPy array
[25, 40, 10, 25]
Enter fullscreen mode Exit fullscreen mode

Why?

Later in your code, you use:

np.hstack()
Enter fullscreen mode Exit fullscreen mode

to combine this country feature with other numerical features.

So a NumPy array is convenient for that operation.

Presentation

“Finally, I convert the encoded values into a NumPy array so they can be combined with the other numerical feature matrices later.”


Complete Function 2

def apply_country_target_encoding(
    country_series,
    country_means,
    global_mean
):
    return (
        pd.Series(country_series)
        .map(country_means)
        .fillna(global_mean)
        .to_numpy()
    )
Enter fullscreen mode Exit fullscreen mode

Simple way to remember it

Country
   ↓
Look up learned country mean
   ↓
Known country → country mean
Unseen country → global mean
   ↓
NumPy array
Enter fullscreen mode Exit fullscreen mode

Function 1 + Function 2 Together

This is the most important concept.

Function 1

fit_country_target_encoding()
Enter fullscreen mode Exit fullscreen mode

Learns:

Germany → 25
USA     → 40
UK      → 10
Enter fullscreen mode Exit fullscreen mode

Function 2

apply_country_target_encoding()
Enter fullscreen mode Exit fullscreen mode

Uses:

Germany → 25
USA     → 40
UK      → 10
Enter fullscreen mode Exit fullscreen mode

to transform new observations.

So:

                TRAINING DATA
                     ↓
        fit_country_target_encoding()
                     ↓
             Country Mapping
                     ↓
        apply_country_target_encoding()
                     ↓
              Numerical Feature
Enter fullscreen mode Exit fullscreen mode

Important Viva Question — Target Leakage

Teacher: “Is this target encoding leakage-free?”

Don't automatically say yes.

The basic function:

fit_country_target_encoding()
Enter fullscreen mode Exit fullscreen mode

calculates country means using the target values of the data passed to it.

If you use it directly on the same training observations to create their own features, an observation's own target can contribute to its encoded value.

That can cause target leakage.

That's why your notebook later has:

fit_country_target_encoding_oof()
Enter fullscreen mode Exit fullscreen mode

which uses Out-of-Fold encoding for the training observations.

Strong answer

“Basic target encoding can introduce target leakage if each observation contributes its own target to its encoded feature. That's why for the training data I use the OOF version later, where the encoding for each observation is calculated from other folds.”

This is a very important point to understand before your viva.


🎤 How to Present These Two Functions

Start:

“These two functions implement the basic country target-encoding mechanism. The first function learns the mapping, and the second function applies that mapping.”

Then Function 1:

“First, I combine country and the corresponding PCF values into a temporary dataframe. I calculate the global PCF mean and then calculate the mean PCF for each country. These two values are returned.”

Then Function 2:

“The second function takes the learned country means and maps each country to its corresponding numerical value. For an unseen country, I use the global mean as a fallback, and finally convert the result to a NumPy array.”

Then connect to the next function:

“However, because this is target encoding, using the target directly can create leakage for training observations. Therefore, later in the notebook I use out-of-fold target encoding to address this issue.”

That last sentence is excellent for your viva because it shows you understand not only what your code does, but why the next function exists.

For this encoding cell

  • Trace one row through both functions

Top comments (0)