目录
一 基本概念
1 简介
2 朴素贝叶斯的优缺点
2 先验概率和后验概率
3 条件概率与全概率公式
4 贝叶斯推断
二 贝叶斯分类器的简单应用
1 数据说明
2 进行分类
三 朴素贝叶斯过滤垃圾邮件
1 流程说明
2 构建词向量
3 词向量计算概率
4 朴素贝叶斯分类函数
5 使用朴素贝叶斯进行交叉验证
四 总结

一、基本概念

1.简介

最为广泛的两种分类模型是决策树模型(Decision Tree Model)和朴素贝叶斯模型(Naive Bayesian Model,NBM)。和决策树模型相比,朴素贝叶斯分类器(Naive Bayes Classifier 或 NBC)发源于古典数学理论,有着坚实的数学基础,以及稳定的分类效率。同时,NBC模型所需估计的参数很少,对缺失数据不太敏感,算法也比较简单。理论上,NBC模型与其他分类方法相比具有最小的误差率。但是实际上并非总是如此,这是因为NBC模型假设属性之间相互独立,这个假设在实际应用中往往是不成立的,这给NBC模型的正确分类带来了一定影响。

2.贝叶斯的优缺点

朴素贝叶斯的主要优点有:

1)朴素贝叶斯模型发源于古典数学理论,有稳定的分类效率。

2)对小规模的数据表现很好,能个处理多分类任务,适合增量式训练,尤其是数据量超出内存时,我们可以一批批的去增量训练。

3)对缺失数据不太敏感,算法也比较简单,常用于文本分类。

朴素贝叶斯的主要缺点有:

1) 理论上,朴素贝叶斯模型与其他分类方法相比具有最小的误差率。但是实际上并非总是如此,这是因为朴素贝叶斯模型假设属性之间相互独立,这个假设在实际应用中往往是不成立的,在属性个数比较多或者属性之间相关性较大时,分类效果不好。而在属性相关性较小时,朴素贝叶斯性能最为良好。对于这一点,有半朴素贝叶斯之类的算法通过考虑部分关联性适度改进。

2)需要知道先验概率,且先验概率很多时候取决于假设,假设的模型可以有很多种,因此在某些时候会由于假设的先验模型的原因导致预测效果不佳。

3)由于我们是通过先验和数据来决定后验的概率从而决定分类,所以分类决策存在一定的错误率。

4)对输入数据的表达形式很敏感。

3.先验概率和后验概率

P(cj)代表还没有训练模型之前,根据历史数据/经验估算cj 拥有的初始概率。P(cj)常被称为cj的先验概率(prior probability) , 它反映了cj的概率分布,该分布独立于样本。

通常可以用样例中属于cj的样例数|cj|比上总样例数|D|来

近似,即:

4.条件概率与全概率公式

已知两个独立事件AB,事件B发生的前提下,事件A发生的概率可

以表示为P(A|B),即上图中橙色部分占红色部分的比例,即:

5. 贝叶斯推断

根据条件概率和全概率公式,可以得到贝叶斯公式如下:

P(A) 称为先验概率(prior probability),即在B事件发生之前,我们对A事件概率的一个判断;
P ( A ∣ B ) 称为后验概率(posterior probability),即在B事件发生之后,我们对A事件概率的重新评估;
P ( B ∣ A ) /P(B) 称为可能性函数(Likely hood),这是一个调整因子,使得预估概率更接近真实概率。

所以条件概率可以理解为:后验概率 = 先验概率 × 调整因子
如果"可能性函数">1,意味着"先验概率"被增强,事件A的发生的可能性变大;
如果"可能性函数"=1,意味着B事件无助于判断事件A的可能性;
如果"可能性函数"<1,意味着"先验概率"被削弱,事件A的可能性变小。

二、贝叶斯分类器的简单应用

朴素贝叶斯分类器的训练器的训练过程就是基于训练集D估计类

先验概率P(c),并为每个属性估计条件概率 P(Xi|c) 。

令Dc表示训练集D中第c类样本组合的集合,则类先验概率:

1 数据说明

下表收集了15天内某网球爱好者每天是否打网球的数据,其中从左往右每列的属性分别为:天数、天气情况、温度、湿度、风力、当天是否打网球。

2 进行分类

现在假设有一个样例 x = {Sunny, Hot, High, Weak},那该种情况下应该去打网球还是不去呢,如何对其进行分类呢?
首先分别统计对15天中去打排球和没去打排球的天数以及各自情况下不同属性分类的的个数,如下图:

此时,根据贝叶斯公式,分别求解去打网球和不去打网球的概率,求解公式如下:

其中,x={Sunny, Hot, High, Weak},由于分母相同,因此只需计算分子的结果来进行比较即可,计算结果如下图所示:

三 、朴素贝叶斯过滤垃圾邮件

1.流程说明:

1. 数据准备:收集数据与读取

2. 数据预处理:处理数据

3. 训练集与测试集:将先验数据按一定比例进行拆分。

4. 提取数据特征,将文本解析为词向量 。

5. 训练模型:建立模型,用训练数据训练模型。即根据训练样本集,计算词项出现的概率P(xi|y),后得到各类下词汇出现概率的向量 。

6. 测试模型:用测试数据集评估模型预测的正确率。

混淆矩阵

准确率、精确率、召回率、F值

7. 预测一封新邮件的类别。

2、构建向量

我们把文本看成单词向量或者词条向量,也就是说将句子转换为向量。考虑出现在所有文档中的所有单词,再决定将哪些词纳入词汇表或者说所要的词汇集合,然后必须要将每一篇文档转换为词汇表上的向量。

代码:

# 创建实验样本
def loadDataSet():postingList = [['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],['stop', 'posting', 'stupid', 'worthless', 'garbage'],['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]classVec = [0, 1, 0, 1, 0, 1]return postingList,classVec
"""
函数说明:将实验样本中的词条进行合并(剔除重复项)
Parameters:dataset:样本数据集列表
Rerurns:vocabSet:包含所有文档中出现的不重复词的列表
"""
def createVocabList(dataset):vocabSet = set([])for document in dataset:# 取并集vocabSet = vocabSet | set(document)return list(vocabSet)
"""
函数说明:将样本列表(inputSet)向量化(0或1)
Parameters:vocabList:词集列表(createVocabList()函数返回后的列表)inputSet:待向量化的词条列表
Rerurns:returnVec:inputSet列表向量化后映射到vocabList中的列表
"""
# 将数据集转为词向量(创建一个包含在所有文档中出现的不重复的词集)
def setOfWords2Vec(vocabList, inputSet):# 创建一个其中所含元素都为0的列表returnVec = [0]*len(vocabList)for word in inputSet:if word in vocabList:returnVec[vocabList.index(word)] = 1else:print('the word: %s is not in my Vocabulary!' % word)return returnVec
if __name__ == '__main__':postingList, classVec = loadDataSet()myVocabList = createVocabList(postingList)print('myVocabList:\n', myVocabList)print(setOfWords2Vec(myVocabList, postingList[0]))

截图:

3 、词向量计算概率

记w表示一个向量(可理解为经过向量化后的一封邮件),它由多个数值组成。在该例中数值个数与词汇表中的词条个数相同,则贝叶斯公式可表示为:

源代码:

"""
函数说明:朴素贝叶斯分类器训练函数
Parameter:trainMatrix — 训练文档矩阵,即setOfWord2Vec函数返回的returnVec构成的矩阵trainCategory - 训练类别标签向量,即loadDataSet返回的classVec
Returns:p0Vect - 非侮辱类的条件概率数组p1Vect - 侮辱类的条件概率数组pAbusive - 文档属于侮辱类的概率
"""
def trainNBO(trainMatrix,trainCategory):#文档数目(6)numTrainDocs = len(trainMatrix) #词数numWords = len(trainMatrix[0])##初始化概率     pAbusive = sum(trainCategory) / float(numTrainDocs)#使用zeros()初始化后的数组如果其中一个概率值为0则最后的结果也为0,因此使用ones() # numpy中的ndarray对象用于存放同类型元素的多维数组。p0Num = np.ones(numWords)p1Num = np.ones(numWords)p0Denom = 2.0p1Denom = 2.0for i in range(numTrainDocs):if trainCategory[i] == 1:#向量相加p1Num += trainMatrix[i]p1Denom += sum(trainMatrix[i])  else:p0Num += trainMatrix[i]p0Denom += sum(trainMatrix[i])# 分别计算某个词条在某个类别(该类别中所有词条的总数)中的占比  # #避免程序输出下溢,采用自然对数处理p1Vect = np.log(p1Num/p1Denom)p0Vect = np.log(p0Num/p0Denom)return p0Vect,p1Vect,pAbusive
if __name__ == '__main__':postingList, classVec = loadDataSet()myVocabList = createVocabList(postingList)trainMat = []for postinDoc in postingList:trainMat.append(setOfWords2Vec(myVocabList, postinDoc))p0Vect, p1Vect, pAbusive = trainNBO(trainMat, classVec)print('p0Vect:\n', p0Vect)print('p1Vect:\n', p1Vect)print('文档属于侮辱性文档的概率:', pAbusive)

4.朴素贝叶斯函数

源代码:

# -*- coding: UTF-8 -*-"""
函数说明:创建实验样本
Parameters:无
Returns:postingList - 实验样本切分的词条classVec - 类别标签向量
"""
def loadDataSet():postingList=[['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],                #切分的词条['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],['stop', 'posting', 'stupid', 'worthless', 'garbage'],['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]classVec = [0,1,0,1,0,1]                                                                   #类别标签向量,1代表侮辱性词汇,0代表不是return postingList,classVecif __name__ == '__main__':postingLIst, classVec = loadDataSet()for each in postingLIst:print(each)print(classVec)

运行截图:

5、使用朴素贝叶斯进行交叉验证

源代码:

import numpy as np
import random
import re'''
Parameters:dataSet - 整理的样本数据集
Returns:vocabSet - 返回不重复的词条列表,也就是词汇表
'''
# 函数说明:将切分的实验样本词条整理成不重复的词条列表,也就是词汇表
def createVocabList(dataSet):vocabSet = set([])                      #创建一个空的不重复列表for document in dataSet:vocabSet = vocabSet | set(document) #取并集return list(vocabSet)'''
Parameters:vocabList - createVocabList返回的列表inputSet - 切分的词条列表
Returns:returnVec - 文档向量,词集模型
'''
# 函数说明:根据vocabList词汇表,将inputSet向量化,向量的每个元素为1或0
def setOfWords2Vec(vocabList, inputSet):returnVec = [0] * len(vocabList)                               #创建一个其中所含元素都为0的向量for word in inputSet:                                          #遍历每个词条if word in vocabList:                                      #如果词条存在于词汇表中,则置1returnVec[vocabList.index(word)] = 1else: print("the word: %s is not in my Vocabulary!" % word)return returnVec                                               #返回文档向量'''
Parameters:vocabList - createVocabList返回的列表inputSet - 切分的词条列表
Returns:returnVec - 文档向量,词袋模型
'''
# 函数说明:根据vocabList词汇表,构建词袋模型
def bagOfWords2VecMN(vocabList, inputSet):returnVec = [0]*len(vocabList)                          #创建一个其中所含元素都为0的向量for word in inputSet:                                   #遍历每个词条if word in vocabList:                               #如果词条存在于词汇表中,则计数加一returnVec[vocabList.index(word)] += 1return returnVec                                        #返回词袋模型'''
Parameters:trainMatrix - 训练文档矩阵,即setOfWords2Vec返回的returnVec构成的矩阵trainCategory - 训练类别标签向量,即loadDataSet返回的classVec
Returns:p0Vect - 侮辱类的条件概率数组p1Vect - 非侮辱类的条件概率数组pAbusive - 文档属于侮辱类的概率
'''
# 函数说明:朴素贝叶斯分类器训练函数
def trainNB0(trainMatrix,trainCategory):numTrainDocs = len(trainMatrix)                     #计算训练的文档数目numWords = len(trainMatrix[0])                      #计算每篇文档的词条数pAbusive = sum(trainCategory)/float(numTrainDocs)   #文档属于侮辱类的概率p0Num = np.ones(numWords); p1Num = np.ones(numWords)#创建numpy.ones数组,词条出现数初始化为1,拉普拉斯平滑p0Denom = 2.0; p1Denom = 2.0                        #分母初始化为2,拉普拉斯平滑for i in range(numTrainDocs):if trainCategory[i] == 1:                       #统计属于侮辱类的条件概率所需的数据,#即P(w0|1),P(w1|1),P(w2|1)···p1Num += trainMatrix[i]p1Denom += sum(trainMatrix[i])else:                                           #统计属于非侮辱类的条件概率所需的数据,#即P(w0|0),P(w1|0),P(w2|0)···p0Num += trainMatrix[i]p0Denom += sum(trainMatrix[i])p1Vect = np.log(p1Num/p1Denom)                      #取对数,防止下溢出p0Vect = np.log(p0Num/p0Denom)return p0Vect,p1Vect,pAbusive#返回属于侮辱类的条件概率数组,属于非侮辱类的条件概率数组,文档属于侮辱类的概率'''
Parameters:vec2Classify - 待分类的词条数组p0Vec - 侮辱类的条件概率数组p1Vec -非侮辱类的条件概率数组pClass1 - 文档属于侮辱类的概率
Returns:0 - 属于非侮辱类1 - 属于侮辱类
'''
# 函数说明:朴素贝叶斯分类器分类函数
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):p1 = sum(vec2Classify * p1Vec) + np.log(pClass1)        #对应元素相乘。logA * B = logA + logB,#所以这里加上log(pClass1)p0 = sum(vec2Classify * p0Vec) + np.log(1.0 - pClass1)if p1 > p0:return 1else:return 0'''
Parameters:trainMatrix - 训练文档矩阵,即setOfWords2Vec返回的returnVec构成的矩阵trainCategory - 训练类别标签向量,即loadDataSet返回的classVec
Returns:p0Vect - 侮辱类的条件概率数组p1Vect - 非侮辱类的条件概率数组pAbusive - 文档属于侮辱类的概率
'''
# 函数说明:朴素贝叶斯分类器训练函数
def trainNB0(trainMatrix,trainCategory):numTrainDocs = len(trainMatrix)                      #计算训练的文档数目numWords = len(trainMatrix[0])                       #计算每篇文档的词条数pAbusive = sum(trainCategory)/float(numTrainDocs)    #文档属于侮辱类的概率p0Num = np.ones(numWords); p1Num = np.ones(numWords) #创建numpy.ones数组,词条出现数初始化为1,拉普拉斯平滑p0Denom = 2.0; p1Denom = 2.0                         #分母初始化为2,拉普拉斯平滑for i in range(numTrainDocs):if trainCategory[i] == 1:                        #统计属于侮辱类的条件概率所需的数据,#即P(w0|1),P(w1|1),P(w2|1)···p1Num += trainMatrix[i]p1Denom += sum(trainMatrix[i])else:                                            #统计属于非侮辱类的条件概率所需的数据,#即P(w0|0),P(w1|0),P(w2|0)···p0Num += trainMatrix[i]p0Denom += sum(trainMatrix[i])p1Vect = np.log(p1Num/p1Denom)                       #取对数,防止下溢出p0Vect = np.log(p0Num/p0Denom)return p0Vect,p1Vect,pAbusive#返回属于侮辱类的条件概率数组,属于非侮辱类的条件概率数组,文档属于侮辱类的概率# 函数说明:接收一个大字符串并将其解析为字符串列表
def textParse(bigString):                                       #将字符串转换为字符列表listOfTokens = re.split(r'\W+', bigString)                  #将特殊符号作为切分标志进行字符串切分,即非字母、非数字return [tok.lower() for tok in listOfTokens if len(tok) > 2]#除了单个字母,例如大写的I,其它单词变成小写# 函数说明:测试朴素贝叶斯分类器
def spamTest():docList = []; classList = []; fullText = []for i in range(1, 26):                                             #遍历25个txt文件wordList = textParse(open('email/spam/%d.txt' % i, 'r').read())#读取每个垃圾邮件,并字符串转换成字符串列表docList.append(wordList)fullText.append(wordList)classList.append(1)                                            #标记垃圾邮件,1表示垃圾文件wordList = textParse(open('email/ham/%d.txt' % i, 'r').read()) #读取每个非垃圾邮件,并字符串转换成字符串列表docList.append(wordList)fullText.append(wordList)classList.append(0)                            #标记非垃圾邮件,1表示垃圾文件vocabList = createVocabList(docList)            #创建词汇表,不重复trainingSet = list(range(50)); testSet = []      #创建存储训练集的索引值的列表和测试集的索引值的列表for i in range(10):#从50个邮件中,随机挑选出40个作为训练集,10个做测试集randIndex = int(random.uniform(0, len(trainingSet)))              #随机选取索索引值testSet.append(trainingSet[randIndex])                            #添加测试集的索引值del(trainingSet[randIndex])                                       #在训练集列表中删除添加到测试集的索引值trainMat = []; trainClasses = []                                      #创建训练集矩阵和训练集类别标签系向量for docIndex in trainingSet:                                          #遍历训练集trainMat.append(setOfWords2Vec(vocabList, docList[docIndex]))     #将生成的词集模型添加到训练矩阵中trainClasses.append(classList[docIndex])                          #将类别添加到训练集类别标签系向量中p0V, p1V, pSpam = trainNB0(np.array(trainMat), np.array(trainClasses))#训练朴素贝叶斯模型errorCount = 0                                                        #错误分类计数for docIndex in testSet:                                              #遍历测试集wordVector = setOfWords2Vec(vocabList, docList[docIndex])         #测试集的词集模型if classifyNB(np.array(wordVector), p0V, p1V, pSpam) != classList[docIndex]:#如果分类错误errorCount += 1                                               #错误计数加1print("分类错误的测试集:",docList[docIndex])print('错误率:%.2f%%' % (float(errorCount) / len(testSet) * 100))if __name__ == '__main__':spamTest()

运行截图:

分类错误的测试集: ['yay', 'you', 'both', 'doing', 'fine', 'working', 'mba', 'design', 'strategy', 'cca', 'top', 'art', 'school', 'new', 'program', 'focusing', 'more', 'right', 'brained', 'creative', 'and', 'strategic', 'approach', 'management', 'the', 'way', 'done', 'today']
分类错误的测试集: ['home', 'based', 'business', 'opportunity', 'knocking', 'your', 'door', 'don抰', 'rude', 'and', 'let', 'this', 'chance', 'you', 'can', 'earn', 'great', 'income', 'and', 'find', 'your', 'financial', 'life', 'transformed', 'learn', 'more', 'here', 'your', 'success', 'work', 'from', 'home', 'finder', 'experts']
错误率:20.00%

四、总结

最小错误概率贝叶斯分类器和最小风险概率贝叶斯分类器基于最小错误率的贝叶斯决策
实质:通过观察x把状态的先验概率P(wi)转化为后验概率判别错误率的问题。

机器学习-----朴素贝叶斯相关推荐

  1. 秒懂机器学习---朴素贝叶斯

    秒懂机器学习---朴素贝叶斯 一.总结 一句话总结: 尽管朴素贝叶斯的条件独立性假设存在一定的问题,但是朴素贝叶斯算法仍然能取得比较理想的分类预测结果. 1.朴素贝叶斯分类算法 和 KNN分类算法和决 ...

  2. 机器学习朴素贝叶斯算法+tkinter库界面实现好瓜坏西瓜分类

    机器学习朴素贝叶斯算法+tkinter库界面实现好瓜坏西瓜分类 一.界面实现 from tkinter import * from tkinter import ttk import NBdef ma ...

  3. 机器学习朴素贝叶斯算法_机器学习中的朴素贝叶斯算法

    机器学习朴素贝叶斯算法 朴素贝叶斯算法 (Naive Bayes Algorithm) Naive Bayes is basically used for text learning. Using t ...

  4. python机器学习-朴素贝叶斯(Naive Bayes)模型建立及评估(完整代码+实现效果)

    实现功能: python机器学习-朴素贝叶斯(Naive Bayes)模型建立及评估. 实现代码: # 导入需要的库 from warnings import simplefilter simplef ...

  5. 机器学习 | 朴素贝叶斯法知识总结

    机器学习 | 朴素贝叶斯法理论知识 贝叶斯决策论是概率框架下实施决策的基本方法.对分类任务来说,在所有相关概率都已知的理想情况下,贝叶斯决策论考虑如何基于这些概率和误判损失来选择最优的类别标记.朴素贝 ...

  6. 机器学习朴素贝叶斯_机器学习基础朴素贝叶斯分类

    机器学习朴素贝叶斯 In the previous stories, I had given an explanation of the program for implementation of v ...

  7. 机器学习---朴素贝叶斯模型

    机器学习-朴素贝叶斯模型 1.通俗解释: 朴素贝叶斯模型的基本思路就是利用贝叶斯的后验概率公式来推算当前属性下的数据样本属于哪一个类别.直白一点说,就是在特征属性为当前取值的条件下,该样本归属于那个类 ...

  8. 机器学习-朴素贝叶斯(基础讲解+代码实现+图像展示)

    朴素贝叶斯 定理: 某晚,C准备收拾东西接女朋友,那么小C要不要带伞呢. 已知:天气预报说今日降水概率为50%–P(A) 晚高峰堵车的概率为80%–P(B) 如果下雨,晚高峰堵车的概率是95%–P(B ...

  9. 5 机器学习 朴素贝叶斯算法 高斯模型 多项式模型 伯努利模型 拉普拉普平滑系数 TfidfVectorizer

    机器学习 1 朴素贝叶斯算法 1.1 朴素贝叶斯算法介绍 朴素贝叶斯算法是一种衡量标签和特征之间概率关系的监督学习算法,是一种专注于分类的算法."朴素"二字表示这个算法基于一个朴素 ...

  10. 机器学习-朴素贝叶斯。

    前言: 朴素贝叶斯是经典的机器学习算法之一,也是为数不多的基于概率论的分类算法.朴素贝叶斯原理简单,也很容易实现,多用于文本分类,比如垃圾邮件过滤. 1.算法思想--基于概率的预测 决策树算法中提到朴 ...

最新文章

  1. PyQt4 进度条和日历 代码
  2. U盘为什么还有剩余空间,但却提示说空间不够
  3. c 定义结构体时提示应输入声明_C语言结构体的坑很多,这6大方法千万要记住!...
  4. 万里目联合网易云信 引领奢侈品电商新风潮
  5. linux安装python3教程_linux下安装python3和对应的pip环境教程详解
  6. eureka多了一个莫名其妙的服务_SpringCloud 服务注册与发现组件 Eureka
  7. python 3.9 发布计划_Python 3.9.0 beta4 发布
  8. java 垃圾回收机制_Java的垃圾回收机制
  9. RK平台ubuntu安装vbox
  10. php代码高亮正则,php通过正则表达式实现语法高亮
  11. oracle 安装包_【Oracle监控】-Spotlight On Oracle安装和使用
  12. mysql oracle视频网盘_动力节点MySQL数据库视频 百度云 网盘 下载
  13. 使用java实现MD5码算法
  14. 技术管理进阶——什么是影响力
  15. 学3D建模需要有美术功底吗?
  16. Java自学路线总结
  17. 按什么键能够迅速锁定计算机,电脑快速锁屏按什么键
  18. banne图怎么设计才会有更多的点击率
  19. Cisco交换机与路由器常用协议及其配置命令
  20. Android Telephony通话状态更新消息上报流程

热门文章

  1. oracle模糊查询like语句,sql语句select like模糊查询用法
  2. linux打开文件慢,Linux 文件打开过多 (Too many open files)
  3. 码code | 腾讯大佬带你深入理解小游戏的架构设计与开发
  4. 首席新媒体黎想教程:可复用的社群运营,加直播流程!
  5. 房产中介、房屋租赁、房屋买卖APP(H5)
  6. View系列:贝塞尔曲线专栏:绘制二阶贝塞尔曲线(二)
  7. 规划一个智能工厂应避免的十个坑
  8. Python 海龟绘图 100 题——第 14 题
  9. bilibili登录注册页面
  10. 如何在线CAJ转换成Word文档