Naive Bayes
概率和统计里有哪些需要掌握的概念?
- 随机变量(Random Variable)来描述事件所有可能出现的状态
- 离散型随机变量(Discrete Random Variable)
- 连续型随机变量(Continuous Random Variable)
- 概率分布(Probability Distribution)来描述每个状态出现的可能性
- 联合概率(Joint Probability)
- 边缘概率(Marginal Probability)
- 条件概率
说了这么多,不知道你有没有一种感觉,其实概率论研究的就是这些概率之间相互转化的关系,比如联合概率、条件概率和边缘概率。通过这些关系,概率论中产生了著名的贝叶斯定理(Bayes’ theorem)。加上变量的独立性,我们就可以构建**朴素贝叶斯(Naive Bayes)**分类算法。
此外,基于概率发展而来的信息论,提出了很多重要的概率,例如**信息熵(Entropy)、香农熵(Shannon Entropy)、信息增益(Information Gain)、基尼指数(Gini)等。这些概念都被运用到了决策树(Decision Tree)**的算法中。
通过这些概念之间的相互推导,我们可以得到贝叶斯定理,这是朴素贝叶斯等系列算法的核心。而在概率基础之上发展而来的信息论,定义了信息熵、信息增益和基尼指数等,构成了决策树等系列算法的核心。
概率研究的是模型如何产生数据,统计研究的是如何通过数据来推导其背后的模型。所以说,概率和统计其实是互逆的。
概率和统计可以帮我们做什么?
- 第一,概率可以帮助我们进行更精准的复杂度分析;
- 第二,概率统计更多的是用在机器学习和大数据分析中;
- 第三,概率统计还可以用在各种机器学习的算法中。
离散 & 连续
随机变量根据其取值是否连续,可分为离散型随机变量和连续型随机变量。举几个例子,抛硬币出现正反面的次数以及每周下雨的天数,都是离散的值,所以对应的随机变量为离散型。而汽车每小时行驶的速度和银行排队的时间,都是连续的值,对应的随机变量为连续型。换句话,从计算的角度来说,我们可以直接求和得出的,就是“离散的”,需要用积分计算的,就是“连续的”。
概率分布
- 离散
抛硬币事件来看
离散分布模型:常用的离散分布有伯努利分布、分类分布、二项分布、泊松分布
- 连续
汽车每小时行驶的公里数
连续分布模型:比较经典的连续分布有正态分布、均匀分布、指数分布、拉普拉斯分布
期望值
期望值,也叫数学期望,是每次随机结果的出现概率乘以其结果的总和。如果我们把每种结果的概率看作权重,那么期望值就是所有结果的加权平均值。它在我们的生活中十分常见,例如计算多个数值的平均值,其实就是求期望值,只不过我们假设每个数值出现的概率是相同的。
在我看来,一个问题只要满足两个要素,我们就可以考虑使用期望值:
- 第一个要素,在这个问题中可能出现不同的情况,而且各种情况的出现满足了一定的概率分布;
- 第二个要素,每种情况都对应一个数值,这个数值代表了具体的应用含义。
那么,对于连续型的随机变量,这种期望值应该如何计算呢?我们需要使用下面的积分公式:
面积
联合概率、条件概率和边缘概率
解释清楚了条件概率,我就可以列出概率、条件概率和联合概率之间的“三角”关系了。简单的说,联合概率是条件概率和概率的乘积,采用通用的公式来表达就是:
贝叶斯定理
这就是非常经典的贝叶斯法则。为什么说经典呢?是因为它有很多应用的场景,比如朴素贝叶斯,你可以多多熟悉一下这个公式。在这个公式中,还包含了先验概率(Prior Probability)、似然函数(Likelihood)、边缘概率(Marginal Probability)和后验概率(Posterior Probability)的概念。
在这里面,我们把 P(x) 称为先验概率。之所以称为“先验”,是因为它是从数据资料统计得到的,不需要经过贝叶斯定理的推算。
P(y | x) 是给定 x 之后 y 出现的条件概率。在统计学中,我们也把 P(y | x) 写作似然函数 L(x | y)。在数学里,似然函数和概率是有区别的。概率是指已经知道模型的参数来预测结果,而似然函数是根据观测到的结果数据,来预估模型的参数。不过,当 y 值给定的时候,两者在数值上是相等的,在应用中我们可以不用细究。
另外,我们没有必要事先知道 P(y)。P(y) 可以通过联合概率 P(x, y) 计算边缘概率得来,而联合概率 P(x, y) 可以由 P(y|x) * P(x) 推出。针对离散型和连续型的边缘概率推导分别如下:
最主要的应用场景:通过先验概率,推导出后验概率,这就是贝叶斯定理神奇的地方。
随机变量之间的独立性
说到多个随机变量的联合和条件概率,你可能会产生一个问题:这些随机变量是否会相互影响呢?比如,性别和分数之间有怎样的关系?性别是否会影响分数的概率分布?
相互独立会产生一些有趣的现象,刚刚我们提到:
另外,将 p(x | y) = p(x) 带入贝叶斯公式,就可以得出:
如何将原始信息转化为计算机能看懂的数据?
最常用的方式就是提取现实世界中的对象之属性,并将这些转化为数字。
朴素贝叶斯的核心思想
贝叶斯定理的核心思想:用先验概率和条件概率估计后验概率
那具体到这里的分类问题,我们该如何运用这个公式呢?为了便于理解,我们可以将上述公式改写成这样:
其中,c 表示一个分类(class),f 表示属性对应的数据字段(field)。如此一来,等号左边的 P(c|f) 就是待分类样本中,出现属性值 f 时,样本属于类别 c 的概率。而等号右边的 P(f|c) 是根据训练数据统计,得到分类 c 中出现属性 f 的概率。P©是分类 c 在训练数据中出现的概率,P(f) 是属性 f 在训练样本中出现的概率。
看到这里,你可能要问了,这里的贝叶斯公式只描述了单个属性值属于某个分类的概率,可是我们要分析的水果每个都有很多属性啊,这该怎么办呢?
别急,朴素贝叶斯在这里就要发挥作用了。这是基于一个简单假设建立的一种贝叶斯方法,并假定数据对象的不同属性对其归类影响时是相互独立的。此时若数据对象 o 中同时出现属性 fi 与 fj,则对象 o 属于类别 c 的概率就是这样:
对于出现的 0.00 概率,在做贝叶斯公式中的乘积计算时,会出现结果为 0 的情况,因此我们通常取一个比这个数据集里最小统计概率还要小的极小值,来代替“零概率”。比如,我们这里取 0.01。在填充训练数据中从来没有出现过的属性值的时候,我们就会使用这种技巧,我们给这种技巧起个名字就叫作平滑(Smoothing)。
你可能已经注意到了,这几个公式里的概率乘积通常都非常小,在物品的属性非常多的时候,这个乘积可能就小到计算机无法处理的地步。因此,在实际运用中,我们还会采用一些数学手法进行转换(比如取 log 将小数转换为绝对值大于 1 的负数),原理都是一样的。
内容比较多,我稍微总结一下。朴素贝叶斯分类主要包括这几个步骤:
- 准备数据:针对水果分类这个案例,我们收集了若干水果的实例,并从水果的常见属性入手,将其转化为计算机所能理解的数据。这种数据也被称为训练样本。
- 建立模型:通过手头上水果的实例,我们让计算机统计每种水果、属性出现的先验概率,以及在某个水果分类下某种属性出现的条件概率。这个过程也被称为基于样本的训练。
- 分类新数据:对于一颗新水果的属性数据,计算机根据已经建立的模型进行推导计算,得到该水果属于每个分类的概率,实现了分类的目的。这个过程也被称为预测。
通用的贝叶斯公式
朴素贝叶斯
它是一种简单但极为强大的预测建模算法。
之所以称为朴素贝叶斯,是因为它假设每个输入变量是独立的。这是一个强硬的假设,实际情况并不一定,但是这项技术对于绝大部分的复杂问题仍然非常有效。
朴素贝叶斯模型由两种类型的概率组成:
- 每个类别的概率P(Cj);
假设我有 7 个棋子,其中 3 个是白色的,4 个是黑色的。那么棋子是白色的概率就是 3/7,黑色的概率就是 4/7,这个就是类别概率。
- 每个属性的条件概率P(Ai|Cj)。
假设我把这 7 个棋子放到了两个盒子里,其中盒子 A 里面有 2 个白棋,2 个黑棋;盒子 B 里面有 1 个白棋,2 个黑棋。那么在盒子 A 中抓到白棋的概率就是 1/2,抓到黑棋的概率也是 1/2,这个就是条件概率,也就是在某个条件(比如在盒子 A 中)下的概率。
在朴素贝叶斯中,我们要统计的是属性的条件概率,也就是假设取出来的是白色的棋子,那么它属于盒子 A 的概率是 2/3。
为了训练朴素贝叶斯模型,我们需要先给出训练数据,以及这些数据对应的分类。那么上面这两个概率,也就是类别概率和条件概率。他们都可以从给出的训练数据中计算出来。一旦计算出来,概率模型就可以使用贝叶斯原理对新数据进行预测。
另外我想告诉你的是,贝叶斯原理、贝叶斯分类和朴素贝叶斯这三者之间是有区别的。
贝叶斯原理是最大的概念,它解决了概率论中“逆向概率”的问题,在这个理论基础上,人们设计出了贝叶斯分类器,朴素贝叶斯分类是贝叶斯分类器中的一种,也是最简单,最常用的分类器。朴素贝叶斯之所以朴素是因为它假设属性是相互独立的,因此对实际情况有所约束,如果属性之间存在关联,分类准确率会降低。不过好在对于大部分情况下,朴素贝叶斯的分类效果都不错。
朴素贝叶斯分类工作原理
朴素贝叶斯分类是常用的贝叶斯分类方法。我们日常生活中看到一个陌生人,要做的第一件事情就是判断 TA 的性别,判断性别的过程就是一个分类的过程。根据以往的经验,我们通常会从身高、体重、鞋码、头发长短、服饰、声音等角度进行判断。这里的“经验”就是一个训练好的关于性别判断的模型,其训练数据是日常中遇到的各式各样的人,以及这些人实际的性别数据。
- 离散数据案例
针对这个问题,我们先确定一共有 3 个属性,假设我们用 A 代表属性,用 A1, A2, A3 分别为身高 = 高、体重 = 中、鞋码 = 中。一共有两个类别,假设用 C 代表类别,那么 C1,C2 分别是:男、女,在未知的情况下我们用 Cj 表示。
那么我们想求在 A1、A2、A3 属性下,Cj 的概率,用条件概率表示就是 P(Cj|A1A2A3)。根据上面讲的贝叶斯的公式,我们可以得出:
- 连续数据案例
那么如果给你一个新的数据,身高 180、体重 120,鞋码 41,请问该人是男是女呢?
这时,可以假设男性和女性的身高、体重、鞋码都是正态分布,通过样本计算出均值和方差,也就是得到正态分布的密度函数。有了密度函数,就可以把值代入,算出某一点的密度函数的值。比如,男性的身高是均值 179.5、标准差为 3.697 的正态分布。所以男性的身高为 180 的概率为 0.1069。怎么计算得出的呢? 你可以使用 EXCEL 的 NORMDIST(x,mean,standard_dev,cumulative) 函数,一共有 4 个参数:
- x:正态分布中,需要计算的数值;
- Mean:正态分布的平均值;
- Standard_dev:正态分布的标准差;
- Cumulative:取值为逻辑值,即 False 或 True。它决定了函数的形式。当为 TRUE 时,函数结果为累积分布;为 False 时,函数结果为概率密度。
朴素贝叶斯分类器工作流程
朴素贝叶斯分类 VS 其他分类算法
- 和KNN 最近邻相比,朴素贝叶斯需要更多的时间进行模型的训练,但是它在对新的数据进行分类预测的时候,通常效果更好、用时更短。
- 和决策树相比,朴素贝叶斯并不能提供一套易于人类理解的规则,但是它可以提供决策树通常无法支持的模糊分类(一个对象可以属于多个分类)。
- 和SVM 支持向量机相比,朴素贝叶斯无法直接支持连续值的输入。所以,在前面的案例中,我将连续值转化成了离散值,便于朴素贝叶斯进行处理。
朴素贝叶斯的应用场景
如果一个分类的应用场景中,待分类对象的属性值大部分都是离散的(或者很容易转化为离散的)、需要支持模糊分类,并且需要快速可靠的实时分类,那么这种场景通常就非常适合使用朴素贝叶斯方法。
朴素贝叶斯分类最适合的场景就是文本分类、情感分析和垃圾邮件识别。其中情感分析和垃圾邮件识别都是通过文本来进行判断。从这里你能看出来,这三个场景本质上都是文本分类,这也是朴素贝叶斯最擅长的地方。所以朴素贝叶斯也常用于自然语言处理 NLP 的工具。
文本分类系统的基本框架
基于自然语言的预处理
和之前的水果案例相比,新闻这种文本数据最大的区别在于,它包含了大量的自然语言。那么如何让计算机理解自然语言呢?我们的计算机体系没有思维,要理解人类的语言在现阶段是不现实的。但是,我们仍然可以对自然语言进行适当的处理,将其变为机器所能处理的数据。
首先,我们要知道,文本的的重要属性是什么,这样我们才能提取出它的特征。怎么才能知道哪些属性是重要的呢?
我举个例子,假如说,有人给你一篇几千字的文章,让你在 10 秒钟之内说出文章大意,你会怎么办?我想大部分人的解决方案是“找关键词”!没错,我们也可以交给计算机用同样的办法。而计算机处理文本的基本单位就是字和单词,这就是人们最常用的方法:词袋(Bag of words)模型。
这种模型会忽略文本中的词语出现的顺序以及相应的语法,将整篇文章仅仅看做是一个大量单词的组合。文本中每个词的出现都是独立的,不依赖于其他词的出现情况。讲到这里,你有没有发现在词包模型中,所有单词相互之间是独立的,这个假设和朴素贝叶斯模型的独立假设是不是一致呀?
没错!这里我们就可以很巧妙地将朴素贝叶斯和文本处理结合起来了。不过先不要急,我们还要掌握一些方法,才能将文本中的长篇大论处理成关键词。
- 分词
介绍两种目前比较主流的分词模型,你只需要了解就行。
第一种是基于字符串匹配。其实就是扫描字符串。如果发现字符串的子串和词相同,就算匹配成功。匹配规则通常是“正向最大匹配”“逆向最大匹配”“长词优先”。这些算法的优点是只需使用基于字典的匹配,因此计算复杂度低;缺点是处理歧义词效果不佳。
第二种是基于统计和机器学习。这类分词基于人工标注的词性和统计特征,对中文进行建模。训练阶段,根据标注好的语料对模型参数进行估计。 在分词阶段再通过模型计算各种分词出现的概率,将概率最大的分词作为最终结果。常见的序列标注模型有隐马尔科夫模型(HMM,Hidden Markov Model)和条件随机场(CRF,Conditional Random Field),我们后面章节会讲到,这里我先不展开。
- 取词干和归一化
我们刚才说了,相对中文而言,英文完全不需要考虑分词。不过它也有中文不具有的单复数、各种时态,因此它需要考虑取词干(stemming)。取词干的目标就是为了减少词的变化形式,将派生词转化为基本形式。
最后,我们还要考虑大小写转化和多种拼写(例如 color 和 colour)这样的统一化,我们把这种做法称为归一化。
- 停用词
无论何种语言,都会存在一些不影响(或基本不影响)相关性的词。有的时候干脆可以指定一个叫停用词(stop word)的字典,直接将这些词过滤,不予以考虑。例如英文中的 a、an、the、that、is、good、bad 等。中文“的、个、你、我、他、好、坏”等。
如此一来,我们可以在基本不损失语义的情况下,减少数据文件的大小,提高计算机处理的效率。当然,也要注意停用词的使用场景,例如用户观点分析,good 和 bad 这样的形容词反而成为了关键。不仅不能过滤,反而要加大它们的权重。
- 同义词和扩展词
不同的地域或者不同时代,会导致人们对于同样的物品叫法也不同。例如,在中国北方“番茄“应该叫“西红柿”,而*地区将“菠萝”称为“凤梨”。对于计算机而言,需要意识到这两个词是等价的。添加同义词就是一个很好的手段。
有了这样的词典,当看到文本中出现“番茄”关键词的时候,计算机系统就会将其等同于“西红柿”这个词。有的时候我们还需要扩展词。如果简单地将 Dove 分别和多芬、德芙简单地等价,那么多芬和德芙这两个完全不同的品牌也变成了同义词,这样做明显是有问题的。那么我们可以采用扩展关系,当系统看到文本中的“多芬”时将其等同于“Dove”,看到“德芙”时将其等同于“Dove”。但是看到“Dove”的时候并不将其等同于“多芬”或“德芙”。
通过词包模型的假设,以及上述这些自然语言处理的方法,我们可以将整篇的文字,切分为一个个的单词,这些是表示文章的关键属性。你不难发现,每个单词可以作为文章的属性,而通过这些单词的词频(出现的频率),我们很容易进行概率的统计。下面我对分类的先验概率、单词的先验概率、某个分类下某个单词的条件概率分别给出了示例。
如果发现某些单词从未在某个分类中出现,例如“航母”这个词从未在“体育”和“娱乐”这两个分类中出现。对于这种情况,我们可以使用平滑(smoothing)的技术,将其词频或条件概率设置为一个极小的值。这里,我设置了最小的词频,也就是 1。
运用朴素贝叶斯模型
在新闻分类中,o 就表示一篇文章,而c表示新闻的种类(包括政治、军事、财经等等)。而属性字段f就是我们从文档集而建立的各种单词。公式等号左边的 P(c|f) 就是待分类新闻中,出现单词 f 时,该新闻属于类别 c 的概率。而等号右边的 P(f|c) 是根据训练数据统计,得到分类 c 中出现单词 f 的概率。P( c ) 是分类 c 在新闻训练数据中出现的概率,P(f) 是单词 f 在训练样本中出现的概率。
这里需要注意一个很实际的问题:文章的篇幅很长,常常会导致非常多的 P(f|c) 连续乘积。而 P(f|c) 通常是非常小的数值,因此最后的乘积将快速趋近于 0 以至于计算机无法识别。这里可以使用我们之前提到的一些数学手法进行转换,比如取 log,将小数转换为绝对值大于 1 的负数。这样的转换,虽然会改变每篇文章属于每个分类的概率之绝对值,但是并不会改变这些概率的相对大小。
sklearn 机器学习包
sklearn 的全称叫 Scikit-learn,它给我们提供了 3 个朴素贝叶斯分类算法,分别是
- 高斯朴素贝叶斯(GaussianNB)
- 多项式朴素贝叶斯(MultinomialNB)
- 伯努利朴素贝叶斯(BernoulliNB)
这三种算法适合应用在不同的场景下,我们应该根据特征变量的不同选择不同的算法:
- 高斯朴素贝叶斯:特征变量是连续变量,符合高斯分布,比如说人的身高,物体的长度。
- 多项式朴素贝叶斯:特征变量是离散变量,符合多项分布,在文档分类中特征变量体现在一个单词出现的次数,或者是单词的 TF-IDF 值等。
- 伯努利朴素贝叶斯:特征变量是布尔变量,符合 0/1 分布,在文档分类中特征是单词是否出现。
伯努利朴素贝叶斯是以文件为粒度,如果该单词在某文件中出现了即为 1,否则为 0。而多项式朴素贝叶斯是以单词为粒度,会计算在某个文件中的具体次数。而高斯朴素贝叶斯适合处理特征变量是连续变量,且符合正态分布(高斯分布)的情况。比如身高、体重这种自然界的现象就比较适合用高斯朴素贝叶斯来处理。而文本分类是使用多项式朴素贝叶斯或者伯努利朴素贝叶斯。
什么是 TF-IDF 值呢?
TF-IDF 是一个统计方法,用来评估某个词语对于一个文件集或文档库中的其中一份文件的重要程度。
词频 TF:计算了一个单词在文档中出现的次数,它认为一个单词的重要性和它在文档中出现的次数呈正比。
逆向文档频率 IDF:指一个单词在文档中的区分度。它认为一个单词出现在的文档数越少,就越能通过这个单词把该文档和其他文档区分开。IDF 越大就代表该单词的区分度越大。
所以 TF-IDF 实际上是词频 TF 和逆向文档频率 IDF 的乘积。这样我们倾向于找到 TF 和 IDF 取值都高的单词作为区分,即这个单词在一个文档中出现的次数多,同时又很少出现在其他文档中。这样的单词适合用于分类。
TF-IDF 如何计算
为什么 IDF 的分母中,单词出现的文档数要加 1 呢?因为有些单词可能不会存在文档中,为了避免分母为 0,统一给单词出现的文档数都加 1。
TF-IDF=TF*IDF。
如何求 TF-IDF
在 sklearn 中我们直接使用 TfidfVectorizer 类,它可以帮我们计算单词 TF-IDF 向量的值。在这个类中,取 sklearn 计算的对数 log 时,底数是 e,不是 10。
什么是停用词?停用词就是在分类中没有用的词,这些词一般词频 TF 高,但是 IDF 很低,起不到分类的作用。为了节省空间和计算时间,我们把这些词作为停用词 stop words,告诉机器这些词不需要帮我计算。
如何对文档进行分类
- 基于分词的数据准备:包括分词、单词权重计算、去掉停用词;
- 应用朴素贝叶斯分类进行分类:首先通过训练集得到朴素贝叶斯分类器,然后将分类器应用于测试集,并与实际结果做对比,最终得到测试集的分类准确率。
数据挖掘神器 sklearn
从数据挖掘的流程来看,一般包括了获取数据、数据清洗、模型训练、模型评估和模型部署这几个过程。
sklearn 中包含了大量的数据挖掘算法,比如三种朴素贝叶斯算法,我们只需要了解不同算法的适用条件,以及创建时所需的参数,就可以用模型帮我们进行训练。在模型评估中,sklearn 提供了 metrics 包,帮我们对预测结果与实际结果进行评估。
在文档分类的项目中,我们针对文档的特点,给出了基于分词的准备流程。一般来说 NTLK 包适用于英文文档,而 jieba 适用于中文文档。我们可以根据文档选择不同的包,对文档提取分词。这些分词就是贝叶斯分类中最重要的特征属性。基于这些分词,我们得到分词的权重,即特征矩阵。
通过特征矩阵与分类结果,我们就可以创建出朴素贝叶斯分类器,然后用分类器进行预测,最后预测结果与实际结果做对比即可以得到分类器在测试集上的准确率。
总结