r - 朴素贝叶斯的特征选择

标签 r naivebayes

我用朴素贝叶斯进行了分类。目标是通过文本预测 4 个因素。数据如下所示:

 'data.frame':  387 obs. of  2 variables:
 $ reviewText: chr  "I love this. I have a D800. I am mention my camera to make sure that you understand that this product is not ju"| __truncated__ "I hate buying larger gig memory cards - because there's always that greater risk of losing the photos, and/or r"| __truncated__ "These chromebooks are really a pretty nice idea -- Almost no maintaince (no maintaince?), no moving parts, smal"| __truncated__ "Purchased, as this drive allows a much speedier read/write and is just below a full SSD (they need to drop the "| __truncated__ ...
 $ pragmatic : Factor w/ 4 levels "-1","0","1","9": 4 4 4 3 3 4 3 3 3...

我用 caret 进行了分类包裹。分类代码如下所示:

sms_corpus <- Corpus(VectorSource(sms_raw$text))
sms_corpus_clean <- sms_corpus %>%
    tm_map(content_transformer(tolower)) %>% 
    tm_map(removeNumbers) %>%
    tm_map(removeWords, stopwords(kind="en")) %>%
    tm_map(removePunctuation) %>%
    tm_map(stripWhitespace)
sms_dtm <- DocumentTermMatrix(sms_corpus_clean)

train_index <- createDataPartition(sms_raw$type, p=0.5, list=FALSE)
sms_raw_train <- sms_raw[train_index,]
sms_raw_test <- sms_raw[-train_index,]
sms_corpus_clean_train <- sms_corpus_clean[train_index]
sms_corpus_clean_test <- sms_corpus_clean[-train_index]
sms_dtm_train <- sms_dtm[train_index,]
sms_dtm_test <- sms_dtm[-train_index,]

sms_dict <- findFreqTerms(sms_dtm_train, lowfreq= 5) 
sms_train <- DocumentTermMatrix(sms_corpus_clean_train, list(dictionary=sms_dict))
sms_test <- DocumentTermMatrix(sms_corpus_clean_test, list(dictionary=sms_dict))

convert_counts <- function(x) {
    x <- ifelse(x > 0, 1, 0)
    x <- factor(x, levels = c(0, 1), labels = c("Absent", "Present"))
}
sms_train <- sms_train %>% apply(MARGIN=2, FUN=convert_counts)
sms_test <- sms_test %>% apply(MARGIN=2, FUN=convert_counts)


ctrl <- trainControl(method="cv", 10)
set.seed(8)
sms_model1 <- train(sms_train, sms_raw_train$type, method="nb",
                trControl=ctrl)


sms_predict1 <- predict(sms_model1, sms_test)
cm1 <- confusionMatrix(sms_predict1, sms_raw_test$type)

当我以这种方式使用这个模型时,这意味着我同时对所有 4 个变量进行预测,我得到一个低 Accuracy:0.5469 ,混淆矩阵看起来像这样。

          Reference
Prediction -1  0  1  9
        -1  0  0  1  0
        0   0  0  0  0
        1   9  5 33 25
        9  11  3 33 72

当我分别对所有 4 个变量进行预测时,我得到了更好的结果。分类代码与上面相同,但不是 df$sensorial <- factor(df$sensorial)我愿意df$sensorial <- as.factor(df$sensorial == 9) 。对于其他变量,我使用 1 , -10而不是 9 。如果我这样做,我会得到 Accuracy: 0.772对于9 ,一个Accuracy:0.829对于-1 ,一个Accuracy:0.9016对于0和一个Accuracy:0.7959对于1 。此外,结果要好得多。所以一定和特征选择有关系。不同结果的原因可能是不同值的特征通常是相同的。因此,一个可能的解决方案是赋予这些特征更多的重要性,这种特征仅在存在某个值的情况下发生,但在其他值存在的情况下则不会发生。有没有办法以这种方式选择特征,这样如果我同时对所有 4 个变量进行预测,模型会更好?像加权术语文档矩阵之类的东西?

编辑:

我计算了四个值的权重,就像 Cihan Ceyhan 所说的那样:

prop.table(table(sms_raw_train$type))
         -1           0           1           9 
0.025773196 0.005154639 0.180412371 0.788659794 

modelweights <- ifelse(sms_raw_train$type == -1, 
             (1/table(sms_raw_train$type)[1]) * 0.25, 
             ifelse(sms_raw_train$type == 0, 
             (1/table(sms_raw_train$type)[2]) * 0.25,
             ifelse(sms_raw_train$type == 1, 
             (1/table(sms_raw_train$type)[3]) * 0.25,
             ifelse(sms_raw_train$type == 9, 
             (1/table(sms_raw_train$type)[4]) * 0.25,9))))    

但结果并没有更好Accuracy:0.5677

              Reference
    Prediction -1  0  1  9
            -1  1  0  1  1
            0   1  0  1  0
            1  11  3 32 20
            9   7  5 33 76

因此,也许最好分别计算每个值的结果,然后将结果相加,就像发布的第二个解决方案一样。

最佳答案

此处使用的准确性是一个具有误导性的指标。在您发布的多标签混淆矩阵中,如果您仅查看标签 -1others,则准确率约为 89%。因为您仅预测 -1 一次,并将 -1 误分类为 其他 20 次 (9+11)。对于所有其他情况,您可以正确分类 -1others 问题,因此准确度为 170/191=89%。但这当然并不意味着该模型正在按预期运行;它只是将 others 打印到几乎所有情况。这种机制也是您在单标签分类中看到更高准确度数字的原因。

参见here对类别不平衡问题以及缓解该问题的潜在方法有一个很好的概述。

还有这个thread与您的案例非常相关,所以我建议您看一下。

关于r - 朴素贝叶斯的特征选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48169370/

相关文章:

r - 在 R 中加载聚会包时出现“找不到对象”错误

python - NaiveBayes 分类器在 python 中处理不同的数据类型

c - C 中的静态到动态性质

r - 如何在 R 中无错误地显示堆栈跟踪?

r - 如何让Leaflet for R使用100%的Shiny仪表板高度

r - 尝试使用 "bnlearn"实现一个简单的朴素贝叶斯分类器。不断出现错误 "variables must be either numeric, factors or ordered factors"

python - 用一些不在训练集中的词预测分类(朴素贝叶斯)

machine-learning - 朴素贝叶斯对训练观察的数量敏感吗?

r - 创建一个增量列来绘制 R 中的时间序列差异

r - 如何从 R 中的 Betareg 模型中找到 R 平方和 Beta 值?