RareLabelEncoder#

The RareLabelEncoder() 将不常见的类别分组到一个名为 ‘Rare’ 的新类别中,或者由用户指定的其他字符串。我们需要指定一个类别应保留的最小观察百分比,以及一个变量在被重新分组之前应具有的最小唯一类别数。

tol

在参数 tol 中,我们指定了某个类别应具有的最小观测比例,以避免被分组。换句话说,频率或观测比例 <= tol 的类别将被分组到一个唯一的项中。

n_categories

在参数 n_categories 中,我们指定了分类变量的最小基数,以便将不常见的类别分组。例如,如果 n_categories=5,则只有在具有超过5个唯一类别的分类变量中才会对类别进行分组。其余变量将被忽略。

当我们有大型的数据集并且没有时间逐一检查所有分类变量时,此参数非常有用。通过这种方式,我们确保低基数的变量不会进一步减少。

max_n_categories

在参数 max_n_categories 中,我们指定了编码变量中所需的最大唯一类别数。如果 max_n_categories=5,那么在编码后,最流行的5个类别将保留在变量中,所有其他类别将被归入一个单一类别。

如果我们打算在其后进行独热编码,此参数很有用,可以控制特征空间的扩展。

示例

让我们来看一个使用泰坦尼克号数据集的例子。

首先,让我们加载数据并将其分为训练集和测试集:

from sklearn.model_selection import train_test_split
from feature_engine.datasets import load_titanic
from feature_engine.encoding import RareLabelEncoder

X, y = load_titanic(
    return_X_y_frame=True,
    handle_missing=True,
    predictors_only=True,
    cabin="letter_only",
)
X["pclass"] = X["pclass"].astype("O")

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=0,
)

print(X_train.head())

我们在下面看到生成的数据:

      pclass     sex        age  sibsp  parch     fare cabin embarked
501        2  female  13.000000      0      1  19.5000     M        S
588        2  female   4.000000      1      1  23.0000     M        S
402        2  female  30.000000      1      0  13.8583     M        C
1193       3    male  29.881135      0      0   7.7250     M        Q
686        3  female  22.000000      0      0   7.7250     M        Q

让我们探索变量 "cabin" 中的唯一类别数量。

X_train["cabin"].unique()

我们在下面的输出中看到唯一类别的数量:

array(['M', 'E', 'C', 'D', 'B', 'A', 'F', 'T', 'G'], dtype=object)

现在,我们设置 RareLabelEncoder() 将观察中出现少于3%的类别分组到一个新的组或类别中,称为’Rare’。如果指示的变量中每个变量有超过2个唯一类别,我们将对其进行分组。

encoder = RareLabelEncoder(
    tol=0.03,
    n_categories=2,
    variables=['cabin', 'pclass', 'embarked'],
    replace_with='Rare',
)

# fit the encoder
encoder.fit(X_train)

通过 fit()RareLabelEncoder() 找到在超过3%的观察中出现的类别,即那些不会被分组的类别。这些类别可以在 encoder_dict_ 属性中找到。

encoder.encoder_dict_

encoder_dict_ 中,我们找到每个变量最频繁的类别进行编码。任何不在此字典中的类别,将被分组。

{'cabin': ['M', 'C', 'B', 'E', 'D'],
'pclass': [3, 1, 2],
'embarked': ['S', 'C', 'Q']}

现在我们可以继续转换变量:

# transform the data
train_t = encoder.transform(X_train)
test_t = encoder.transform(X_test)

现在让我们检查变量 "cabin" 在转换后的唯一类别数量:

train_t["cabin"].unique()

在下面的输出中,我们看到不常见的类别已被替换为 "Rare"

array(['M', 'E', 'C', 'D', 'B', 'Rare'], dtype=object)

我们还可以使用 max_n_categories 参数指定可以被视为频繁的最大类别数。

让我们首先创建一个玩具数据框,并计算每个类别的观测值数量:

from feature_engine.encoding import RareLabelEncoder
import pandas as pd
data = {'var_A': ['A'] * 10 + ['B'] * 10 + ['C'] * 2 + ['D'] * 1}
data = pd.DataFrame(data)
data['var_A'].value_counts()
A    10
B    10
C     2
D     1
Name: var_A, dtype: int64

在这段代码中,我们仅对具有超过3个唯一类别的变量进行类别分组,然后绘制结果:

rare_encoder = RareLabelEncoder(tol=0.05, n_categories=3)
rare_encoder.fit_transform(data)['var_A'].value_counts()
A       10
B       10
C        2
Rare     1
Name: var_A, dtype: int64

现在,我们保留变量的两个最频繁的类别,并将其余的归入’稀有’组:

rare_encoder = RareLabelEncoder(tol=0.05, n_categories=3, max_n_categories=2)
Xt = rare_encoder.fit_transform(data)
Xt['var_A'].value_counts()
A       10
B       10
Rare     3
Name: var_A, dtype: int64

提示#

可以使用 RareLabelEncoder() 来将不常见的类别分组,从而在使用独热编码时控制特征空间的扩展。

某些分类编码如果在测试集中存在但在训练集中未见过的类别,也会返回 NAN。如果我们在训练编码器之前对稀有标签进行分组,通常可以避免这种不便。

某些分类编码器在特定类别没有足够观察值时也会返回NAN。例如 WoEEncoder()PRatioEncoder()。这种行为可以通过在编码前使用 RareLabelEncoder() 对不常见的标签进行分组来防止。

其他资源#

在下面的笔记本中,你可以找到更多关于 RareLabelEncoder() 功能的详细信息以及编码变量的示例图:

有关此方法和其他特征工程方法的更多详细信息,请查看以下资源:

../../_images/feml.png

机器学习的特征工程#











或者阅读我们的书:

../../_images/cookbook.png

Python 特征工程手册#














我们的书籍和课程都适合初学者和更高级的数据科学家。通过购买它们,您正在支持 Feature-engine 的主要开发者 Sole。