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

基于RandomForest与TF-IDF的文本情感分类混淆矩阵异常排查

为啥RandomForest+TF-IDF把所有Bad样本都判成Good?

咱先从你的结果倒推问题:看混淆矩阵里的样本数,Bad类总共才2631个,Good类却有10166个——Good样本是Bad的近4倍,这是严重的类别不平衡!

RandomForest这类树模型有个特点:它会优先追求整体准确率。你算下,哪怕把所有样本都判成Good,准确率也能达到 10166/(10166+2631)≈79.5%,正好和你得到的准确率完全一致!模型觉得“反正判成Good准没错,不用费劲找Bad的特征”,直接躺平偏向多数类了。

那为啥MultinomialNB+CountVectorizer就正常?这得说两个点:

  • NB模型本身的特性:MultinomialNB是基于概率统计的,它会考虑每个类别的先验概率,不会单纯被多数类的数量优势带偏;
  • 特征类型的适配性:CountVectorizer保留了词的原始计数,NB这类依赖词频统计的模型对这种特征天生适配,能抓得住Bad类的特征词信号;而TF-IDF会压低高频通用词的权重,万一Bad类的特征词刚好是相对高频的(比如“差”“烂”这类吐槽词),TF-IDF反而削弱了它们的区分度,让RandomForest更难学到Bad类的特征。

给你几个解决RandomForest+TF-IDF问题的办法

1. 先搞定类别不平衡

这是核心问题,有两种思路:

  • 给模型加class_weight='balanced'参数,让模型自动给少数类(Bad)更高的权重,强迫它重视少数类:
    rf = RandomForestClassifier(n_estimators=50, max_depth=20, n_jobs=-1, class_weight='balanced')
    
  • 对数据做采样:要么给Bad类做过采样(比如用SMOTE算法生成更多Bad样本),要么给Good类做欠采样(随机删掉一部分Good样本),让两类样本量尽量均衡。

2. 调整TF-IDF的参数

试试过滤掉无意义的噪声特征,比如设置min_df=5(去掉在少于5个样本里出现的词),或者max_df=0.8(去掉在80%以上样本里出现的通用词),让TF-IDF保留更有区分度的特征:

tfidf_vect = TfidfVectorizer(analyzer=clean_text, min_df=5, max_df=0.8)

3. 调优RandomForest的参数

你当前设的max_depth=20可能太浅了,模型欠拟合,根本学不到Bad类的特征。试试把max_depth设大一点(比如改成None,让树完全生长),或者增加n_estimators的数量(比如调到100),给模型更多学习的空间。

4. 用分层交叉验证划分数据集

你之前用的train_test_split是随机划分的,万一测试集里Bad样本占比极低,也会影响结果。改用StratifiedKFold做分层交叉验证,保证训练集和测试集的类别分布和原数据一致:

from sklearn.model_selection import StratifiedKFold
skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
for train_idx, test_idx in skf.split(X_tfidf, df['Label']):
    X_train, X_test = X_tfidf[train_idx], X_tfidf[test_idx]
    y_train, y_test = df['Label'][train_idx], df['Label'][test_idx]
    # 后续模型训练代码

先确认你的数据分布

可以先跑一行代码看看标签的具体分布,验证咱的判断:

print(df['Label'].value_counts())

要是Good的占比确实远高于Bad,那类别不平衡就是罪魁祸首啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 19:38:10