本文所有代码都是基于python3.6的,数据及源码下载:传送门

引言

最简单的解决方法通常是最强大的,朴素贝叶斯呢就是一个很好的证明。尽管在过去的几年里机器学习取得了巨大的进步,各种优秀算法层出不穷,但朴素贝叶斯依旧证明了它不仅简单,而且快速、准确、可靠。朴素贝叶斯已经成功地用于许多机器学习领域,但它在自然语言处理(NLP)问题上尤其有效。
朴素贝叶斯是一种利用概率论和贝叶斯定理来预测样本类别的概率算法。概率性,这意味着朴素贝叶斯计算给定样本的每个类别的概率,然后输出最高的类别。它们得到这些概率的方法是使用贝叶斯定理,它描述了一个特征的概率,基于可能与这个特征相关的先验知识。
众所周知,概率论是许多机器学习算法的基础,所以理解概率论相关知识对我们深刻理解这一主题就显得尤为重要。前面决策树分享:ID3决策树原理分析及python实现我们在计算香农熵时,有涉及到一些概率知识。这次分享将在此基础上做进一部分的拓展。

一个简单的例子

我们接下来看看在一个实际的例子,假设我们正在构造一个分类器,它表示文本是否与运动有关。我们的训练集一共有五个句子:

Text Category
“A great game” Sports
“The election was over” Not Sports
“Very clean match” Sports
“A clean but forgettable game” Sports
“It was a close election” Not Sports
那么问题来了,文本"A very close game"属于哪一类呢?(结合前面已经分享的kNN、decision tree)。既然朴素贝叶斯是一个概率分类器,那么我们只要计算出该文本属于Sports的概率P1以及不属于Sports的概率P2,选择概率最大的类别即可。从数学公式上来说就是:$P(Sports A\ very\ close\ game) $——给定句子A very close game,该句子类别是Sports的概率。
啊哈,如何?简单吧,那么我们该如何求这些概率呢?

特征工程

在创建机器模型时,我们所做的第一件事是把什么用作特征。在这个例子中,我们没有数值特征,只有文本。我们需要把文本转换成我们可以用来计算概率的数字。那么我们该怎么做呢?很简单!我们使用词频。也就是说,我们忽略单词顺序和句子结构,把每个文本都看成是它包含的单词的集合。我们的特征就是是每一个单词的计数。尽管这种方法看起来过于简单,但效果却出奇的好。

贝叶斯定理

现在我们需要把我们想要计算的概率转换成可以用词频来计算的东西。为此,我们将使用概率的一些基本性质,以及贝叶斯定理。贝叶斯定理在处理条件概率时很好用。
###贝叶斯决策论
贝叶斯决策论是概率框架下实施决策的基本方法。对于分类任务来说,在所有相关概率都已知的理想情形下,贝叶斯决策论考虑如何基于这些概率和误判损失来选择最优的类别标记。我们用上面的例子举例。假设有两种可能的类别标记N=2N=2N=2,则类别标签y={c1,c2}y=\{c_1,c_2\}y={c1​,c2​},其中λij\lambda_{ij}λij​ 是将一个真实标记为cjc_jcj​的样本误分类为cic_ici​所产生的损失。基于后验概率P(ci∣x)P(c_i|x)P(ci​∣x)可获得将样本xxx分类为cic_ici​所产生的期望损失,即样本x上的”条件风险“
R(ci∣x)=∑j=1NλijP(cj∣x)R(c_i|x) = \sum_{j=1}^N \lambda_{ij}P(c_j|x)R(ci​∣x)=j=1∑N​λij​P(cj​∣x)
接下来我们的任务是寻找一个判定准则来最小化总体风险:
R(h)=Ex[R(h(x)∣x)]R(h) = E_x[R(h(x)|x)]R(h)=Ex​[R(h(x)∣x)]
为了最小化总体风险,我们就有了贝叶斯判定准则:为了最小化总体风险,只需在每个样本上选择那个能使条件风险R(c∣x)R(c|x)R(c∣x)最小的类别标记。
对于上述例子中的二分类问题,若目标是最小化分类错误率,则误判损失可写为:
λij={1,otherwise,0,ifi=j;\lambda_{ij} = \{_{1,otherwise,}^{0 , if i=j;}λij​={1,otherwise,0,ifi=j;​
此时条件风险
R(c∣x)=1−P(c∣x)R(c|x) = 1-P(c|x)R(c∣x)=1−P(c∣x)
于是我们最小化R(c∣x)R(c|x)R(c∣x)就是最大化后验概率P(c∣x)P(c|x)P(c∣x)
其实,机器学习所要实现的就是基于有限的训练样本尽可能准确地估计出后验概率P(c∣x)P(c|x)P(c∣x)大体来说,主要有两种策略:

  • 给定x,直接建模P(c∣x)P(c|x)P(c∣x)来预测c,这样的得到的是”判别式模型“
  • 给定x,先对联合概率分布P(x,c)P(x,c)P(x,c)建模,然后再由P(c∣x)=P(x,c)P(x)P(c|x) = \frac{P(x,c)}{P(x)}P(c∣x)=P(x)P(x,c)​获得P(c∣x)P(c|x)P(c∣x)。
    本文讲的朴素贝叶斯就是生成式模型,基于贝叶斯定理,P(c∣x)P(c|x)P(c∣x)可写为
    P(c∣x)=P(c)P(x∣c)P(x)P(c|x) = \frac{P(c)P(x|c)}{P(x)}P(c∣x)=P(x)P(c)P(x∣c)​
    其中,P©是类”先验“概率;P(x∣c)P(x|c)P(x∣c)是样本x相对于类标记c的类条件概率,或称为”似然“;P(x)P(x)P(x)是用于归一化的”证据“因子。

那么在前面的举例中,通过贝叶斯定理我们可以由下面的公式转换求得:
P(Sports∣Averyclosegame)=P(Sports)P(Averyclosegame∣Sports)P(Averyclosegame)P(Sports|A\ very\ close\ game) = \frac{P(Sports) P(A\ very\ close\ game|Sports)}{P(A\ very\ close\ game)} P(Sports∣A very close game)=P(A very close game)P(Sports)P(A very close game∣Sports)​
P(NotSports∣Averyclosegame)=P(NotSports)P(Averyclosegame∣NotSports)P(Averyclosegame)P(Not\ Sports|A\ very\ close\ game) = \frac{P(Not\ Sports) P(A\ very\ close\ game|Not\ Sports)}{P(A\ very\ close\ game)} P(Not Sports∣A very close game)=P(A very close game)P(Not Sports)P(A very close game∣Not Sports)​
通过这个转换我们就能计算概率了,我们只需要计算句子”A very close game“在类别Sports中出现的次数就能通过运算获得P(Sports∣Averyclosegame)P(Sports|A\ very\ close\ game)P(Sports∣A very close game)。
但是问题来了,句子”A very close game“并没有在训练集的类别中出现,那么概率就是0么?很明显”未被观测到“与”出现概率为0“通常是不同的。

朴素起来

极大似然估计

在讲朴素贝叶斯之前我们得提一下极大似然估计。我们前面说了,类条件概率P(x∣c)P(x|c)P(x∣c)直接计数是不可取的,那么不能直接计数得到,那么我们就来”估算“得到。意思就是我们先假定类条件概率具有某种确定的概率分布形式,然后我们再基于训练样本对概率分布的参数进行估计。
事实上,概率模型的训练过程就是参数估计过程。对于参数估计,统计学界有两种不同的观点从而分成了两种学派:

  • 频率主义学派:参数虽然未知,但却是客观存在的固定值,因此可以通过一些准则来确定参数值。
  • 贝叶斯学派:参数是未观察到的随机变量,其本身也可有分布,因此可以先假定参数服从一个先验分布,然后基于观测到的数据来计算参数的后验分布。

我们这篇博文讲的就是频率主义学派的极大似然估计MLE,根据数据采样来估计参数的经典方法。

朴素贝叶斯

前面我们遇到的句子不在训练样本中出现的本质原因是类条件概率P(x∣c)P(x|c)P(x∣c)是所有属性上的联合概率,难以从有限的训练样本中直接估计得到。在朴素贝叶斯中,有种假设:

  • 我们假设特征之间相互独立,就好比上面的句子”A very close game“单词very出现的可能性与very和其他单词相邻没有关系。也就是句子”A very close game“、”very A close game“、”very close A game“是同一个句子!这个假设就是我们标题**朴素(naive)**的含义了。

因此我们有P(Averyclosegame∣Sports)=P(A∣Sports)P(very∣Sports)P(close∣Sports)P(game∣Sports)P(A very close game|Sports) = P(A|Sports)P(very|Sports)P(close|Sports)P(game|Sports)P(Averyclosegame∣Sports)=P(A∣Sports)P(very∣Sports)P(close∣Sports)P(game∣Sports)
Note:朴素贝叶斯通常有两种实现方式:一种基于贝努利模型实现:该实现方式不考虑词在文档中出现的次数,只考虑出不出现(这种就是假设词是等权重的);一种基于多项式模型实现:它考虑词在文档中出现的次数。这两种方法在准备数据时,分别有两种实现方式,一种是词条向量模型,一种是词袋模型

词集模型的python实现

从文本中构建词向量

首先我们先要知道下什么叫词条向量?一个词条是字符的任意组合,把每一个文本片段表示为一个词条向量,其中值为1表示词条出现在文档中,0表示词条未出现(这里假设每个词条都是同等重要的)。
###从词向量中计算概率
伪代码如下:

训练代码如下:

def trainNB0(trainMatrix,trainCategory):numTrainDocs = len(trainMatrix)numWords = len(trainMatrix[0])pAbusive = sum(trainCategory)/float(numTrainDocs)p0Num = ones(numWords); p1Num = ones(numWords)      #change to ones() p0Denom = 2.0; p1Denom = 2.0                        #change to 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 = log(p1Num/p1Denom)          #change to log()p0Vect = log(p0Num/p0Denom)          #change to log()return p0Vect,p1Vect,pAbusive

分类代码如下:

def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):p1 = sum(vec2Classify * p1Vec) + log(pClass1)    #element-wise multp0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)if p1 > p0:return 1else: return 0

词袋模型的python实现

前面我们将每个词出现与否作为一个特征,也就是词集模型。如果一个词在文档中出现不止一次,这可能意味着包含该词是否出现在文档中所不能表达的某种信息,这种方法被称为词袋模型。在词袋中每个单词可以出现多次,而在词集中,每个单词只能出现一次。两者在代码实现上的唯一区别就是词袋模型每当遇到一个单词时,它会增加词向量中的对应值,而不是只将对应数值设为1。

实际应用–使用朴素贝叶斯来从CSDN博客中获取博客主文章特征分析

我们接下来将使用两位博主的文章来训练一个分类器,然后观察分类器的效果。我们的目的并不是使用该分类器进行分类,而是通过观察单词和条件概率值来发现与特定博主相关的内容。

收集数据:导入RSS源

CSDN (Chinese Software Developer Network) 创立于1999年,是中国最大的IT社区和服务平台,为中国的软件开发者和IT从业者提供知识传播、职业发展、软件开发等全生命周期服务,满足他们在职业发展中学习及共享知识和信息、建立职业发展社交圈、通过软件开发实现技术商业化等刚性需求。博主OraYang的博客及博主j_shine的博客均支持RSS订阅。

import feedparser
ora = feedparser.parse('http://blog.csdn.net/u010665216/rss/list')
lujie = feedparser.parse('http://blog.csdn.net/j_shine/rss/list')

构造RSS源分类器

def localWords(feed1,feed0):import feedparserdocList=[]; classList = []; fullText =[]minLen = min(len(feed1['entries']),len(feed0['entries']))for i in range(minLen):wordList = textParse(feed1['entries'][i]['summary'])docList.append(wordList)fullText.extend(wordList)classList.append(1) #NY is class 1wordList = textParse(feed0['entries'][i]['summary'])docList.append(wordList)fullText.extend(wordList)classList.append(0)vocabList = createVocabList(docList)#create vocabularytop30Words = calcMostFreq(vocabList,fullText)   #remove top 30 wordsfor pairW in top30Words:if pairW[0] in vocabList: vocabList.remove(pairW[0])trainingSet = list(range(2*minLen)); testSet=[]           #create test setfor i in range(20):randIndex = int(random.uniform(0,len(trainingSet)))testSet.append(trainingSet[randIndex])del(trainingSet[randIndex])  trainMat=[]; trainClasses = []for docIndex in trainingSet:#train the classifier (get probs) trainNB0trainMat.append(bagOfWords2VecMN(vocabList, docList[docIndex]))trainClasses.append(classList[docIndex])p0V,p1V,pSpam = trainNB0(array(trainMat),array(trainClasses))errorCount = 0for docIndex in testSet:        #classify the remaining itemswordVector = bagOfWords2VecMN(vocabList, docList[docIndex])if classifyNB(array(wordVector),p0V,p1V,pSpam) != classList[docIndex]:errorCount += 1print('the error rate is: ',float(errorCount)/len(testSet))return vocabList,p0V,p1V

显示最具表征性的单词

def getTopWords(ny,sf):import operatorvocabList,p0V,p1V=localWords(ny,sf)topNY=[]; topSF=[]for i in range(len(p0V)):if p0V[i] > -6.5 : topSF.append((vocabList[i],p0V[i]))if p1V[i] > -6.5 : topNY.append((vocabList[i],p1V[i]))sortedSF = sorted(topSF, key=lambda pair: pair[1], reverse=True)print("Lujie***********************************************************************************************************Lujie")for item in sortedSF:print(item[0])sortedNY = sorted(topNY, key=lambda pair: pair[1], reverse=True)print("Ora*****************************************************************************************************************Ora")for item in sortedNY:print(item[0])

实验结果显示


从显示结果的单词中很容易看到两位博主的侧重点不同,J_shine博文偏向于java后台相关的内容,OraYang则偏向于python、机器学习、基础算法。

总结

本篇博文分享的贝叶斯概率及贝叶斯准则提供了一种利用已知值来估计未知概率的有效方法。文中提到的,条件独立性假设,可以降低对数据量的要求。在计算条件概率时还会遇到下溢出的问题,此时可以用取对数的方法解决。词袋模型比词集模型在解决文档分类的问题上效果更优。最后我们使用RSS源分析中,还可以通过移除停用词来进一步优化咱们的结果(代码中没实现),但让我感觉最重要的还是需要对读取RSS源并对文本进行切分进行大量优化,这是提高分类器效果的重要点。本文还有一个点没有提到,就是当算出的概率值为0时,一般采用“拉普拉斯修正”来对数据进行平滑处理(分子加1,分母加类别可能数)。

基于概率论的分类方法:朴素贝叶斯及CSDN_RSS源分析相关推荐

  1. 基于概率论的分类方法—朴素贝叶斯

    基于概率论的分类方法-朴素贝叶斯 转载于:https://www.cnblogs.com/liuys635/p/11181304.html

  2. 《机器学习实战》学习笔记(四):基于概率论的分类方法 - 朴素贝叶斯

    欢迎关注WX公众号:[程序员管小亮] [机器学习]<机器学习实战>读书笔记及代码 总目录 https://blog.csdn.net/TeFuirnever/article/details ...

  3. 基于概率论的分类方法: 朴素贝叶斯

    朴素贝叶斯 概述 贝叶斯分类是一类分类算法的总称,这类算法均以贝叶斯定理为基础,故统称为贝叶斯分类.本章首先介绍贝叶斯分类算法的基础--贝叶斯定理.最后,我们通过实例来讨论贝叶斯分类的中最简单的一种: ...

  4. 机器学习实战教程(三):基于概率论的分类方法——朴素贝叶斯

    文章目录 一.朴素贝叶斯理论 1.贝叶斯决策理论 2.条件概率 3.全概率公式 4.贝叶斯推断 5.朴素贝叶斯推断 二.示例:言论过滤器 三.朴素贝叶斯改进之拉普拉斯平滑 四.示例:朴素贝叶斯之过滤垃 ...

  5. 《机器学习实战》笔记(04):基于概率论的分类方法 - 朴素贝叶斯分类

    基于概率论的分类方法:朴素贝叶斯分类 Naive Bayesian classification 这大节内容源于带你理解朴素贝叶斯分类算法,并非源于<机器学习实战>.个人认为<机器学 ...

  6. 机器学习实战之基于概率论的分类方法:朴素贝叶斯

    基于概率论的分类方法:朴素贝叶斯 引入 1 基于贝叶斯决策理论的分类方法 1.1 条件概率 1.2 使用条件概率来分类 1.3 使用朴素贝叶斯进行文档分类 2 使用Python进行文本分类 2.1 准 ...

  7. 机器学习监督学习之分类算法---朴素贝叶斯理论知识

    感谢Jack-Cui大佬的知识分享 机器学习专栏点击这里 目录 感谢Jack-Cui大佬的知识分享 0. 概述 1. 朴素贝叶斯理论 1.1 贝叶斯理论 1.1.1 相关计算公式:条件概率公式,贝叶斯 ...

  8. Machine Learning in Action 读书笔记---第4章 基于概率论的分类方法:朴素贝叶斯

    Machine Learning in Action 读书笔记 第4章 基于概率论的分类方法:朴素贝叶斯 文章目录 Machine Learning in Action 读书笔记 一.基于贝叶斯决策理 ...

  9. 情感分类与朴素贝叶斯

    本文介绍一种机器学习分类算法--朴素贝叶斯算法及其在NLP中的应用.具体实现部分可参考朴素贝叶斯用于情感分类的实现 NLP中的分类 许多自然语言处理任务涉及分类,分类也是人类和机器智能的核心. 文本分 ...

最新文章

  1. 如何更改应用在app store的名称
  2. 广西国际商务职业技术学院官网计算机功课,2019—2020学年秋季学期线上线下混合式教学课程听课情况汇报...
  3. 新鲜出炉的百度js面试题
  4. 查看 php yii脚本位置,Yii框架分析(一)入口脚本index.php的启动过程剖析
  5. 交互式数据可视化的优势
  6. linux 自动清理var log,Linux 系统 /var/log/journal/ 垃圾日志清理-Fun言
  7. gaussian软件linux版本,Gaussian 09的版本与平台。
  8. 常见物理性能测试仪器设备档案
  9. GCN与图谱理论(三):图的谱分析与图傅里叶变换
  10. 云南省计算机考研排名,考研云南有哪些大学排名
  11. Justinmind使用教程(5)——Justinmind破解
  12. 使用postman测试图片上传
  13. 牛排生熟程度 英语说法
  14. 8分钟带你彻底弄懂《信号与系统》
  15. java面试笔记整理
  16. PYNQ-Z2零基础学习详解
  17. 老铁们来区分函数和宏定义的速度了哈!
  18. 电商网站秒杀和抢购的高并发技术实现和优化
  19. 子域名收集原理与子域名爆破工具
  20. 聊一聊SLAP:单一抽象层级原则

热门文章

  1. 计算机网络——不同网段下的主机通信
  2. Gazebo机器人仿真
  3. STM32初学——OLED调试4-1 5-1/5-2
  4. 2019年的最后一天,你会想些啥?
  5. 2.4G与5GWiFi频段的区别
  6. MSSQL数据导入导出Excel的相关代码
  7. 软考高级信息系统项目管理师0介绍
  8. 获取发表论文期刊的封面和目录页
  9. 来自天堂的魔鬼用计算机伴奏,来自天堂的魔鬼(伴奏)
  10. 猿创征文|基于Java+SpringBoot+vue学生学习平台详细设计实现