MatchCategories#

MatchCategories() 确保分类变量被编码为 pandas 的 ‘categorical’ 数据类型,而不是通用的 python ‘object’ 或其他数据类型。

在底层,’categorical’ dtype 是一种表示方法,它将每个类别映射到一个整数,从而提供比 ‘str’ 等更节省内存的对象结构,并允许对生成的对象进行更快的分组、映射和类似操作。

MatchCategories() 记住了每个类别所代表的编码或级别,因此可以用于确保在将分类数据传递给支持此数据类型的建模包时应用正确的编码,或者例如防止未见过的类别到达管道中的进一步转换器或估计器。

让我们通过一个例子来探讨这一点。首先我们加载泰坦尼克号数据集,并将其分为训练集和测试集:

from feature_engine.preprocessing import MatchCategories
from feature_engine.datasets import load_titanic

# Load dataset
data = load_titanic(
    predictors_only=True,
    handle_missing=True,
    cabin="letter_only",
)

data['pclass'] = data['pclass'].astype('O')

# Split test and train
train = data.iloc[0:1000, :]
test = data.iloc[1000:, :]

现在,我们设置 MatchCategories() 并将其拟合到训练集。

# set up the transformer
match_categories = MatchCategories(missing_values="ignore")

# learn the mapping of categories to integers in the train set
match_categories.fit(train)

MatchCategories() 将其属性中的训练集映射存储起来:

# the transformer stores the mappings for categorical variables
match_categories.category_dict_
{'pclass': Int64Index([1, 2, 3], dtype='int64'),
 'sex': Index(['female', 'male'], dtype='object'),
 'cabin': Index(['A', 'B', 'C', 'D', 'E', 'F', 'M', 'T'], dtype='object'),
 'embarked': Index(['C', 'Missing', 'Q', 'S'], dtype='object')}

如果我们使用相同的 match_categories 对象转换测试数据框,分类变量将被转换为具有相同编号(从类别到整数的映射)的 ‘category’ 数据类型,该编号已应用于训练数据集:

# encoding that would be gotten from the train set
train.embarked.unique()
array(['S', 'C', 'Missing', 'Q'], dtype=object)
# encoding that would be gotten from the test set
test.embarked.unique()
array(['Q', 'S', 'C'], dtype=object)
# with 'match_categories', the encoding remains the same
match_categories.transform(train).embarked.cat.categories
Index(['C', 'Missing', 'Q', 'S'], dtype='object')
# this will have the same encoding as the train set
match_categories.transform(test).embarked.cat.categories
Index(['C', 'Missing', 'Q', 'S'], dtype='object')

如果在训练数据中不存在某些类别,它将不会映射到任何整数,因此不会被编码。此行为可以通过参数 errors 进行修改:

# categories present in the train data
train.cabin.unique()
array(['B', 'C', 'E', 'D', 'A', 'M', 'T', 'F'], dtype=object)
# categories present in the test data - 'G' is new
test.cabin.unique()
array(['M', 'F', 'E', 'G'], dtype=object)
match_categories.transform(train).cabin.unique()
['B', 'C', 'E', 'D', 'A', 'M', 'T', 'F']
Categories (8, object): ['A', 'B', 'C', 'D', 'E', 'F', 'M', 'T']
# unseen category 'G' will not get mapped to any integer
match_categories.transform(test).cabin.unique()
['M', 'F', 'E', NaN]
Categories (8, object): ['A', 'B', 'C', 'D', 'E', 'F', 'M', 'T']

何时使用变压器#

在为分类列创建自定义转换器时,或者在将分类列传递给原生支持它们但将变量转换留给用户的建模包(如 lightgbmglum)时,此转换器非常有用。