编辑:可在以下链接找到可用的正确代码版本: https://github.com/a7x/NaiveBayes-Classifier
我使用了来自openClassroom的数据,并开始在Python中开发一个小型的朴素贝叶斯版本。步骤包括常规的训练和预测。我有一些问题,想知道为什么准确率相当差。
-
在训练过程中,我通过以下公式计算了对数似然:
log( P ( word | spam ) +1 ) /( spamSize + vocabSize .)
我的问题是:为什么在这种情况下要加上
vocabSize
?这是正确的方法吗?使用的代码如下:#这是用于训练的。计算所有概率并将它们存储在一个向量中。最好将它们存储在一个文件中,以便更容易访问 from __future__ import division import sys,os ''' 1. 垃圾邮件和非垃圾邮件已经各占50%。所以它们默认是0.5 2. 现在我们需要分别计算每个单词在垃圾邮件和非垃圾邮件中的概率 2.1 我们可以创建两个字典,基本上是defaultdicts,分别用于垃圾邮件和非垃圾邮件 2.2 当需要计算概率时,我们只需代入值''' from collections import * from math import * spamDict = defaultdict(int) nonspamDict = defaultdict(int) spamFolders = ["spam-train"] nonspamFolders = ["nonspam-train"] path = sys.argv[1] #基础路径 spamVector = open(sys.argv[2],'w') #将所有垃圾邮件值写入此文件 nonspamVector = open(sys.argv[3],'w') #非垃圾邮件值 #遍历垃圾邮件中的所有文件,并迭代添加值 spamSize = 0 nonspamSize = 0 vocabSize = 264821 for f in os.listdir(os.path.join(path,spamFolders[0])): data = open(os.path.join(path,spamFolders[0],f),'r') for line in data: words = line.split(" ") spamSize = spamSize + len(words) for w in words: spamDict[w]+=1 for f in os.listdir(os.path.join(path,nonspamFolders[0])): data = open(os.path.join(path,nonspamFolders[0],f),'r') for line in data: words = line.split(" ") nonspamSize = nonspamSize + len(words) for w in words: nonspamDict[w]+=1 logProbspam = {} logProbnonSpam = {} #这是用于存储对数概率的 for k in spamDict.keys(): #需要计算P(x | y = 1) numerator = spamDict[k] + 1 # 频率 print 'Word',k,' frequency',spamDict[k] denominator = spamSize + vocabSize p = log(numerator/denominator) logProbspam[k] = p for k in nonspamDict.keys(): numerator = nonspamDict[k] + 1 #频率 denominator = nonspamSize + vocabSize p = log(numerator/denominator) logProbnonSpam[k] = p for k in logProbnonSpam.keys(): nonspamVector.write(k+" "+str(logProbnonSpam[k])+"\n") for k in logProbspam.keys(): spamVector.write(k+" "+str(logProbspam[k])+"\n")
-
在预测过程中,我只是取一封邮件,将其拆分为单词,分别为垃圾邮件/非垃圾邮件添加所有概率,并乘以0.5。哪个值更高就是类别标签。代码如下:
http://pastebin.com/8Y6Gm2my (Stackoverflow 又在搞什么鬼 :-/)
编辑:我已经删除了spam = spam + 1的部分。相反,我只是忽略这些单词
问题:我的准确率相当差。如下所示。
垃圾邮件中的文件数为130
../NaiveBayes/spam-test中的垃圾邮件数为53,非垃圾邮件数为77
非垃圾邮件中的文件数为130
../NaiveBayes/nonspam-test/中的垃圾邮件数为6,非垃圾邮件数为124
请告诉我我哪里做错了。我认为低于50%的准确率意味着实现中一定存在一些明显的错误。
回答: