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
- 非常不错的拉普拉斯平滑讲解
- 《机器学习实战》