首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我怎样才能排除特定的列从柱变压器/管道滑雪?

我怎样才能排除特定的列从柱变压器/管道滑雪?
EN

Stack Overflow用户
提问于 2022-09-12 09:40:20
回答 2查看 430关注 0票数 2

我正在尝试用sklearn管道和ColumnTransformer构建一个数据预处理管道。预处理步骤包括并行输入值和将(幂变换、缩放或OHE)转换为特定列。这个预处理ColumnTransform工作得很好。

但是,在对预处理结果做了一些分析之后,我决定从最终结果中排除一些列。我的目标是有一个管道,从原始数据开始,输入和转换值,排除预选的列,并触发模型拟合为一体。所以要明确的是,我不想在管道安装/转换后掉下柱子。相反,我希望删除列的过程是列转换的一部分。

从模型中移除数值列很容易(简单地不添加它们),但是我如何排除由OHE创建的列?我不想排除所有由OHE创建的列,只是其中的一部分。例如,如果分类列“示例”变成Example_1、Example_2和Example_3,我如何只排除Example_2?

示例代码:

代码语言:javascript
复制
### Importing libraries
from sklearn.impute import SimpleImputer
SimpleImputer.get_feature_names_out = (lambda self, names = None: self.feature_names_in_) # SimpleImputer does not have get_feature_names_out, so we need to add it manually.
from sklearn.preprocessing import OneHotEncoder, MinMaxScaler
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer


### Dummy dataframe
df_foo = pd.DataFrame({'Num_col' : [1,2,np.nan,4,5,6,7,np.nan,9],
                       'Example' : ['A','B','C','A','B','A','A','C','C'], 
                       'another_col' : range(10,100,10)})

### Pipelines
SimpImpMean_MinMaxScaler = Pipeline([
    ('SimpleImputer', SimpleImputer(strategy="mean")),
    ('MinMaxScaler', MinMaxScaler()),
])
SimpImpConstNoAns_OHE = Pipeline([
    ('SimpleImputer', SimpleImputer(strategy="constant", fill_value='no_answer')),
    ('OHE', OneHotEncoder(sparse=False, drop='if_binary', categories='auto')),
])

### ColumnTransformer
preprocessor_transformer = ColumnTransformer([
    ('pipeline-1', SimpImpMean_MinMaxScaler, ['Num_col']),
    ('pipeline-2', SimpImpConstNoAns_OHE, ['Example'])
     ],
    remainder='drop',
    verbose_feature_names_out=False)
preprocessor_transformer


### Preprocessing dummy dataframe
df_foo = pd.DataFrame(preprocessor_transformer.fit_transform(df_foo), 
            columns=preprocessor_transformer.get_feature_names_out()
            )
print(df_foo)

最后,我看到了这个解决方案(Adding Dropping Column instance into a Pipeline),但我没有设法使自定义columnDropperTransformer在我的情况下工作。将columnDropperTransformer添加到管道中将返回一个ValueError:给定的列不是dataframe的列,它引用不再存在于dataframe中的列“ValueError”。

代码语言:javascript
复制
class columnDropperTransformer():
    def __init__(self,columns):
        self.columns=columns

    def transform(self,X,y=None):
        return X.drop(self.columns,axis=1)

    def fit(self, X, y=None):
        return self 

processor= make_pipeline(preprocessor_transformer,columnDropperTransformer([]))

processor.fit_transform(df_foo)

有什么建议吗?

EN

回答 2

Stack Overflow用户

发布于 2022-09-12 15:44:47

根据我的经验和今天,在sklearn中自动化这类治疗并不容易,原因如下:

  • Pipeline执行的步骤(在它上调用.fit_transform()时)会使您失去DataFrame结构(熊猫DataFrame变成一个numpy数组)。我建议你读

How to be sure that sklearn piepline applies fit_transform method when using feature selection and ML model in piepline?how to use ColumnTransformer() to return a dataframe?

有关在.fit()实例上调用Pipeline.fit_transform()时发生的事情的详细信息.

反过来,numpy数组中的“列”不能再通过名称引用,而只能通过positionally.引用。

以下是一些不能扩展的 imo解决方案,但可以适用于您的情况:

  1. 您可以在管道中添加一个步骤,该步骤只用于将numpy数组(它是管道执行的中间转换的标准输出)转换回DataFrame中(通过ColumnExtractor转换器)。一旦有了DataFrame,就可以利用引用链接的columnDropperTransformer通过其名称删除列Example_B

从sklearn.base导入BaseEstimator,TransformerMixin类ColumnExtractor(BaseEstimator,TransformerMixin):def __init__( self,columns):self.columns =列def转换(self,X,*_):返回pd.DataFrame(X,columns=self.columns) def fit(self,*_):返回self class columnDropperTransformer():def __init__(self,columns):self.columns=columns def transform(self,X,( y=None):返回X.drop(self.columns,axis=1)适合(自我,X,y=None):返回自我

ColumnExtractor转换器只用于映射DataFrame中的结果数组。明显的缺点是,您需要手动指定希望您的DataFrame由哪些列组成。

从sklearn.impute导入SimpleImputer SimpleImputer.get_feature_names_out = (lambda,name= None: self.feature_names_in_) # SimpleImputer没有get_feature_names_out,因此我们需要手动添加它。从sklearn.preprocessing OneHotEncoder进口,从sklearn.pipeline进口管道从sklearn.compose进口ColumnTransformer从sklearn.pipeline进口ColumnTransformer ColumnTransformer从sklearn.pipeline进口熊猫'another_col‘:range(10,100,10)}) SimpImpMean_MinMaxScaler =管道('SimpleImputer',SimpleImputer(strategy=“SimpleImputer’)),('MinMaxScaler',MinMaxScaler(),) SimpImpConstNoAns_OHE =管道('SimpleImputer',SimpleImputer(strategy=”常数“,fill_value=‘no_答案’),('OHE',OneHotEncoder(sparse=False,drop=‘if_二进制’,类别=‘auto’),) ### ColumnTransformer preprocessor_transformer = ColumnTransformer([ (“管道-1”,SimpImpMean_MinMaxScaler,“Num_col”),(“管道-2”,SimpImpConstNoAns_OHE,“示例”),余数=‘drop’,verbose_feature_names_out=False)处理器= make_pipeline( preprocessor_transformer,ColumnExtractor( 'Num_col‘),’示例_A‘,’示例_B‘,’Example_C‘) f_processor = make_pipeline(处理器,f_processor.fit_transform(df_foo) columnDropperTransformer(‘Example_B’)

  1. 您可以引用数组的“列”,它是从Pipeline转换的应用程序(即按索引)中得到的。例如,您可以定义这样一个虚拟转换器。

类NumpyColumnSelector():def __init__( self ):传递def变换(self,X,y=None):返回X[:,0,1,3]

它只保留所有列,但与Example_B列对应的列除外。

从sklearn.impute导入SimpleImputer SimpleImputer.get_feature_names_out = (lambda,name= None: self.feature_names_in_) # SimpleImputer没有get_feature_names_out,因此我们需要手动添加它。从sklearn.preprocessing OneHotEncoder进口,从sklearn.pipeline进口管道从sklearn.compose进口ColumnTransformer从sklearn.base进口BaseEstimator,TransformerMixin从sklearn.pipeline进口make_pipeline进口熊猫作为pd进口numpy作为np ###虚拟数据交换df_foo = pd.DataFrame({'Num_col‘:1,2,np.nan,4,5,6,7,np.nan,9,’示例“:'A','B','C','A','B','A','A','C','C','another_col‘:range(10,100,10)}) SimpImpMean_MinMaxScaler =管道('SimpleImputer',SimpleImputer(strategy=’strategy=‘SimpleImputer’),('MinMaxScaler',MinMaxScaler(),) SimpImpConstNoAns_OHE =管道('SimpleImputer',SimpleImputer(“常数”,fill_value=‘no_答案’),('OHE',OneHotEncoder(sparse=False ),drop=‘if_二进制’,MinMaxScaler=‘auto’),) f_processor.fit_transform(df_foo) ) ### ColumnTransformer preprocessor_transformer = ColumnTransformer([ (“管道-1”,SimpImpMean_MinMaxScaler,“Num_col”),(“管道-2”,SimpImpConstNoAns_OHE,“示例”) ],余数=“下降”,verbose_feature_names_out=False) f_processor = make_pipeline(preprocessor_transformer,NumpyColumnSelector())

票数 2
EN

Stack Overflow用户

发布于 2022-09-12 20:30:11

对于删除由OHE生成的虚拟列的非常具体的用例(对于一个更通用的答案,+1到amiola ),您可以指定categorieshandle_unknown='ignore'。在您的示例中,将OHE行替换为:

代码语言:javascript
复制
('OHE', OneHotEncoder(sparse=False, categories=[['A', 'C']], handle_unknown='ignore')),

产生这种情况:

代码语言:javascript
复制
    Num_col  Example_A  Example_C
0  0.000000        1.0        0.0
1  0.125000        0.0        0.0
2  0.482143        0.0        1.0
3  0.375000        1.0        0.0
4  0.500000        0.0        0.0
5  0.625000        1.0        0.0
6  0.750000        1.0        0.0
7  0.482143        0.0        1.0
8  1.000000        0.0        1.0
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73687267

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档