带OHE的ColumnTransformer&管道-执行ct后,OHE编码字段是保留还是删除?

2022-04-09 00:00:00 python scikit-learn pipeline

问题描述

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.

我认为这个余数=与正在进行OneFire编码的字段无关。我想知道OHE领域是怎样的(例如。"CatX")正在处理中。

当我执行独立的CT转换时,我看到‘CATx’没有出现在输出中。

ct = ColumnTransformer(transformers=[('OHE',ohe,ohe_col)],remainder='passthrough')
当我做一个单独的CT,重复OHE时,它是成功的(即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. 使用管道时,谁控制CT是否在退出时传递‘CATx’?
  2. 使用管道时,如果正在传递"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转换器都作用于原始数据。关于这一点有一些有趣的帖子,参见here和here和here,例如

因此,这将是通过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的示例。也就是说,city列在ct1中是热编码的,当应用ct2时,它的输出(实际上是其输出的第0列)经历了相同的命运(其余的列被传递)。更具体地说,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))

相关文章