问题描述
这么多年前,这里也有类似的问题,但没有答案。我也有同样的问题。我想在建立TfidfVectorizer
和进行{{1之前,将新的数据列(在我的情况下为3列虚拟变量)添加到稀疏矩阵(来自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
的单词向量和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
中的OneHotEncoder
和sklearn.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())
])
# ...