import numpy as np from collections import Counter '''词频进行统计,统计出每个单词出现的个数 输入的是一个一个很长的文章或者句子,应该有断点吧 ,还是在jieba中处理,就在说了 return:1,key-value 2,就是0,1,2这种标记.貌似第一种比较容易实现 ''' '''用counter一次计数文件,这样对原始文件只操作一次。 统计每个单词出现的次数 输入:文件地址 输出:{word1:num1,word2:num2...} hamcnt:正常邮件 spamcnt:垃圾邮件 totanNum:邮件总数 hamNum: 正常邮件数目 spamNum: 垃圾邮件数目 ''' def seperate(filename): hamcnt = Counter() #正常邮件统计字典 spamcnt = Counter()#垃圾邮件统计字典 file = open(filename,encoding='gb18030',errors = 'ignore')#处理不能打开的异常 totalNum=0 #邮件的总数 hamNum=0 #正常邮件数 spamNum=0 #垃圾邮件数 i=0 for line in file: i=i+1 new = line.split(' ') #将单个文本,按照单词分开 totalNum = totalNum +1 if 'ham' in new[0]: #如果是正常邮件,进入hamcnt统计 hamNum =hamNum+1 for word in new[1:]: hamcnt[word] +=1 if 'spam' in new[0]: #如果是垃圾邮件,进入spamcnt统计 spamNum =spamNum +1 for word in new[1:]: spamcnt[word] +=1 print('*********样本的总的行数是%s**********'%i) return hamcnt,spamcnt,totalNum,hamNum,spamNum '''preData是一个句子,或者一封邮件。 return:true,false 是否是垃圾邮件 过程:1,先进行分表,分为两类---调用seperate() 2,进行词频统计,为下面计算概率做准备 3,计算两种情况的概率:p1(spam)p(word1|spam)p(word2|spam)p(word3|spam)... *****修正公式p(word|spam) = (1+wordExistNUm)/(wordsExistNum+wordsNum) 4,比较概率,确定输出结果 ''' def train(filename,preData): hamcnt,spamcnt,totalNum,hamNum,spamNum = seperate(filename) #计算词的总数 wordNumerOfham = 0 for key in hamcnt: wordNumerOfham += hamcnt[key] wordNumerOfspam = 0 for key in spamcnt: wordNumerOfspam +=spamcnt[key] #对要预测的文本进行拆解 newPreData = preData.split(' ') #计算概率p(spam|total),p(ham|total) p1_spam = hamNum/totalNum p1_ham = spamNum/totalNum hamProbablity =1 spamProbability =1 for word in newPreData: try: hamProbablity = hamProbablity*(hamcnt[word]+1)/(wordNumerOfham+len(hamcnt)) except: #文本中没有该单词 hamProbablity = hamProbablity*1/(wordNumerOfham+len(hamcnt)) res1 = hamProbablity*p1_ham for word in newPreData: try: spamProbability = spamProbability*(spamcnt[word]+1)/(wordNumerOfspam+len(spamcnt)) except: spamProbability = spamProbability*(1)/(wordNumerOfspam+len(spamcnt)) res2 = spamProbability*p1_spam if res1 == res2: print('res1',res1,'res2',res2) if res1>res2: print('不是垃圾邮件!','正常文件:',res1,'垃圾邮件',res2) return 0 else: print('是垃圾邮件','正常文件:',res1,'垃圾邮件',res2) return 1 '''外部调用过程: 1,读取数据 2,训练,得到结果 ''' filename = 'D:\\学习\\计算机培训\\机器学习部分\\贝叶斯分类器\\smsspamcollection\\SMSSpamCollection.txt' preData = 'You have won ?1,000 cash or a ?2,000 prize! To claim, call09050000327' res = train(filename,preData)
朴素贝叶斯的实现理论:http://blog.csdn.net/gane_cheng/article/details/53219332 (这个链接里面也有数据集)
说明:统计的文本函数式counter,对统计英文文本速度还是很快的。