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

求助:含文本与分类特征的数据集如何正确应用SMOTE解决类别不平衡

解决文本+多特征场景下SMOTE与Pipeline整合问题

问题根源分析

你之前的方案存在两个核心问题:

  1. 未处理非文本的分类特征:ColumnTransformer仅对description做了TF-IDF向量化,但其他分类特征如果是字符串格式,remainder='passthrough'会直接保留原格式,SMOTE无法处理非数值特征,导致采样逻辑异常甚至静默失效。
  2. 对ImbPipeline的采样逻辑理解偏差:ImbPipeline会自动在模型拟合前对训练数据执行采样,但前提是所有输入特征都是数值型,且采样策略配置正确。

正确解决方案

1. 统一预处理所有特征

用ColumnTransformer批量处理不同类型的特征:文本特征做TF-IDF向量化,分类特征做独热编码,数值特征直接保留。

示例代码:

from sklearn.compose import ColumnTransformer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.preprocessing import OneHotEncoder

# 替换为你的实际特征列名
text_cols = ['description']
cat_cols = ['category1', 'category2']
num_cols = ['num_feature1', 'num_feature2']

# 构建预处理管道
column_transformer = ColumnTransformer(
    transformers=[
        ('tfidf', TfidfVectorizer(max_features=5000), text_cols),  # 限制特征数避免高维问题
        ('onehot', OneHotEncoder(handle_unknown='ignore', sparse_output=False), cat_cols)
    ],
    remainder='passthrough',  # 直接保留数值特征
    verbose_feature_names_out=False  # 生成简洁特征名(可选)
)

2. 构建正确的ImbPipeline

按「预处理→SMOTE→分类器」的顺序组装管道,同时配置SMOTE的采样策略:

from imblearn.pipeline import ImbPipeline
from imblearn.over_sampling import SMOTE
from sklearn.ensemble import RandomForestClassifier

# 初始化SMOTE与分类模型
smote = SMOTE(
    sampling_strategy='auto',  # 默认将少数类采样至与多数类数量一致;多分类可手动指定比例
    k_neighbors=5,
    random_state=42
)
rf_model = RandomForestClassifier(n_estimators=100, random_state=42)

# 完整管道
pipeline = ImbPipeline([
    ('preprocessing', column_transformer),
    ('smote', smote),
    ('classifier', rf_model)
])

3. 验证SMOTE生效

拟合后可手动检查采样前后的类别分布,确认SMOTE是否正常工作:

from collections import Counter

# 拟合管道
pipeline.fit(X_train, y_train)

# 获取预处理后的特征矩阵并应用SMOTE
X_processed = pipeline.named_steps['preprocessing'].transform(X_train)
X_resampled, y_resampled = pipeline.named_steps['smote'].fit_resample(X_processed, y_train)

# 打印类别分布对比
print("原始训练集类别分布:", Counter(y_train))
print("SMOTE采样后类别分布:", Counter(y_resampled))

4. 合理评估模型

类别不平衡场景下准确率无参考价值,需用F1-score、召回率、混淆矩阵等指标评估:

from sklearn.metrics import classification_report
from sklearn.model_selection import cross_val_score

# 分层交叉验证(适配类别不平衡)
cv_scores = cross_val_score(pipeline, X_train, y_train, cv=5, scoring='f1_macro', n_jobs=-1)
print("交叉验证F1分数均值:", cv_scores.mean())

# 测试集评估
y_pred = pipeline.predict(X_test)
print(classification_report(y_test, y_pred))

常见失效排查点

如果SMOTE仍未生效,检查以下内容:

  • 所有特征是否已转换为数值型:可通过column_transformer.transform(X_train).dtype验证;
  • SMOTE的sampling_strategy是否匹配你的类别分布(多分类场景需手动指定);
  • 是否误用了普通Pipeline而非ImbPipeline:普通Pipeline不会自动在训练阶段应用采样器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 22:17:43