如何在管道中添加外部功能?

问题描述

这么多年前,这里也有类似的问题,但没有答案。我也有同样的问题。我想在建立TfidfVectorizer和进行{{1之前,将新的数据列(在我的情况下为3列虚拟变量)添加到稀疏矩阵(来自Pipeline)中。 }},以找到最佳的超级参数。

目前,我可以使用下面的代码在没有GridSearchGridSearch的情况下按模型进行此模型处理。

Pipeline

从这里,我可以将模型拟合到# this is an NLP project X = df["text"] # column of text y = df["target"] # continuous target variable X_train,X_unseen,y_train,y_unseen = train_test_split(X,y,test_size=0.5,stratify=df_merged["platform"],random_state=42) # vectorize tvec = TfidfVectorizer(stop_words="english") X_train_tvec = tvec.fit_transform(X_train) # get dummies dummies = pd.get_dummies(df["dummies"]).values # add dummies to tvec sparse matrix X_train_tvec_dumm = hstack([X_train_tvec,dummies]).toarray() 训练数据上,该训练数据包括来自X_train_tvec_dumm的单词向量和3个虚拟列的稀疏矩阵(形状:n_rows,n_columns)。因此,最终形状为(n_rows,n_columns + 3)。

我尝试按照以下步骤构建TfidfVectorizer

Pipeline

一个tutorial描述了如何为# get dummies dummies = pd.get_dummies(df["dummies"]).values def add_dummies(matrix): return hstack([matrix,dummies]).toarray() pipe = Pipeline([ ("features",FeatureUnion([ ("tvec",TfidfVectorizer(stop_words="english")),("dummies",add_dummies(??)) <-- how do I add this step into the pipeline? ])),("ridge",RidgeCV()) ]) pipe_params = { 'features__tvec__max_features': [200,500],'features__tvec__ngram_range': [(1,1),(1,2)] } gs = gridsearchcv(pipe,param_grid=pipe_params,cv=4) gs.fit(X_train,y_train) print(gs.best_score_) 构建自定义转换器,但是其自定义函数添加了通过在X_train上进行转换而设计的新功能。不幸的是,我的虚拟变量位于X_train集合的外部。

解决方法

使用get_dummies中的OneHotEncodersklearn.preprocessing中的ColumnTransformer来代替熊猫sklearn.compose。创建一个同时具有“文本”和“类别|假人”列作为特征的DataFrame。

OneHotEncoder需要整数类型的功能。如果您的功能不是int类型,请先将其编码|映射为int,然后应用OneHotEncoder

# ...
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import OneHotEncoder


text_features = ['text']
text_transformer = Pipeline(steps=[
    ('vectorizer',TfidfVectorizer(stop_words="english"))])

categorical_features = ['category']
categorical_transformer = Pipeline(steps=[
    ('imputer',SimpleImputer(strategy='constant',fill_value='missing')),('onehot',OneHotEncoder(handle_unknown='ignore'))])

preprocessor = ColumnTransformer(
    transformers=[
        ('text',text_transformer,text_features),('cat',categorical_transformer,categorical_features)])


pipe =  Pipeline(steps=[('preprocessor',preprocessor),("ridge",RidgeCV())
])

# ...