如何在分类任务中通过FeatureUnion使用2个TfidfVectorizer?
同一任务使用多个TfidfVectorizer的可行性与实现
可行性说明
完全可行,且针对你遇到的场景非常可取。普通文本和LaTeX内容的语法规则、有效语义单元差异极大,使用两个独立的TfidfVectorizer分别提取两类文本的特征,比强制用同一套向量化规则的效果更好,属于多模态文本特征工程的常规操作。
实现方法
你当前用的FeatureUnion机制本身就支持多分支特征提取,只需要新增LaTeX文本的处理分支即可,修改后的流水线示例如下:
import numpy as np from sklearn.pipeline import Pipeline, FeatureUnion from sklearn.preprocessing import FunctionTransformer from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.ensemble import RandomForestClassifier # 假设df的结构为:[数值特征1, 数值特征2, ..., 普通文本, LaTeX文本] # 三个数据选择器分别提取对应类型的字段 def get_numeric_data(df): # 取除了最后两列文本之外的所有数值字段 return np.array([record[:-2].astype(float) for record in df]) def get_normal_text(df): # 取倒数第二列的普通文本 return [record[-2] for record in df] def get_latex_text(df): # 取倒数第一列的LaTeX文本 return [record[-1] for record in df] # 初始化各选择器 transformer_numeric = FunctionTransformer(get_numeric_data) transformer_normal_text = FunctionTransformer(get_normal_text) transformer_latex_text = FunctionTransformer(get_latex_text) pipeline = Pipeline([ ('features', FeatureUnion([ # 数值特征分支 ('numeric_features', Pipeline([ ('selector', transformer_numeric) ])), # 普通文本特征分支:用默认适配普通文本的Tfidf配置 ('normal_text_features', Pipeline([ ('selector', transformer_normal_text), ('vec', TfidfVectorizer(analyzer='word', stop_words='english')) ])), # LaTeX文本特征分支:单独配置适配LaTeX语法的向量化参数 ('latex_text_features', Pipeline([ ('selector', transformer_latex_text), # 可自定义token_pattern匹配LaTeX命令、公式符号等特殊单元 ('vec', TfidfVectorizer(analyzer='word', token_pattern=r'[a-zA-Z0-9\\{}_^]+', ngram_range=(1,2))) ])) ])), ('clf', RandomForestClassifier()) ])
额外说明
- 两个TfidfVectorizer独立拟合、各自维护词表,不会互相干扰,训练阶段会分别用对应字段的文本完成拟合,预测阶段也会分别处理两类文本再拼接所有特征送入分类器。
- 如果你的样本是分批次的,一部分只有普通文本、一部分只有LaTeX文本,可以再额外添加分支判断逻辑,也可以替换为
ColumnTransformer更便捷地按列选择不同字段处理。
内容的提问来源于stack exchange,提问作者Deshwal
相关产品推荐
相关产品推荐

