1.贝叶斯( Bayes)分类法
1.1 贝叶斯分类法原理
贝叶斯分类算法是一种基于概率的常用分类算法,该算法基于贝叶斯定理和特征条件独立假设原则。对该算法两大基础解释如下:
- 1.特征条件独立假设:即各个条件的出现不会相互影响,例如就不能把这是个男人,这个人有胡子作为两个特征。因为这两个特征本身会相互影响。
- 2.贝叶斯定理:
该定理的核心思想可以总结为:“A是一个亚洲人,经过统计发现他亚洲人是黄种人的几率最大。读入结果,B是一个黄种人,则他大概率是一个亚洲人。”
该算法学习和预测的过程可以总结为:学习过程即求后验概率的过程,预测过程为根据特征求其先验概率。
以四个特征两种结果的情况举例,例如四个特征分别为(W,X,Y,Z)。两种结果为A和B。假如四个特征每个分别有两种情况,则可能特征分别为:
- W:W1、W2
- X:X1、X2
- Y:Y1、Y2
- Z:Z1、Z2
那么此时得到的统计数据(输入集)就是在(W1/2,X1/2,Y1/2,Z1/2)时结果为A/B。我们要做的第一步就是训练,也就是要求:
然后,当读入一个数据,例如则计算过程如下:
然后对比和,选一个大的认为预测结果为A或者B
1.2 贝叶斯分类法例题
1.2.1 使用朴素贝叶斯进行垃圾邮件分类
这里给出的数据集是两组邮件txt文件,ham文件夹下为正常邮件,spam文件夹下为垃圾邮件,文件名为1.txt-25.txt。
#读取文件并返回列表分词列表 import re def readFileToList(filename): with open(filename) as f: bigstring = f.read() wordlist = re.split(r"\W+",bigstring) return [word.lower() for word in wordlist if len(word)>2 ] #print(readFileToList("attach/1.3/email/ham/1.txt"))
import random def getTrainDataSet(): #用40个当作训练数据集 dataSet = [] wordSet = [] classifySet = [] for i in range(1,21): hamFile = "attach/1.3/email/ham/"+str(i)+".txt" spamFile = "attach/1.3/email/spam/"+str(i)+".txt" wordlist = readFileToList(hamFile) dataSet.append(wordlist)#保存正常邮件数据集 wordSet.extend(wordlist)#将单词保存至单词集合中方便后续计算 classifySet.append(False)#存储数据集定义为非垃圾邮件 wordlist = readFileToList(spamFile) dataSet.append(wordlist)#保存垃圾邮件数据集 wordSet.extend(wordlist)#将单词保存至单词集合中方便后续计算 classifySet.append(True)#存储数据集定义为垃圾邮件 return dataSet,classifySet,wordSet ''' trainSet = list(range(50)) testSet =[] for i in range(10): randomIndex = random.randint(0,len(trainSet)) #print(randomIndex) testSet.append(trainSet[randomIndex])#假如测试集合 del(trainSet[randomIndex])#假如训练集合 return dataSet,classifySet,wordSet,trainSet,testSet ''' trainSet,classifySet,wordSet=spamTest() #print(trainSet,testSet)
#划分好了训练集合和测试集合后现在就是要根据公式求概率 import math def calcNum(wordNeededCalc,wordlist):#输入一个元素和一个集合,计算该元素在集合中出现的次数 num = 0.0 for word in wordlist: if word==wordNeededCalc: num +=1 #Prob = num/len(wordlist) return num #print(calcProb('you',wordSet)) def classify(emailwordlist,trainSet,classifySet,wordSet): dataTypeList = [] #所有分类集合 for dataType in classifySet: if dataType not in dataTypeList: dataTypeList.append(dataType) #计算概率P(A)、P(B).. dataTypeProbList=[] for i in range(len(dataTypeList)): num=0.0 #记录每个类型数据数量 for classify in classifySet: if classify==dataTypeList[i]: num+=1 dataTypeProbList.append(num/len(classifySet)) #计算联合分布概率 max_prob=0 res=0 for i in range(len(dataTypeList)): p_up=1 p_down=1 for word in emailwordlist: num=0.0 all_word_num=0.0 if word in wordSet: #先判断这个单词在不在训练数据集的词向量列表里 for index,value in enumerate(trainSet): if classifySet[index]==dataTypeList[i]: num+=calcNum(word,value) all_word_num+=len(value) if (num!=0): p_up*=(num/all_word_num) p_down*=(calcNum(word,wordSet)/len(wordSet)) if p_up!=1: p = p_up/p_down else: p=0 if p>max_prob: max_prob=p res = dataTypeList[i] #print(p) return res #print(dataTypeProbList) #for word in emailwordlist: # for index in trainSet: # calcProb(word,) #res=classify(trainSet[1],trainSet,classifySet,wordSet) #print(res)
for i in range(21,26): testfilename1 = "attach/1.3/email/ham/"+str(i)+".txt" testWordlist1 = readFileToList(testfilename1) testfilename2 = "attach/1.3/email/spam/"+str(i)+".txt" testWordlist2 = readFileToList(testfilename2) print(classify(testWordlist1,trainSet,classifySet,wordSet),testfilename1) print(classify(testWordlist2,trainSet,classifySet,wordSet),testfilename2) #正确率百分之九十左右,算法整的有点问题,有时间改
False attach/1.3/email/ham/21.txt True attach/1.3/email/spam/21.txt False attach/1.3/email/ham/22.txt True attach/1.3/email/spam/22.txt False attach/1.3/email/ham/23.txt True attach/1.3/email/spam/23.txt False attach/1.3/email/ham/24.txt True attach/1.3/email/spam/24.txt False attach/1.3/email/ham/25.txt False attach/1.3/email/spam/25.txt
参考:
- 贝叶斯算法分析:https://www.jianshu.com/p/5953923f43f0
- 贝叶斯算法分析:https://www.cnblogs.com/lliuye/p/9178090.html
- 非常不错的拉普拉斯平滑讲解
- 《机器学习实战》