目录
一:朴素贝叶斯
一:什么是朴素贝叶斯
在主观条件的基础上,不了解客观的事实情况下可以先估计一个数值,然后根据结果不断进行修正,基于条件概率这个概念发展而来,因此要理解朴素贝叶斯的思想首先需要知道什么是条件概率
1.1条件概率
假设抛硬币三次观察正反两面,已知出现反面一次为(A),在未知中想要知道三次同时出现正面/反面为(B)。因此我们知道事件A发生的情况下那么事件B的概率是多少。就是条件概率P(B|A)
2.1贝叶斯公式
在事件A的条件下事件B的概率P(B|A)=P(AB)/A。那么在B的条件下A的概率是P(A|B)=P(BA)/B。总合上面两种P(AB)=P(B|A)P(A)/P(B)
2.2直观的理解公示
如图,蓝色设为A,绿色设为B,中间的交集设为
从空间和约束上看,原样本空间S大小为1,其中以B集合例子为说明:
在P(B)在样本S上面增加约束B得到子空间P(B)=B/S。而P(A|B) 表示以P(B)为全集的基础上增加约束A之后得到的子空间(在B的条件下求A的概率)P(A|B)=P(BA)/B,P(A|B)P(B)是在样本空间S上先后增加两个约束条件B和A后得到的最终子空间在图像中是属于=P(A|B)P(B),公式转换一下就是=(P(BA)/B)*P(B);
以A集合为例子与上述过程一致;A和B的先后次序对整个过程不产生影响,所以
P(A|B)P(B)=P(B|A)P(A)
二:朴素贝叶斯的实现方式
2.1伯努利朴素贝叶斯
是假定样本特征的条件概率分布服从二项分布。加入我们进行抛硬币的实验落下的两种结果:正面或者是反面。这是就是二项分布(0-1)
2.2高斯朴素贝叶斯
假定样本特征符合高斯分布的算法。高斯分布也成为正态分布,是数学中常见的一种分布形态。如果随机变量X俯冲一个数学的期望u,方差是的平方的正太分布,可记为N(u,的平方),那么改了密度曲线是一个典型的钟形曲线;日常比较常见的如身高、体重、学习成绩或者实验中的随机误差
2.3多项式朴素贝叶斯
假定样本特征符合多项式常用的算法。二项式典型的是抛硬币,硬币朝向正面的是P,重新抛n次,k次为正面的概率即是一个二项式分布概率。百二项公式推广到多种状态,就得到多项式。典型的例子就是骰子
二:one-hot热编码:
一:为什么需要热编码
大部分算法是基于向量空间中的度量来进行计算的,为了使非偏序关系的变量取值不具有偏序性,并且到圆点是等距的。使用one-hot编码,将离散特征的取值扩展到了欧式空间,离散特征的某个取值就对应欧式空间的某个点。将离散型特征使用one-hot编码,会让特征之间的距离计算更加合理。离散特征进行one-hot编码后,编码后的特征,其实每一维度的特征都可以看做是连续的特征。就可以跟对连续型特征的归一化方法一样,对每一维特征进行归一化。比如归一化到[-1,1]或归一化到均值为0,方差为1。
二:为什么特征向量要映射到欧式空间?
可以通过one-hot编码映射到欧式空间,是因为,在回归,分类,聚类等机器学习算法中,特征之间距离的计算或相似度的计算是非常重要的,而我们常用的距离或相似度的计算都是在欧式空间的相似度计算,计算余弦相似性,基于的就是欧式空间。
三:代码实现
一:读取文件内容
doclist:存放邮件样本,里面的文字已经切割过讲一句话为一个列表,列表中是一个个词作为词料库;classlist:标签,1为来及邮件,0是正常的邮件
doclist = []
classlist = []
for i in range(1,样本的数量):
lj_email = re.split(r'\W+', open(垃圾邮件的路径,'r',encoding='gbk').read())
wordlist = [tok.lower() for tok in lj_email if len(lj_email) > 2]
doclist.append(wordlist)
classlist.append(1) #1表示垃圾邮件
nor_email=re.split(r'\W+', open(正常邮件的路径,'r',encoding='gbk').read())
wordlist = [tok.lower() for tok in nor_email if len(nor_email) > 2]
doclist.append(wordlist)
classlist.append(0) #0表示正常邮件
二:准备数据
将词料库中去重,并且划分测试集和训练集
def creatVocablist(doclist):
vocabSet = set([])
for document in doclist:
vocabSet = vocabSet|set(document)
return list(vocabSet)
vocablist = creatVocablist(doclist)
trainSet = list(range(50))
testSet = []
for i in range(10):
randIndex = int(random.uniform(0,len(trainSet)))
testSet.append(trainSet[randIndex])
del (trainSet[randIndex])
三:训练-朴素贝叶斯
训练数据之前,需要将文本转化为one-hot编码,每格样本的one-hot编码对应标签保存,做贝叶斯的计算之前需要统计词频,每个词在垃圾邮件的出现概率和在正常邮件出现的概率。
p1:垃圾邮件的概率
p1vec:训练中垃圾邮件词频的出现概率
p0vec:训练中正常邮件词频的出现概率
def setOfWord2Vec(vocablist,inputSet):###one-hot编码
returnVec = [0]*len(vocablist)
for word in inputSet:
if word in vocablist:
returnVec[vocablist.index(word)] = 1
return returnVec
def trainNB(trainMat,trainClass):
numTrainDocs = len(trainMat)
numWords = len(trainMat[0])
p1 = sum(trainClass)/float(numTrainDocs)
p0Num = np.ones((numWords)) #做了一个平滑处理
p1Num = np.ones((numWords))
p0Denom = #标签个数
p1Denom = #标签个数
for i in range(numTrainDocs):
if trainClass[i] == 1: #垃圾邮件
p1Num += trainMat[i]
p1Denom += sum(trainMat[i])
else:
p0Num += trainMat[i]
p0Denom += sum(trainMat[i])
p1Vec = np.log(p1Num/p1Denom)
p0Vec = np.log(p0Num/p0Denom)
return p0Vec,p1Vec,p1
for docIndex in trainSet:
trainMat.append(setOfWord2Vec(vocablist,doclist[docIndex]))
trainClass.append(classlist[docIndex])
p0Vec,p1Vec,p1 = trainNB(np.array(trainMat),np.array(trainClass))
errorCount = 0
四:测试预测模型:
假设P(A|S)=P(A)*P(S|A)/P(S)所有邮件拿到正常邮件的概率,P(B|S)=P(B)*P(S|B)/P(S)所有邮件拿到垃圾邮件的概率,由于属于是二项式,最后做比较的时候可以忽略P(S),因此P(A|S)=P(A)*P(S|A),P(B|S)=P(B)*P(S|B),主要是将对象判定是垃圾还是正常邮件,直接由概率的大小判定,但是出线数值会相近的情况拉开之间的差距就用上了对数LOGP(A)+LOG(P(S|A)),最后预测和真实对比
def setOfWord2Vec(vocablist,inputSet):
returnVec = [0]*len(vocablist)
for word in inputSet:
if word in vocablist:
returnVec[vocablist.index(word)] = 1
return returnVec
def classifyNB(wordVec,p0Vec,p1Vec,p1_class): ###wordVec使用one-hot编码0和1表示出现的词是1
p1 = np.log(p1_class) + sum(wordVec*p1Vec)###垃圾邮件概率+在垃圾邮件出现的样本的词频概率
p0 = np.log(1.0 - p1_class) + sum(wordVec*p0Vec)###正常邮件概率+正常邮件的出现样本词频概率
if p0>p1:
return 0
else:
return 1
for docIndex in testSet:
wordVec = setOfWord2Vec(vocablist,doclist[docIndex])
if classifyNB(np.array(wordVec),p0Vec,p1Vec,p1) != classlist[docIndex]:
errorCount+=1
one-hot编码:https://blog.csdn.net/ZYC88888/article/details/103819604
对于one-hot编码没很深入的研究,参考了一个写的比较完整的博主文章也收获不少