gpt4 book ai didi

python - 朴素贝叶斯的实现——准确性问题

转载 作者:太空宇宙 更新时间:2023-11-03 15:25:02 24 4
gpt4 key购买 nike

编辑:可以在以下位置找到有效代码的正确版本: https://github.com/a7x/NaiveBayes-Classifier

我使用了来自 openClassroom 的数据并开始使用 Python 开发一个小版本的朴素贝叶斯。步骤是通常的训练,然后是预测。我有几个问题,想知道为什么准确性很差。

  1. 为了训练,我通过以下公式计算对数似然:

    log( P ( word | spam ) +1 ) /( spamSize + vocabSize .)

    我的问题是:为什么我们要在这种情况下添加 vocabSize :( 这是正确的做法吗?使用的代码如下:

    #This is for training.     Calculate all probabilities and store them in a vector. Better to store it in a file  for easier access 
    from __future__ import division
    import sys,os
    '''
    1. The spam and non-spam is already 50% . So they by default are 0.5
    2. Now we need to calculate probability of each word , in spam and non-spam separately
    2.1 we can make two dictionaries, defaultdicts basically, for spam and non-spam
    2.2 When time comes to calculate probabilities, we just need to substitute values
    '''
    from collections import *
    from math import *

    spamDict = defaultdict(int)
    nonspamDict = defaultdict(int)
    spamFolders = ["spam-train"]
    nonspamFolders = ["nonspam-train"]
    path = sys.argv[1] #Base path
    spamVector = open(sys.argv[2],'w') #WRite all spam values into this
    nonspamVector = open(sys.argv[3],'w') #Non-spam values

    #Go through all files in spam and iteratively add values
    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 = {} #This is to store the log probabilities
    for k in spamDict.keys():
    #Need to calculate P(x | y = 1)

    numerator = spamDict[k] + 1 # Frequency
    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 #frequency
    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")
  2. 为了预测,我只是拿了一封邮件,把它分成单词,加上所有的概率,分别为垃圾邮件/非垃圾邮件,并将它们乘以 0.5。以较高者为准。代码如下:

    http://pastebin.com/8Y6Gm2my (Stackoverflow 出于某种原因又开始玩游戏了:-/)

编辑:我删除了 spam = spam + 1 东西。相反,我只是忽略了那些话

问题:我的准确性很差。如下所述。

    No of files in spam is 130
No. of spam in ../NaiveBayes/spam-test is 53 no. of non-spam 77
No of files in non-spam is 130
No. of spam in ../NaiveBayes/nonspam-test/ is 6 no. of non-spam 124

请告诉我哪里出错了。我认为准确率低于 50% 意味着在实现过程中肯定存在一些明显的错误。

最佳答案

在你的程序中有多个错误和错误的假设 - 在它的两个部分。这里有几个。

  1. 您将拥有相同数量的垃圾邮件和非垃圾邮件这一事实硬编码到您的程序中。我建议不要硬编码这个假设。这不是绝对必要的,但在更一般的情况下,您需要将其删除。
  2. 你在你的程序中编码了一些你认为是词汇量的数字。我不建议这样做,因为这个数字可能会随着训练集的任何修改而改变。而且,实际上是不正确的。我建议在学习期间计算它。
  3. 这可能不是一个错误,但你似乎掌握了训练集中所有单词的词汇表。这可能不是最理想的;实际上,您引用的页面建议只考虑所有电子邮件中的前 2500 个单词。然而,这对于获得正确的结果并不是必不可少的 - 即使没有这种过滤,我的实现也只会得到几封未分类的电子邮件。
  4. 您错误地只考虑了在垃圾邮件或非垃圾邮件中观察到的词。在另一个子集中找到它们的对数概率不是您添加的 1,而是 log(1/(spamSize+vocabSize))log( 1/(nonspamSize+vocabSize)) 取决于它的组。这实际上非常重要 - 您需要将此概率与您的数据一起存储,以使程序正常运行。
  5. 您不会忽略在训练集中从未观察到的单词。实际上,这些可能有不同的处理方式,但您应该考虑到它们。
  6. 由于预测函数中的缩进不正确,您预测使用的不是整条消息,而是消息的第一行。只是一个编程错误。

更新。您已经修复了 6 个。此外,在您使用此数据集时,1 个不是严格必须修复的,3 个也不是必需的。
您的修改没有正确修复 4 或 5。首先,如果该词从未在某个集合中被观察到,则该消息出现在其中的概率应该会降低。忽略这个词不是一个好主意,你需要把它当作一个极不可能的词来考虑。
其次,您当前的代码是不对称的,因为垃圾邮件中不存在该词会取消对非垃圾邮件的检查(但不是相反)。如果您不需要在异常处理程序中执行任何操作,请使用 pass,而不是 continue,因为后者会立即转到下一个 for w in words: 迭代。
问题 2 也仍然存在——您使用的词汇量与真实词汇量不符。它必须是在训练集中观察到的不同单词的数量,而不是所有消息中的单词总数。

关于python - 朴素贝叶斯的实现——准确性问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8680243/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com