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

朴素贝叶斯多分类特征选择优化:提升多类别同时预测精度

多类别Naive Bayes文本分类性能优化建议

问题回顾

你正在用Naive Bayes处理4类别文本分类任务,数据集含387条观测,核心变量是文本reviewText和4水平因子pragmatic("-1","0","1","9")。目前遇到的核心问题是:

  • 多类别同时预测精度仅0.5469,混淆矩阵显示模型几乎无法识别-1和0类别,严重偏向占比最高的9类别
  • 但将每个类别单独做二分类时,精度显著提升(9类0.772、-1类0.829、0类0.9016、1类0.7959)
  • 尝试类别权重调整后,精度仅小幅提升至0.5677,效果不理想

推测核心原因是全局特征选择无法捕捉类别特异性词汇,加上严重的类别不平衡(训练集9类占比78.87%,0类仅0.52%),导致多类别模型难以有效区分不同类别。

针对性解决方案

一、面向多类别的特征选择优化

针对Naive Bayes的特性,你可以尝试以下特征选择策略,筛选出类别特异性更强的词汇:

  1. 类别特异性词筛选(互信息/卡方检验)
    不要只用全局高频词(findFreqTerms),而是计算每个词汇与不同类别的关联度,保留对单个类别区分度高的词。比如用卡方检验筛选每个类别的Top N特征:

    library(quanteda)
    # 构建训练集的DFM矩阵
    train_corpus <- corpus(sms_raw_train, text_field = "text")
    train_dfm <- dfm(train_corpus, 
                     tolower = TRUE, 
                     remove_punct = TRUE, 
                     remove_numbers = TRUE, 
                     stopwords = "english")
    # 计算词与类别的卡方值
    chi_scores <- textstat_keyness(train_dfm, target = sms_raw_train$type, measure = "chi2")
    # 筛选每个类别top20的特征
    top_terms <- chi_scores %>% 
      group_by(feature) %>% 
      slice_max(n=20, order_by=chi2)
    # 用筛选后的特征构建新的矩阵
    filtered_dtm <- dfm_select(train_dfm, pattern = top_terms$feature)
    

    这种方法能过滤掉那些在所有类别中都高频的通用词,保留真正能区分类别的词汇。

  2. TF-IDF加权替代二元特征
    你当前用的是二元特征(词存在/不存在),可以换成TF-IDF加权,它能降低高频通用词的权重,提升低频但类别特异性词的权重:

    # 构建TF-IDF矩阵
    sms_tfidf <- DocumentTermMatrix(sms_corpus_clean, 
                                    control = list(weighting = weightTfIdf))
    # 后续分割训练测试集、筛选特征的步骤和之前一致
    

    对于文本分类,TF-IDF通常比二元特征更能捕捉文本的语义差异,尤其适合多类别场景。

  3. 基于模型的特征重要性筛选
    训练多类别Naive Bayes后,提取每个特征对不同类别的后验概率差异,筛选出那些能显著拉开类别差距的特征。比如计算每个词在类别c中的概率与其他类别平均概率的差值,保留差值较大的词。

二、One-vs-Rest(OvR)单类别预测融合方案

从你的二分类结果来看,每个类别单独预测的精度远高于多类别模型,这种情况下OvR融合方案会是更优选择,具体步骤:

  1. 训练4个二分类Naive Bayes模型,每个模型对应一个类别(比如模型1:-1 vs 其他;模型2:0 vs 其他,以此类推)
  2. 对每个测试样本,获取4个模型的预测概率(而非硬分类结果)
  3. 选择概率最高的类别作为最终分类结果

示例代码:

# 定义训练单个二分类模型的函数
train_ovr_model <- function(target_class, train_data, train_labels) {
  binary_labels <- as.factor(train_labels == target_class)
  ctrl <- trainControl(method="cv", 10)
  set.seed(8)
  model <- train(train_data, binary_labels, method="nb", trControl=ctrl)
  return(model)
}

# 训练4个OvR模型
target_classes <- c("-1", "0", "1", "9")
ovr_models <- lapply(target_classes, function(c) {
  train_ovr_model(c, sms_train, sms_raw_train$type)
})

# 获取每个模型的预测概率
predict_probs <- lapply(ovr_models, function(m) {
  predict(m, sms_test, type="prob")[,2]  # 取正类的概率
})
predict_probs_df <- do.call(cbind, predict_probs)
colnames(predict_probs_df) <- target_classes

# 选择概率最高的类别作为最终预测
final_predict <- apply(predict_probs_df, 1, function(x) {
  names(x)[which.max(x)]
})

# 评估融合后的结果
cm_ovr <- confusionMatrix(as.factor(final_predict), sms_raw_test$type)

这种方式能避免多类别模型中少数类别被主导的问题,充分利用每个二分类模型的优势。

额外注意事项

  • 极端类别不平衡处理:你的训练集中0类仅占0.52%,属于极端不平衡,即使加权也很难有效学习。可以尝试:
    • 过采样:用SMOTE等方法合成少数类别的样本
    • 调整二分类阈值:降低少数类别的判定阈值,让模型更容易预测到少数类别
  • 预处理优化:添加词干提取(tm_map(stemDocument))或词形还原,减少词汇冗余;也可以尝试保留部分有意义的停用词(比如情感类词汇)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:32:09