秒懂机器学习---朴素贝叶斯进行垃圾邮件分类实战

曾经终败给现在 2022-01-06 23:09 334阅读 0赞

秒懂机器学习—-朴素贝叶斯进行垃圾邮件分类实战

一、总结

一句话总结:

没必要一次学很多个算法,不然,其实真的一个也不懂,要一个一个搞懂了再往下学
如何讲解这个问题:实例+人话:朴素贝叶斯( P(结果|关键词1,关键词2…) = P(关键词1,关键词2…|结果)*P(结果)/P(关键词1,关键词2…))
怎么继续学习这个算法:写一个既简单数据量极少的程序出来,由浅入深

1、停词表是什么?

会自动过滤掉某些字或词:比如标点符号,比如虚词

停用词是指在信息检索中,为节省存储空间和提高搜索效率,在处理自然语言数据(或文本)之前或之后会自动过滤掉某些字或词,这些字或词即被称为Stop Words(停用词)。这些停用词都是人工输入、非自动化生成的,生成后的停用词会形成一个停用词表。但是,并没有一个明确的停用词表能够适用于所有的工具。甚至有一些工具是明确地避免使用停用词来支持短语搜索的。

2、python中列表应用实例?

stopList=[]:定义
stopList.append(line[:len(line)-1]):追加
  1. #获得停用词表
  2. def getStopWords(self):
  3. stopList=[]
  4. for line in open("../data/China_stop_word.txt"):
  5. stopList.append(line[:len(line)-1])
  6. return stopList;

3、python中for语句循环的语法是什么?

for in:for in ::for line in open(“../data/China_stop_word.txt”):

4、python的jieba包是干嘛的?

分词模块:词云技术遍地都是,分词模块除了jieba也有很多

5、分词模块包一般有哪些分词模式(比如python的jieba包分’我想和女朋友一起去北京天安门闲逛。。’)?

精确模式:jieba.cut(s):词只分一次:我,想,和,女朋友,一起,去,北京,天安门,闲逛,。,。
全模式:jieba.cut(s,cut_all = True):尽量将所有的词拿出来:我,想,和,女朋友,朋友,一起,去,北京,天安,天安门,闲逛,,,
搜索引擎模式:jieba.cut_for_search(s):我,想,和,朋友,女朋友,一起,去,北京,天安,天安门,闲逛,。,。

6、如何过滤掉非中文字符?

rule=re.compile(r”[^\u4e00-\u9fa5]“)

7、P(x’|c)=P((sunny,cool,high,strong)|yes)这句话是什么意思?

给定了结果是yes的情况,sunny,cool,high,strong分别占各自总数的多少

8、朴素贝叶斯( P(结果|关键词1,关键词2…) = P(关键词1,关键词2…|结果)*P(结果)/P(关键词1,关键词2…))公式怎么解释?

P(结果|关键词1,关键词2…):表示根据 关键词1,关键词2… 判断邮件在什么分类:比如一封邮件拥有这些关键词,你要判断它是不是垃圾邮件
P(关键词1,关键词2…|结果):表示 不同分类下 这些关键词(关键词1,关键词2…)出现的概率:比如关键词1在垃圾邮件中出现的概率为0.7
P(结果):不同分类在总结果中的概率:比如训练数据的垃圾邮件占总邮件的0.5

9、用朴素贝叶斯( P(结果|关键词1,关键词2) = P(关键词1,关键词2|结果)*P(结果)/P(关键词1,关键词2))做邮件分类的原理是什么?

搞懂这句话:P(结果|关键词1,关键词2) = P(关键词1,关键词2|结果)*P(结果)/P(关键词1,关键词2)
选最高频15个词:需要测试的邮件选最高频的15个词就够了

10、朴素贝叶斯的这个概率P(关键词1,关键词2…|结果)的各个小概率之间是相加还是相乘?

相乘:肯定是相乘啊,因为这个条件是所有关键词都要包含,所以肯定是乘

11、现在我要求新邮件是否为垃圾邮件,本质是求P(结果|关键词1,关键词2…)、P(关键词1,关键词2…|结果)中的哪一个?

P(结果|关键词1,关键词2…)

12、用朴素贝叶斯( P(结果|关键词1,关键词2) = P(关键词1,关键词2|结果)*P(结果)/P(关键词1,关键词2))做邮件分类的步骤分类?

获得正常邮件中的词频 和 获得垃圾邮件中的词频:P(关键词1,关键词2|结果)
测试邮件:通过计算每个文件中p(s|w)来得到对分类影响最大的15个词:P(关键词1,关键词2|结果)*P(结果)
比较结果概率,选择结果:计算不同结果对应的 P(关键词1,关键词2|结果)*P(结果)的大小

二、内容在总结中

1、相关知识

2、代码

spamEmail.py

  1. #encoding=utf-8
  2. '''
  3. Created on 2018年3月11日
  4. @author: Fan Renyi
  5. '''
  6. import jieba;
  7. import os;
  8. class spamEmailBayes:
  9. #获得停用词表
  10. def getStopWords(self):
  11. stopList=[]
  12. for line in open("../data/China_stop_word.txt"):
  13. stopList.append(line[:len(line)-1])
  14. return stopList;
  15. #获得词典
  16. def get_word_list(self,content,wordsList,stopList):
  17. #分词结果放入res_list
  18. res_list = list(jieba.cut(content))
  19. for i in res_list:
  20. if i not in stopList and i.strip()!='' and i!=None:
  21. if i not in wordsList:
  22. wordsList.append(i)
  23. #若列表中的词已在词典中,则加1,否则添加进去
  24. def addToDict(self,wordsList,wordsDict):
  25. for item in wordsList:
  26. if item in wordsDict.keys():
  27. wordsDict[item]+=1
  28. else:
  29. wordsDict.setdefault(item,1)
  30. def get_File_List(self,filePath):
  31. filenames=os.listdir(filePath)
  32. return filenames
  33. #通过计算每个文件中p(s|w)来得到对分类影响最大的15个词
  34. def getTestWords(self,testDict,spamDict,normDict,normFilelen,spamFilelen):
  35. wordProbList={}
  36. for word,num in testDict.items():
  37. if word in spamDict.keys() and word in normDict.keys():
  38. #该文件中包含词个数
  39. pw_s=spamDict[word]/spamFilelen
  40. pw_n=normDict[word]/normFilelen
  41. ps_w=pw_s/(pw_s+pw_n)
  42. wordProbList.setdefault(word,ps_w)
  43. if word in spamDict.keys() and word not in normDict.keys():
  44. pw_s=spamDict[word]/spamFilelen
  45. pw_n=0.01
  46. ps_w=pw_s/(pw_s+pw_n)
  47. wordProbList.setdefault(word,ps_w)
  48. if word not in spamDict.keys() and word in normDict.keys():
  49. pw_s=0.01
  50. pw_n=normDict[word]/normFilelen
  51. ps_w=pw_s/(pw_s+pw_n)
  52. wordProbList.setdefault(word,ps_w)
  53. if word not in spamDict.keys() and word not in normDict.keys():
  54. #若该词不在脏词词典中,概率设为0.4
  55. wordProbList.setdefault(word,0.47)
  56. sorted(wordProbList.items(),key=lambda d:d[1],reverse=True)[0:15]
  57. return (wordProbList)
  58. #计算贝叶斯概率
  59. def calBayes(self,wordList,spamdict,normdict):
  60. ps_w=1
  61. ps_n=1
  62. for word,prob in wordList.items() :
  63. print(word+"/"+str(prob))
  64. ps_w*=(prob)
  65. ps_n*=(1-prob)
  66. p=ps_w/(ps_w+ps_n)
  67. # print(str(ps_w)+""+str(ps_n))
  68. return p
  69. #计算预测结果正确率
  70. def calAccuracy(self,testResult):
  71. rightCount=0
  72. errorCount=0
  73. for name ,catagory in testResult.items():
  74. if (int(name)<1000 and catagory==0) or(int(name)>1000 and catagory==1):
  75. rightCount+=1
  76. else:
  77. errorCount+=1
  78. return rightCount/(rightCount+errorCount)

main.py

  1. #encoding=utf-8
  2. '''
  3. Created on 2018年3月11日
  4. @author: Fan Renyi
  5. '''
  6. from spam.spamEmail import spamEmailBayes
  7. import re
  8. import time
  9. #及时函数开始
  10. begin_time=time.time()
  11. #spam类对象
  12. spam=spamEmailBayes()
  13. #保存词频的词典
  14. spamDict={}
  15. normDict={}
  16. testDict={}
  17. #保存每封邮件中出现的词
  18. wordsList=[]
  19. wordsDict={}
  20. #保存预测结果,key为文件名,值为预测类别
  21. testResult={}
  22. #分别获得正常邮件、垃圾邮件及测试文件名称列表
  23. normFileList=spam.get_File_List("./../data/normal")
  24. spamFileList=spam.get_File_List("./../data/spam")
  25. testFileList=spam.get_File_List("./../data/test")
  26. #获取训练集中正常邮件与垃圾邮件的数量
  27. normFilelen=len(normFileList)
  28. spamFilelen=len(spamFileList)
  29. #获得停用词表,用于对停用词过滤
  30. stopList=spam.getStopWords()
  31. #获得正常邮件中的词频
  32. for fileName in normFileList:
  33. wordsList.clear()
  34. for line in open("./../data/normal/"+fileName):
  35. #过滤掉非中文字符
  36. rule=re.compile(r"[^\u4e00-\u9fa5]")
  37. line=rule.sub("",line)
  38. #将每封邮件出现的词保存在wordsList中
  39. spam.get_word_list(line,wordsList,stopList)
  40. #统计每个词在所有邮件中出现的次数
  41. spam.addToDict(wordsList, wordsDict)
  42. normDict=wordsDict.copy()
  43. #获得垃圾邮件中的词频
  44. wordsDict.clear()
  45. for fileName in spamFileList:
  46. wordsList.clear()
  47. for line in open("./../data/spam/"+fileName):
  48. rule=re.compile(r"[^\u4e00-\u9fa5]")
  49. line=rule.sub("",line)
  50. spam.get_word_list(line,wordsList,stopList)
  51. spam.addToDict(wordsList, wordsDict)
  52. spamDict=wordsDict.copy()
  53. # 测试邮件
  54. for fileName in testFileList:
  55. testDict.clear( )
  56. wordsDict.clear()
  57. wordsList.clear()
  58. for line in open("./../data/test/"+fileName):
  59. rule=re.compile(r"[^\u4e00-\u9fa5]")
  60. line=rule.sub("",line)
  61. spam.get_word_list(line,wordsList,stopList)
  62. spam.addToDict(wordsList, wordsDict)
  63. testDict=wordsDict.copy()
  64. #通过计算每个文件中p(s|w)来得到对分类影响最大的15个词
  65. wordProbList=spam.getTestWords(testDict, spamDict,normDict,normFilelen,spamFilelen)
  66. #对每封邮件得到的15个词计算贝叶斯概率
  67. p=spam.calBayes(wordProbList, spamDict, normDict)
  68. if(p>0.9):
  69. testResult.setdefault(fileName,1)
  70. else:
  71. testResult.setdefault(fileName,0)
  72. # 将结果写在answer/ans.txt 里面
  73. f2=open('../data/answer/ans.txt',encoding='utf-8',mode='w')
  74. #计算分类准确率(测试集中文件名低于1000的为正常邮件)
  75. testAccuracy=spam.calAccuracy(testResult)
  76. for i,ic in testResult.items():
  77. print(i+"/"+str(ic))
  78. f2.write(i+"/"+str(ic)+'\n')
  79. print(testAccuracy)
  80. f2.write(str(testAccuracy)+'\n')
  81. end_time=time.time()
  82. print('程序总共运行了:',(end_time-begin_time),'(s)')

转载于:https://www.cnblogs.com/Renyi-Fan/p/10982891.html

发表评论

表情:
评论列表 (有 0 条评论,334人围观)

还没有评论,来说两句吧...

相关阅读

    相关 机器学习-朴素

    朴素贝叶斯介绍 朴素贝叶斯法是基于贝叶斯定理与特征条件独立假设的分类方法。之所以叫朴素,是因为朴素贝叶斯法对条件概率分布作了条件独立性的假设。朴素贝叶斯法是典型的生成学习