You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Scikit-learn使用FeatureUnion为文本分类添加非文本特征

把文本特征和非文本特征结合的scikit-learn实现方案

嘿,我懂你现在的需求——已经搞定了基础的文本分类,现在想加个非文本的number_feature来提升准确率,还想测试FeatureUnion对吧?刚好scikit-learn里有现成的工具能帮你把两种特征无缝结合,我给你一步步讲清楚怎么做~

1. 先模拟你的数据集

首先咱们先把你描述的数据集用代码模拟出来,方便后续测试:

import pandas as pd

# 按照你的要求,每个label对应固定的number_feature
data = {
    'label': ['sandwich', 'greeting', 'goodbye', 'sandwich', 'greeting', 'goodbye'],
    'message': [
        'I want a turkey sandwich', 
        'Hello there!', 
        'See you later', 
        'Can I get a ham sandwich?', 
        'Hi friend', 
        'Bye for now'
    ],
    'number_feature': [1, 2, 3, 1, 2, 3]
}
df = pd.DataFrame(data)

2. 拆分特征与目标变量

这一步很基础,把用于预测的特征(message和number_feature)和目标标签(label)分开:

X = df[['message', 'number_feature']]
y = df['label']

3. 构建特征融合的分类流水线

这里有两种方法,我推荐用官方现在主推的ColumnTransformer,比旧的FeatureUnion更直观;不过既然你提到要测试FeatureUnion,我也会把这个方法列出来。

方法一:用ColumnTransformer(推荐)

这个工具能明确指定哪一列用哪种特征处理逻辑,然后自动合并结果,非常省心:

from sklearn.compose import ColumnTransformer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.naive_bayes import MultinomialNB
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# 先拆分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 定义文本特征的处理流程:用TF-IDF提取文本特征
text_transformer = Pipeline(steps=[
    ('tfidf', TfidfVectorizer(stop_words='english'))  # 去掉英文停用词,效果更好
])

# 定义数值特征的处理流程:
# 因为你的number_feature是每个类别对应固定值,属于类别型数值,不需要缩放,直接传递就行
# 如果是真实的连续数值,可以换成StandardScaler()做标准化
numeric_transformer = Pipeline(steps=[
    ('passthrough', 'passthrough')
])

# 合并两个特征处理流程
preprocessor = ColumnTransformer(
    transformers=[
        ('text_features', text_transformer, 'message'),  # 处理message列
        ('numeric_features', numeric_transformer, ['number_feature'])  # 处理number_feature列
    ])

# 构建完整的分类流水线:特征预处理 + 分类器
clf = Pipeline(steps=[
    ('preprocessor', preprocessor),
    ('classifier', MultinomialNB())  # 你也可以换成其他分类器,比如SVM、RandomForest
])

# 训练模型并预测
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)

# 输出准确率
print(f"加入number_feature后的准确率: {accuracy_score(y_test, y_pred):.2f}")

因为你的number_feature和label是一一对应的,理论上加入这个特征后准确率会接近100%,刚好能验证特征融合的效果~

方法二:用FeatureUnion(旧方法,用于测试)

FeatureUnion是对处理后的特征矩阵进行合并,需要先自定义一个工具来提取DataFrame的指定列:

from sklearn.pipeline import FeatureUnion
from sklearn.base import BaseEstimator, TransformerMixin

# 自定义列选择器,用来从DataFrame中提取指定列并转换成合适的格式
class ColumnSelector(BaseEstimator, TransformerMixin):
    def __init__(self, column):
        self.column = column
    
    def fit(self, X, y=None):
        return self
    
    def transform(self, X):
        # 如果是数值列,转成二维数组;文本列直接返回一维数组给TF-IDF处理
        if isinstance(X[self.column].values[0], (int, float)):
            return X[self.column].values.reshape(-1, 1)
        else:
            return X[self.column].values

# 构建文本特征处理流水线
text_pipeline = Pipeline([
    ('selector', ColumnSelector('message')),
    ('tfidf', TfidfVectorizer(stop_words='english'))
])

# 构建数值特征处理流水线
numeric_pipeline = Pipeline([
    ('selector', ColumnSelector('number_feature')),
    ('passthrough', 'passthrough')  # 同样,因为是类别型数值,直接传递
])

# 合并两个特征流水线的结果
feature_union = FeatureUnion([
    ('text_features', text_pipeline),
    ('numeric_features', numeric_pipeline)
])

# 完整分类流水线
clf = Pipeline([
    ('features', feature_union),
    ('classifier', MultinomialNB())
])

# 训练预测
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)
print(f"用FeatureUnion实现的准确率: {accuracy_score(y_test, y_pred):.2f}")

4. 后续优化建议

  • 如果你的number_feature是真实的连续数值(不是和label绑定的),可以试试用StandardScaler或者MinMaxScaler做标准化,提升部分分类器的效果;
  • 文本特征部分可以试试调整TfidfVectorizer的参数,比如ngram_range=(1,2)加入二元词组,或者自定义停用词;
  • 分类器也可以换成LogisticRegression、RandomForestClassifier等,对比不同模型的效果。

内容的提问来源于stack exchange,提问作者borb183

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:18:22