ColumnTransformer & Pipeline with OHE - 执行 ct 后,OHE 编码字段是保留还是删除?

ColumnTransformer & Pipeline with OHE - Is the OHE encoded field retained or removed after ct is performed?

CT 文档:

remainder{‘drop’, ‘passthrough’} or estimator, default=’drop’

By default, only the specified columns in transformers are transformed and combined in the output, and the non-specified columns are dropped. (default of 'drop'). By specifying remainder='passthrough', all remaining columns that were not specified in transformers will be automatically passed through. This subset of columns is concatenated with the output of the transformers. By setting remainder to be an estimator, the remaining non-specified columns will use the remainder estimator. The estimator must support fit and transform. Note that using this feature requires that the DataFrame columns input at fit and transform have identical order.

我相信这个 remainder= 与被 OneHot 编码的字段无关。我想知道如何处理 OHE 字段(例如 'CatX')。

当我进行独立的 CT 转换时,我发现 'CatX' 没有出现在输出中。

ct = ColumnTransformer(transformers=[('OHE',ohe,ohe_col)],remainder='passthrough')

当我重复OHE进行独立CT时,它成功了(即OHE 2次)。这告诉我在 CT 中,该字段仍然可用,但仅在退出 CT 时被删除。

ct = ColumnTransformer(transformers=[('OHE',ohe,ohe_col),('OHE1',ohe,ohe_col)],
remainder='passthrough')

然后我尝试将其放入管道中,我尝试进行两次 CT。这是令人困惑的部分。它过去了。这告诉我第一个 CT1 将 'CatX' 传给了 CT2。

ct = ColumnTransformer(transformers=[('OHE',ohe,ohe_col)],remainder='passthrough')    
Pipeline([('ct1',ct),('ct2',ct)('model',v)])

问题:

  1. 使用 Pipeline 时,谁在控制 CT 是否会在退出时通过 'CatX'?
  2. 使用 Pipeline 时,如果正在传递 'CatX',那么模型是否无法处理它?

我希望我的问题很清楚。感谢您提前回答。

ColumnTransformer 是指通过指定的转换转换 数组或数据帧的列。这意味着在拟合之后你将不再有原来的列。

import pandas as pd
from sklearn.compose import ColumnTransformer, make_column_selector
from sklearn.preprocessing import OneHotEncoder

X = pd.DataFrame({'city': ['London', 'London', 'Paris', 'Sallisaw'],
              'title': ['His Last Bow', 'How Watson Learned the Trick', 'A Moveable Feast', 'The Grapes of Wrath'],
              'expert_rating': [5, 3, 4, 5],
              'user_rating': [4, 5, 4, 3]})

ct = ColumnTransformer(transformers=[
    ('ohe', OneHotEncoder(), make_column_selector(pattern='city'))], 
    remainder='passthrough', verbose_feature_names_out=False)

pd.DataFrame(ct.fit_transform(X), columns=ct.get_feature_names_out())

同时你应该意识到 ColumnTransformer 并行应用它的转换器 这就是为什么在你的第二个例子中你会看到OHE 应用了两次,即因为两个 OHE 转换器都作用于原始数据。有关于此的有趣帖子,请参阅 and here and 例如

因此,这将是通过 ColumnTransformer:

应用两次转换时的结果
ct_d = ColumnTransformer(transformers=[
    ('ohe1', OneHotEncoder(), make_column_selector(pattern='city')),
    ('ohe2', OneHotEncoder(), make_column_selector(pattern='city'))], 
    remainder='passthrough', verbose_feature_names_out=True)

pd.DataFrame(ct_d.fit_transform(X), columns=ct_d.get_feature_names_out())

然后,我不确定在使用 Pipeline 时是否正确解决了您的问题(也许添加一些细节可能会有用,或者我可能忽略了某些地方)。这就是我在避免通过 ColumnTransformer; 的实例时得到的结果;由于 OneHotEncoder 将其删除,您将找不到原始列。

from sklearn.pipeline import Pipeline

pipe_new = Pipeline([('ohe', OneHotEncoder())])
pd.DataFrame(pipe_new.fit_transform(pd.DataFrame(X['city'])).toarray())

另一方面,这里的示例可能类似于您对 Pipeline 的使用。即,列 cityct1 中进行了单热编码,其输出(实际上是其输出的第 0 列)在应用 ct2 时经历了相同的命运(其余列是通过传递)。更具体地说,ct1 输出 (np.array([1.0, 1.0, 0.0, 0.0]).T) 的第 0 列被单热编码为 np.array([[0.0, 0.0, 1.0, 1.0], [1.0, 1.0, 0.0, 0.0]]).T (实际上它不会是 np 数组,我是这样写的只是为了便于记法)。

ct = ColumnTransformer(transformers=[
    ('ohe', OneHotEncoder(), [0])], remainder='passthrough', verbose_feature_names_out=False)

pipe = Pipeline([
    ('ct1', ct),
    ('ct2', ct)
])

pd.DataFrame(pipe.fit_transform(X))