一、算法原理

贝叶斯公式描述了两个相关的随机事件或随机变量之间的概率关系。贝叶斯分类器使用贝叶斯公式计算样本属于某一类的条件概率值,并将样本判定为概率值最大的那个类。

贝叶斯公式为:

我们把P(A)称为"先验概率"(Prior probability),即在B事件发生之前,我们对A事件概率的一个判断。

P(A|B)称为"后验概率"(Posterior probability),即在B事件发生之后,我们对A事件概率的重新评估。

P(B|A)/P(B)称为"可能性函数"(Likelyhood),这是一个调整因子,使得预估概率更接近真实概率。

这一结论可以推广到随机变量。分类问题中样本的特征向量取值x与样本属性y具有因果关系。因为样本属于y,所以具有特征值x。贝叶斯分类器是在已知样本的特征向量为x的条件下反推样本所属的类别。根据贝叶斯公式有:

只要知道特征向量的概率分布p(x),每一个类出现的概率p(y),以及每一个类样本的条件概率p(y|x),就可以计算出样本属于每一个类的概率p(y|x)。分类问题只要预测类别,比较样本属于每一个类的概率的大小,找出该值最大的那一个类即可,因此可以忽略p(x),因为它对所有类都是相同的。简化后分类器的判别函数为

贝叶斯和朴素贝叶斯的概念是不同的,区别就在于“朴素”二字,朴素贝叶斯对条件个概率分布做了条件独立性的假设。朴素贝叶斯分类器假设特征向量的分量之间相互独立。

二、算法实践

1.离散型特征

以在线社区留言为例。为了不影响社区的发展,我们要屏蔽侮辱性的言论,所以要构建一个快速过滤器,如果某条留言使用了负面或者侮辱性的语言,那么就将该留言标志为内容不当。过滤这类内容是一个很常见的需求。对此问题建立两个类型:侮辱类和非侮辱类,使用1和0分别表示。(来自《机器学习实战》转载自http://blog.csdn.net/c406495762 )

# -*- coding: UTF-8 -*-
import numpy as np
from functools import reduce"""
函数说明:创建实验样本Parameters:无
Returns:postingList - 实验样本切分的词条classVec - 类别标签向量
Author:Jack Cui
Blog:http://blog.csdn.net/c406495762
Modify:2017-08-11
"""
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,classVec                                                             #返回实验样本切分的词条和类别标签向量"""
函数说明:将切分的实验样本词条整理成不重复的词条列表,也就是词汇表Parameters:dataSet - 整理的样本数据集
Returns:vocabSet - 返回不重复的词条列表,也就是词汇表
Author:Jack Cui
Blog:http://blog.csdn.net/c406495762
Modify:2017-08-11
"""
def createVocabList(dataSet):vocabSet = set([])                    #创建一个空的不重复列表for document in dataSet:                vocabSet = vocabSet | set(document) #取并集return list(vocabSet)"""
函数说明:根据vocabList词汇表,将inputSet向量化,向量的每个元素为1或0Parameters:vocabList - createVocabList返回的列表inputSet - 切分的词条列表
Returns:returnVec - 文档向量,词集模型
Author:Jack Cui
Blog:http://blog.csdn.net/c406495762
Modify:2017-08-11
"""
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:trainMatrix - 训练文档矩阵,即setOfWords2Vec返回的returnVec构成的矩阵trainCategory - 训练类别标签向量,即loadDataSet返回的classVec
Returns:p0Vect - 侮辱类的条件概率数组p1Vect - 非侮辱类的条件概率数组pAbusive - 文档属于侮辱类的概率
Author:Jack Cui
Blog:http://blog.csdn.net/c406495762
Modify:2017-08-12
"""
def trainNB0(trainMatrix,trainCategory):numTrainDocs = len(trainMatrix)                            #计算训练的文档数目numWords = len(trainMatrix[0])                           #计算每篇文档的词条数pAbusive = sum(trainCategory)/float(numTrainDocs)       #文档属于侮辱类的概率p0Num = np.zeros(numWords); p1Num = np.zeros(numWords) #创建numpy.zeros数组,p0Denom = 0.0; p1Denom = 0.0                         #分母初始化为0.0for 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 = p1Num/p1Denom                                  #相除        p0Vect = p0Num/p0Denom          return p0Vect,p1Vect,pAbusive #返回属于侮辱类的条件概率数组,属于非侮辱类的条件概率数组,文档属于侮辱类的概率"""
函数说明:朴素贝叶斯分类器分类函数Parameters:vec2Classify - 待分类的词条数组p0Vec - 侮辱类的条件概率数组p1Vec -非侮辱类的条件概率数组pClass1 - 文档属于侮辱类的概率
Returns:0 - 属于非侮辱类1 - 属于侮辱类
Author:Jack Cui
Blog:http://blog.csdn.net/c406495762
Modify:2017-08-12
"""
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):p1 = reduce(lambda x,y:x*y, vec2Classify * p1Vec) * pClass1                #对应元素相乘p0 = reduce(lambda x,y:x*y, vec2Classify * p0Vec) * (1.0 - pClass1)print('p0:',p0)print('p1:',p1)if p1 > p0:return 1else: return 0"""
函数说明:测试朴素贝叶斯分类器Parameters:无
Returns:无
Author:Jack Cui
Blog:http://blog.csdn.net/c406495762
Modify:2017-08-12
"""
def testingNB():listOPosts,listClasses = loadDataSet()                       #创建实验样本myVocabList = createVocabList(listOPosts)                   #创建词汇表trainMat=[]for postinDoc in listOPosts:trainMat.append(setOfWords2Vec(myVocabList, postinDoc))             #将实验样本向量化p0V,p1V,pAb = trainNB0(np.array(trainMat),np.array(listClasses))      #训练朴素贝叶斯分类器testEntry = ['love', 'my', 'dalmation']                                   #测试样本1thisDoc = np.array(setOfWords2Vec(myVocabList, testEntry))               #测试样本向量化if classifyNB(thisDoc,p0V,p1V,pAb):print(testEntry,'属于侮辱类')                                       #执行分类并打印分类结果else:print(testEntry,'属于非侮辱类')                                        #执行分类并打印分类结果testEntry = ['stupid', 'garbage']                                      #测试样本2thisDoc = np.array(setOfWords2Vec(myVocabList, testEntry))               #测试样本向量化if classifyNB(thisDoc,p0V,p1V,pAb):print(testEntry,'属于侮辱类')                                       #执行分类并打印分类结果else:print(testEntry,'属于非侮辱类')                                        #执行分类并打印分类结果if __name__ == '__main__':testingNB()

2.连续型特征

如果特征向量的分量是连续型随机变量,可以假设它们服从正态分布(高斯分布)。根据训练样本集可以计算出正态分布的均值和方差,这可以通过最大似然估计得到。连续型随机变量不能计算它在某一点的概率,因为它在任何一点处的概率为0。我们可以直接用概率密度函数的值作为概率值,得到各类别的概率。

我们通过高斯贝叶斯模型对Iris数据集进行花的类别识别。该数据集包含Iris花的三个品种(Iris setosa, Iris virginica and Iris versicolor)各50个样本,每个样本还有4个特征参数(分别是萼片<sepals>的长宽和花瓣<petals>的长 宽,以厘米为单位)。

(来自《统计学习方法》的python实现)

import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from collections import Counter
import math#data
def create_data():iris = load_iris()df = pd.DataFrame(iris.data, columns=iris.feature_names)df['label'] = iris.targetdf.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'label']#data = df.iloc[:100,:]data = np.array(df)#print (data)return data[:,:-1],data[:,-1]class NaiveBayes:def __init__(self):self.model = None#数学期望@staticmethoddef mean(X):return sum(X) / float(len(X))#标准差(方差)def stdev(self, X):avg = self.mean(X)return math.sqrt(sum([pow(x-avg,2) for x in X]) / float(len(X)))#概率密度函数def gaussian_probability(self, x, mean, stdev):exponent = math.exp(-(math.pow(x-mean, 2)/(2*math.pow(stdev,2))))return (1/ (math.sqrt(2*math.pi) * stdev)) * exponent#处理X_traindef summarize(self, train_data):summarizes = [(self.mean(i), self.stdev(i)) for i in zip(*train_data)]return summarizes#分类别求出数学期望和标准差def fit(self, X, y):labels = list(set(y))data = {label:[] for label in labels}for f, label in zip(X, y):data[label].append(f)self.model = {label: self.summarize(value) for label, value in data.items()}return 'guassianNB train done'#计算概率def calculate_probabilities(self, input_data):probabilities = {}for label, value in self.model.items():probabilities[label] = 1for i in range(len(value)):mean, stdev = value[i]probabilities[label] *= self.gaussian_probability(input_data[i], mean, stdev)return probabilities#类别def predict(self, X_test):label = sorted(self.calculate_probabilities(X_test).items(), key=lambda x: x[-1])[-1][0]return labeldef score(self, X_test, y_test):right = 0for X,y in zip(X_test, y_test):label = self.predict(X)if label == y:right += 1return right / float(len(X_test))if __name__ == '__main__':X,y = create_data()X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)model = NaiveBayes()model.fit(X_train, y_train)score = model.score(X_test, y_test)print(score)pre_label = model.predict([4.4, 3.2, 1.3, 0.2])print(pre_label)

3.sklearn实现

朴素贝叶斯是一类比较简单的算法,scikit-learn中朴素贝叶斯类库的使用也比较简单。在scikit-learn中,一共有3个朴素贝叶斯的分类算法类。分别是GaussianNB,MultinomialNB和BernoulliNB。其中GaussianNB就是先验为高斯分布的朴素贝叶斯,MultinomialNB就是先验为多项式分布的朴素贝叶斯,而BernoulliNB就是先验为伯努利分布的朴素贝叶斯。

官方英文文档地址:http://scikit-learn.org/dev/modules/generated/sklearn.naive_bayes.MultinomialNB.html

import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import GaussianNB, BernoulliNB, MultinomialNB #高斯模型、伯努利模型、多项式模型#data
def create_data():iris = load_iris()df = pd.DataFrame(iris.data, columns=iris.feature_names)df['label'] = iris.targetdf.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'label']#data = df.iloc[:100,:]data = np.array(df)#print (data)return data[:,:-1],data[:,-1]if __name__ == '__main__':X,y = create_data()X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)clf = GaussianNB()clf.fit(X_train, y_train)score = clf.score(X_test, y_test)print(score)pre_label = clf.predict([[4.4, 3.2, 1.3, 0.2]])print(pre_label)

三、算法总结

朴素贝叶斯优点:

  • 生成式模型,通过计算概率来进行分类,可以用来处理多分类问题。
  • 对小规模的数据表现很好,适合多分类任务,适合增量式训练,算法也比较简单。
  • 对数据的训练快,分类也快

朴素贝叶斯缺点:

  • 对输入数据的表达形式很敏感。
  • 由于朴素贝叶斯的“朴素”特点,所以会带来一些准确率上的损失。
  • 需要计算先验概率,分类决策存在错误率。

应用场景:

  • 文本分类/垃圾文本过滤/情感判别
  • 多分类实时预测
  • 推荐系统

四、面试题

1.什么是贝叶斯决策理论?                                                                                                                                                                     贝叶斯决策理论是主观贝叶斯派归纳理论的重要组成部分。贝叶斯决策就是在不完全情报下。对部分未知的状态用主观概率估计,然后用贝叶斯公式对发生的概率进行修正,最后利用期望值和修正概率做出最优决策(选择概率最大的类别)。其基本思想是:(1)已知类条件概率密度参数表达式和先验概率(2)利用贝叶斯公式转化为后验概率(3)根据后验概率大小进行决策分类

2.朴素贝叶斯算法的前提假设是什么?                                                                                                                                                   朴素贝叶斯则是建立在两个前提假设上的:(1)特征之间相互独立(2)每个特征同等重要

3.什么是朴素贝叶斯的零概率问题?                                                                                                                                                       零概率问题,就是在计算实例的概率时,如果某个量x,在训练集中未出现过,会导致整个实例的概率结果为0。可以使用拉普拉斯平滑解决,具体做法是给分子分母同时加上一个正数。如果特征分量的取值有k种情况,将分母加上k,每个类的分子加上1,这样可以保证所有类的条件概率加起来还是1。

4.当数据的属性是连续变量时,朴素贝叶斯算法如何处理?                                                                                                                   当数据的属性是连续变量时,有两种方法可以计算属性的条件概率。(1)把一个连续的属性离散化,然后用相应的离散区间替换连续值。(2)假设连续变量服从某种概率分布,然后使用训练数据估计分布的参数,例如使用高斯分布。

5.朴素贝叶斯有哪几种常用的分类模型?                                                                                                                                              朴素贝叶斯的三个常用模型:高斯、多项式、伯努利

6.高度相关的特征对朴素贝叶斯有什么影响?                                                                                                                                       假设有两个特征高度相关,相当于该特征在模型中发挥了两次作用(计算两次条件概率),使得朴素贝叶斯获得的结果向该特征所希望的方向进行了偏移,影响了最终结果的准确性,所以朴素贝叶斯算法应先处理特征,把相关特征去掉。

机器学习系列七:朴素贝叶斯相关推荐

  1. 机器学习实战之朴素贝叶斯

    机器学习实战之朴素贝叶斯 一.朴素贝叶斯算法概述 1.贝叶斯决策理论 2.条件概率 3.全概率公式 4.贝叶斯推断 5.朴素贝叶斯推断 二.实战 三.总结 1.朴素贝叶斯推断的一些优点: 2.朴素贝叶 ...

  2. 《机器学习实战》朴素贝叶斯

    机器学习实战的朴素贝叶斯一章中的源文件老是提示 IndexError: range object index out of range 看源码里怎么都不会溢出啊,除非minLen为0:所以看了下测试集 ...

  3. 机器学习面试题——朴素贝叶斯

    机器学习面试题--朴素贝叶斯 提示:这些知识点也是大厂笔试经常考的题目,我记得阿里和京东就考!!!想必在互联网大厂就会用这些知识解决实际问题 朴素贝叶斯介绍一下 朴素贝叶斯优缺点 贝叶斯公式 朴素贝叶 ...

  4. 机器学习:基于朴素贝叶斯对花瓣花萼的宽度和长度分类预测

    机器学习:基于朴素贝叶斯对花瓣花萼的宽度和长度分类预测 作者:i阿极 作者简介:Python领域新星作者.多项比赛获奖者:博主个人首页

  5. 机器学习实验:朴素贝叶斯算法

    机器学习实验:朴素贝叶斯算法 问题如下: 根据给出的算法naivebayes.py,实现: 1.将数据集文件naivebayes_data.csv中的数据替换成14天打球与天气数据: 2.预测样本{O ...

  6. 【机器学习算法笔记系列】朴素贝叶斯(NB)算法详解和实战

    朴素贝叶斯(NB)算法概述 朴素贝叶斯(Naïve Bayes, NB)算法,是一种基于贝叶斯定理与特征条件独立假设的分类方法.朴素:特征条件独立:贝叶斯:基于贝叶斯定理.属于监督学习的生成模型,实现 ...

  7. python机器学习库sklearn——朴素贝叶斯分类器

    分享一个朋友的人工智能教程.零基础!通俗易懂!风趣幽默!还带黄段子!大家可以看看是否对自己有帮助:点击打开 全栈工程师开发手册 (作者:栾鹏) python数据挖掘系列教程 文档贝叶斯分类器的相关的知 ...

  8. 机器学习理论学习:朴素贝叶斯

    最近一直在看<统计学习方法>,打算先把理论搞明白,后续将着重用c++实现下自己ml库,计划就是这样,好好干吧.其实在平常中使用这个算法比较少,但他主要的优势是在少量,几十或几百张样本的情况 ...

  9. 垃圾邮件分类快速理解机器学习中的朴素贝叶斯(Naive Bayes)

    贝叶斯方法是一个历史悠久,有着坚实的理论基础的方法,同时处理很多问题时直接而又高效,很多高级自然语言处理模型也可以从它演化而来.因此,学习贝叶斯方法,是研究自然语言处理问题的一个非常好的切入口. 其实 ...

  10. 【机器学习基础】朴素贝叶斯的算法实现

    前言 本次我们将梳理下朴素贝叶斯(Naive Bayes)的相关内容. 本文约1.6k字,预计阅读10分钟. 概要 朴素贝叶斯算法是一种适用于二分类和多分类分类问题的「分类算法」.在贝叶斯概率框架下, ...

最新文章

  1. NandFlash系列之一:NorFlash与NandFlash对比
  2. MySQL返回多行错误怎么处理_结果包含多个行错误mysql
  3. Photoshop简单制作绿色暗调风景图
  4. 数据结构 稀疏矩阵的实现方法
  5. 网络编程模型 / Reactor
  6. Android XML文件中设置字体
  7. docker centos ssh
  8. mysql xdevapi_MySql Connector/C++8简介
  9. DIY 主机 所有AMD IntelCPU及主板
  10. 机器学习训练营_如何不运行学习代码训练营
  11. Centos7下更改docker镜像和容器的默认路径
  12. windows xp 创建 Oracle(11G)数据库实例时写入系统日志失败解决方案
  13. 2019年老电脑E5450+硬改775 无故死机故障排除记录
  14. 什么是 jsp,什么是Servlet?jsp 和Servlet 有什么区别?
  15. 不到90天的时间,备考数据库系统工程师还来得及吗?
  16. ip地址中保留地址讲解
  17. 图像处理: AlphaBlend
  18. 计算机怎么格式化电脑吗,电脑怎么格式化
  19. c语言 将数组转化成二叉树
  20. 干货:一个案例看懂“结巴”分词(Jieba),入行NLP必备

热门文章

  1. 开园一个月,热搜近10次。明星网红纷纷打卡,北京环球影城爆火背后的原因是?
  2. 公司网站应怎样做优化标梵互动
  3. MacOS苹果电脑各种常见音频问题集锦
  4. 笔记本/平板电脑连接电视机打造高清影院/机顶盒
  5. 堆积如山:探索数据结构中的堆
  6. 什么牌子投影仪好?投影仪买什么牌子的好
  7. 配置nginx使其支持pathinfo路径模式
  8. 词法,文法,语法,语义
  9. 《改变你一生的108个心理学法则》读书笔记
  10. 非暴力沟通:沟通场景