如何将外部功能添加到我的管道?
How do I add external features to my pipeline?
很多年前这里有人问过类似的问题,但没有答案。我也有同样的问题。在构建 Pipeline
和执行 GridSearch
找到最好的超参数。
目前,我可以使用下面的代码在没有 GridSearch
和 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
训练数据,其中包括来自 [=12= 的词向量的稀疏矩阵(形状:n_rows、n_columns) ] 和 3 个虚拟列。因此最终的形状是 (n_rows, n_columns + 3).
我尝试按如下方式构建 Pipeline
。
# 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_)
tutorial 描述了如何为 Pipeline
构建自定义转换器,但其自定义函数添加了通过在 X_train 上进行转换而设计的新功能。不幸的是,我的虚拟变量在 X_train 集合之外。
不要使用 pandas 中的 get_dummies
,而是使用 sklearn.preprocessing
中的 OneHotEncoder
,以及 sklearn.compose
中的 ColumnTransformer
。使用 'text' 和 'category|dummies' 列作为特征创建一个 DataFrame。
OneHotEncoder
需要整数类型的特征。如果你的特征不是int类型,先encode|map成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())
])
# ...
很多年前这里有人问过类似的问题,但没有答案。我也有同样的问题。在构建 Pipeline
和执行 GridSearch
找到最好的超参数。
目前,我可以使用下面的代码在没有 GridSearch
和 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
训练数据,其中包括来自 [=12= 的词向量的稀疏矩阵(形状:n_rows、n_columns) ] 和 3 个虚拟列。因此最终的形状是 (n_rows, n_columns + 3).
我尝试按如下方式构建 Pipeline
。
# 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_)
tutorial 描述了如何为 Pipeline
构建自定义转换器,但其自定义函数添加了通过在 X_train 上进行转换而设计的新功能。不幸的是,我的虚拟变量在 X_train 集合之外。
不要使用 pandas 中的 get_dummies
,而是使用 sklearn.preprocessing
中的 OneHotEncoder
,以及 sklearn.compose
中的 ColumnTransformer
。使用 'text' 和 'category|dummies' 列作为特征创建一个 DataFrame。
OneHotEncoder
需要整数类型的特征。如果你的特征不是int类型,先encode|map成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())
])
# ...