朴素贝叶斯 e1071 将每个姓氏分类为相同的祖先

Posted

技术标签:

【中文标题】朴素贝叶斯 e1071 将每个姓氏分类为相同的祖先【英文标题】:Naive Bayes e1071 classifies every surname as the same ancestry 【发布时间】:2016-05-28 11:01:10 【问题描述】:

我是一个新手,我希望使用朴素贝叶斯分类器根据个人的 3-gram 姓氏来识别祖先。

奇怪的是,下面的代码将(大多数)姓氏归类为日本血统-JPN。

library(e1071)
library(caret)
test <- read.csv("https://dl.dropboxusercontent.com/u/116353/test.csv", header=T)
test <- test[,-1]
train <- read.csv("https://dl.dropboxusercontent.com/u/116353/train.csv", header=T)
train <- train[,-1]
model  <- naiveBayes(nation~., data=train, laplace=1) 
predictions <- predict(model, newdata=test[,-1], threshold = 0.01)
confusionMatrix(predictions, test$nation)

一些线索:

当我增加训练集的大小时,问题变得更糟,每个人都被归类为 JPN;

我很确定数据没问题,因为我测试了其他分类器(SVM 和 Carvar & Trenkle),它们的表现还不错。 谢谢!

【问题讨论】:

刚刚意识到你的 ngram 有点尴尬。第一个测试示例有两个 ngram 'ato' 和 'ena'。如果你有两个 3 克,它们应该有两个字母重叠。我假设您已将六个字母的单词分成两半?然而,四个字母的字符串用户应该变成 'use' 和 'ser' 非常感谢您的回复。事实上,我在训练和测试集中删除了稀疏术语。否则,我将在训练集中拥有超过 4600 个特征,在测试集中拥有 2800 个特征。我用全套 ngram 进行了测试,准确率没有变化。 通常参数epsthreshold 应该处理这个问题。我进一步调试了朴素贝叶斯的代码(参见下面我的回答),我必须说它看起来很尴尬。当你进行删除时,你应该确保你是一致的!另请参阅下面的答案;) 【参考方案1】:

如果您查看概率,您会发现

> predictions <- predict(model, newdata=test[,-1], threshold = 0.01,type="raw")
> head(predictions)
               EAS          GER           IBR           ITA JAP
[1,] 1.836872e-109 1.535376e-40 2.058015e-228 1.351274e-124   1
[2,] 1.286083e-276 1.133225e-45  0.000000e+00 2.507828e-157   1
[3,] 4.008149e-163 1.257501e-87 3.181309e-136 7.501385e-191   1
[4,]  2.477674e-71 2.008653e-85  0.000000e+00 9.385175e-133   1
[5,] 1.539279e-289 6.367960e-23 1.251711e-114 1.656610e-149   1
[6,]  2.359038e-95 6.367960e-23 3.390903e-110 8.556824e-156   1

这看起来真的很尴尬。

检查学习的概率并不能提供第一眼的真实内幕:

head(t(as.data.frame(model$tables)))
              EAS       GER         IBR         ITA        JAP
acc.1 0.000000000 0.0000000 0.002253944 0.016165245 0.00000000
acc.2 0.000000000 0.0000000 0.047440015 0.126124942 0.00000000
ach.1 0.011730205 0.0154321 0.006010518 0.003816794 0.00931677
ach.2 0.107721635 0.1234544 0.077323244 0.061669116 0.09614740
ada.1 0.002932551 0.0000000 0.006010518 0.002694207 0.03105590
ada.2 0.054100023 0.0000000 0.077323244 0.051841606 0.17360366

那么让我们看看第一个例子的特点

 head(test[,test[1,]==1])
  ato ena
1   1   1

接下来检查该特征在训练数据中出现的次数:

> tail(cumsum(train[,c("ato","ena")]))
Error in `[.data.frame`(train, , c("ato", "ena")) : 
  undefined columns selected

OPPSY(WTF的技术术语)其实是ena

显然,您的测试集中具有训练集中没有的特征。在实施 ML 模型时诉诸最后一个因素元素并不少见。

您应该使用较小的 n-gram 长度,使用 Katz-back 估计值或过滤测试数据以仅出现在训练集中的特征。

你提高门槛的策略还不错。

predictions <- predict(model, newdata=test[,-1], threshold = 0.1)
 confusionMatrix(predictions, test$nation)
          Reference
Prediction EAS GER IBR ITA JAP
       EAS 166  49 127 280  77
       GER  10   7  24  88   5
       IBR  39  11 152 223  29
       ITA  15   3  31 419   4
       JAP  11   4  21  87  62

Overall Statistics

               Accuracy : 0.4146  

【讨论】:

以上是关于朴素贝叶斯 e1071 将每个姓氏分类为相同的祖先的主要内容,如果未能解决你的问题,请参考以下文章

朴素贝叶斯分类器:每个类别的语料库大小必须相同吗?

带有 R 的朴素贝叶斯分类 - 奇怪的结果

朴素贝叶斯分类器仅基于先验概率做出决策

如何交叉验证朴素贝叶斯分类器?

朴素贝叶斯算法的案例实现

查询包 e1071 R 中的朴素贝叶斯算法