zoukankan      html  css  js  c++  java
  • 机器学习经典算法之朴素贝叶斯分类

    很多人都听说过贝叶斯原理,在哪听说过?基本上是在学概率统计的时候知道的。有些人可能会说,我记不住这些概率论的公式,没关系,我尽量用通俗易懂的语言进行讲解。

    /*请尊重作者劳动成果,转载请标明原文链接:*/

    /* https://www.cnblogs.com/jpcflyer/p/11069659.html  * /

    贝叶斯原理是英国数学家托马斯·贝叶斯提出的。贝叶斯是个很神奇的人,他的经历类似梵高。生前没有得到重视,死后,他写的一篇关于归纳推理的论文被朋友翻了出来,并发表了。这一发表不要紧,结果这篇论文的思想直接影响了接下来两个多世纪的统计学,是科学史上著名的论文之一。
    贝叶斯原理跟我们的生活联系非常紧密。举个例子,如果你看到一个人总是花钱,那么会推断这个人多半是个有钱人。当然这也不是绝对,也就是说,当你不能准确预知一个事物本质的时候,你可以依靠和事物本质相关的事件来进行判断,如果事情发生的频次多,则证明这个属性更有可能存在。    
     
    一、 贝叶斯原理
    贝叶斯原理是怎么来的呢?贝叶斯为了解决一个叫“逆向概率”问题写了一篇文章,尝试解答在没有太多可靠证据的情况下,怎样做出更符合数学逻辑的推测。
     
    什么是“逆向概率”呢?
    所谓“逆向概率”是相对“正向概率”而言。正向概率的问题很容易理解,比如我们已经知道袋子里面有 N 个球,不是黑球就是白球,其中 M 个是黑球,那么把手伸进去摸一个球,就能知道摸出黑球的概率是多少。但这种情况往往是上帝视角,即了解了事情的全貌再做判断。
    在现实生活中,我们很难知道事情的全貌。贝叶斯则从实际场景出发,提了一个问题:如果我们事先不知道袋子里面黑球和白球的比例,而是通过我们摸出来的球的颜色,能判断出袋子里面黑白球的比例么?
    正是这样的一个问题,影响了接下来近 200 年的统计学理论。这是因为,贝叶斯原理与其他统计学推断方法截然不同,它是建立在主观判断的基础上:在我们不了解所有客观事实的情况下,同样可以先估计一个值,然后根据实际结果不断进行修正。
    我们用一个题目来体会下:假设有一种病叫做“贝叶死”,它的发病率是万分之一,即 10000 人中会有 1 个人得病。现有一种测试可以检验一个人是否得病的准确率是 99.9%,它的误报率是 0.1%,那么现在的问题是,如果一个人被查出来患有“叶贝死”,实际上患有的可能性有多大?
    你可能会想说,既然查出患有“贝叶死”的准确率是 99.9%,那是不是实际上患“贝叶死”的概率也是 99.9% 呢?实际上不是的。你自己想想,在 10000 个人中,还存在 0.1% 的误查的情况,也就是 10 个人没有患病但是被诊断成阳性。当然 10000 个人中,也确实存在一个患有贝叶死的人,他有 99.9% 的概率被检查出来。所以你可以粗算下,患病的这个人实际上是这 11 个人里面的一员,即实际患病比例是 1/11≈9%。
    上面这个例子中,实际上涉及到了贝叶斯原理中的几个概念:
     
    先验概率
    通过经验来判断事情发生的概率,比如说“贝叶死”的发病率是万分之一,就是先验概率。再比如南方的梅雨季是 6-7 月,就是通过往年的气候总结出来的经验,这个时候下雨的概率就比其他时间高出很多。
     
    后验概率
    后验概率就是发生结果之后,推测原因的概率。比如说某人查出来了患有“贝叶死”,那么患病的原因可能是 A、B 或 C。患有“贝叶死”是因为原因 A 的概率就是后验概率。它是属于条件概率的一种。
     
    条件概率
    事件 A 在另外一个事件 B 已经发生条件下的发生概率,表示为 P(A|B),读作“在 B 发生的条件下 A 发生的概率”。比如原因 A 的条件下,患有“贝叶死”的概率,就是条件概率。
     
    似然函数(likelihood function)
    你可以把概率模型的训练过程理解为求参数估计的过程。举个例子,如果一个硬币在 10 次抛落中正面均朝上。那么你肯定在想,这个硬币是均匀的可能性是多少?这里硬币均匀就是个参数,似然函数就是用来衡量这个模型的参数。似然在这里就是可能性的意思,它是关于统计参数的函数。
    介绍完贝叶斯原理中的这几个概念,我们再来看下贝叶斯原理,实际上贝叶斯原理就是求解后验概率,我们假设:A 表示事件 “测出为阳性”, 用 B1 表示“患有贝叶死”, B2 表示“没有患贝叶死”。根据上面那道题,我们可以得到下面的信息。
    患有贝叶死的情况下,测出为阳性的概率为 P(A|B1)=99.9%,没有患贝叶死,但测出为阳性的概率为 P(A|B2)=0.1%。另外患有贝叶死的概率为 P(B1)=0.01%,没有患贝叶死的概率 P(B2)=99.99%。
    那么我们检测出来为阳性,而且是贝叶死的概率 P(B1,A)=P(B1)*P(A|B1)=0.01%*99.9%=0.00999%。
    这里 P(B1,A) 代表的是联合概率,同样我们可以求得 P(B2,A)=P(B2)*P(A|B2)=99.99%*0.1%=0.09999%。
    然后我们想求得是检查为阳性的情况下,患有贝叶死的概率,也即是 P(B1|A)。
    所以检查出阳性,且患有贝叶死的概率为:
    检查出是阳性,但没有患有贝叶死的概率为:
    这里我们能看出来 0.01%+0.1% 均出现在了 P(B1|A) 和 P(B2|A) 的计算中作为分母。我们把它称之为论据因子,也相当于一个权值因子。
    其中 P(B1)、P(B2) 就是先验概率,我们现在知道了观测值,就是被检测出来是阳性,来求患贝叶死的概率,也就是求后验概率。求后验概率就是贝叶斯原理要求的,基于刚才求得的 P(B1|A),P(B2|A),我们可以总结出贝叶斯公式为:
    由此,我们可以得出通用的贝叶斯公式:
     
     
     
    朴素贝叶斯
    讲完贝叶斯原理之后,我们再来看下今天重点要讲的算法,朴素贝叶斯。 它是一种简单但极为强大的预测建模算法 。之所以称为朴素贝叶斯,是因为它假设每个输入变量是独立的。这是一个强硬的假设,实际情况并不一定,但是这项技术对于绝大部分的复杂问题仍然非常有效。
     
    朴素贝叶斯模型由两种类型的概率组成:
    每个 类别的概率 P(Cj);
    每个属性的 条件概率 P(Ai|Cj)。
     
    我来举个例子说明下什么是类别概率和条件概率。假设我有 7 个棋子,其中 3 个是白色的,4 个是黑色的。那么棋子是白色的概率就是 3/7,黑色的概率就是 4/7,这个就是类别概率。
    假设我把这 7 个棋子放到了两个盒子里,其中盒子 A 里面有 2 个白棋,2 个黑棋;盒子 B 里面有 1 个白棋,2 个黑棋。那么在盒子 A 中抓到白棋的概率就是 1/2,抓到黑棋的概率也是 1/2,这个就是条件概率,也就是在某个条件(比如在盒子 A 中)下的概率。
    在朴素贝叶斯中,我们要统计的是属性的条件概率,也就是假设取出来的是白色的棋子,那么它属于盒子 A 的概率是 2/3。
    为了训练朴素贝叶斯模型,我们需要先给出训练数据,以及这些数据对应的分类。那么上面这两个概率,也就是类别概率和条件概率。他们都可以从给出的训练数据中计算出来。一旦计算出来,概率模型就可以使用贝叶斯原理对新数据进行预测。
     
    另外我想告诉你的是,贝叶斯原理、贝叶斯分类和朴素贝叶斯这三者之间是有区别的。
    贝叶斯原理是最大的概念,它解决了概率论中“逆向概率”的问题,在这个理论基础上,人们设计出了贝叶斯分类器,朴素贝叶斯分类是贝叶斯分类器中的一种,也是最简单,最常用的分类器。朴素贝叶斯之所以朴素是因为它假设属性是相互独立的,因此对实际情况有所约束,如果属性之间存在关联,分类准确率会降低。不过好在对于大部分情况下,朴素贝叶斯的分类效果都不错。
     
     
    二、 朴素贝叶斯分类工作原理
    朴素贝叶斯分类是常用的贝叶斯分类方法。我们日常生活中看到一个陌生人,要做的第一件事情就是判断 TA 的性别,判断性别的过程就是一个分类的过程。根据以往的经验,我们通常会从身高、体重、鞋码、头发长短、服饰、声音等角度进行判断。这里的“经验”就是一个训练好的关于性别判断的模型,其训练数据是日常中遇到的各式各样的人,以及这些人实际的性别数据。
     
    离散数据案例
    我们遇到的数据可以分为两种,一种是离散数据,另一种是连续数据。那什么是离散数据呢?离散就是不连续的意思,有明确的边界,比如整数 1,2,3 就是离散数据,而 1 到 3 之间的任何数,就是连续数据,它可以取在这个区间里的任何数值。
    我以下面的数据为例,这些是根据你之前的经验所获得的数据。然后给你一个新的数据:身高“高”、体重“中”,鞋码“中”,请问这个人是男还是女?
    针对这个问题,我们先确定一共有 3 个属性,假设我们用 A 代表属性,用 A1, A2, A3 分别为身高 = 高、体重 = 中、鞋码 = 中。一共有两个类别,假设用 C 代表类别,那么 C1,C2 分别是:男、女,在未知的情况下我们用 Cj 表示。
    那么我们想求在 A1、A2、A3 属性下,Cj 的概率,用条件概率表示就是 P(Cj|A1A2A3)。根据上面讲的贝叶斯的公式,我们可以得出:
    因为一共有 2 个类别,所以我们只需要求得 P(C1|A1A2A3) 和 P(C2|A1A2A3) 的概率即可,然后比较下哪个分类的可能性大,就是哪个分类结果。
    在这个公式里,因为 P(A1A2A3) 都是固定的,我们想要寻找使得 P(Cj|A1A2A3) 的最大值,就等价于求 P(A1A2A3|Cj)P(Cj) 最大值。
    我们假定 Ai 之间是相互独立的,那么: P(A1A2A3|Cj)=P(A1|Cj)P(A2|Cj)P(A3|Cj)
    然后我们需要从 Ai 和 Cj 中计算出 P(Ai|Cj) 的概率,带入到上面的公式得出 P(A1A2A3|Cj),最后找到使得 P(A1A2A3|Cj) 最大的类别 Cj。
    我分别求下这些条件下的概率:
    P(A1|C1)=1/2, P(A2|C1)=1/2, P(A3|C1)=1/4,P(A1|C2)=0, P(A2|C2)=1/2, P(A3|C2)=1/2,所以 P(A1A2A3|C1)=1/16, P(A1A2A3|C2)=0。
    因为 P(A1A2A3|C1)P(C1)>P(A1A2A3|C2)P(C2),所以应该是 C1 类别,即男性。
     
    连续数据案例
    实际生活中我们得到的是连续的数值,比如下面这组数据:
    那么如果给你一个新的数据,身高 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 时,函数结果为概率密度。
    这里我们使用的是 NORMDIST(180,179.5,3.697,0)=0.1069。
    同理我们可以计算得出男性体重为 120 的概率为 0.000382324,男性鞋码为 41 号的概率为 0.120304111。
    所以我们可以计算得出:
    P(A1A2A3|C1)=P(A1|C1)P(A2|C1)P(A3|C1)=0.1069*0.000382324* 0.120304111=4.9169e-6
    同理我们也可以计算出来该人为女的可能性:
    P(A1A2A3|C2)=P(A1|C2)P(A2|C2)P(A3|C2)=0.00000147489* 0.015354144* 0.120306074=2.7244e-9
    很明显这组数据分类为男的概率大于分类为女的概率。
    当然在 Python 中,有第三方库可以直接帮我们进行上面的操作,这个我们会在下文中介绍。这里主要是给你讲解下具体的运算原理。
     
    三、朴素贝叶斯分类器工作流程
    朴素贝叶斯分类常用于文本分类,尤其是对于英文等语言来说,分类效果很好。它常用于垃圾文本过滤、情感预测、推荐系统等。
    朴素贝叶斯分类器需要三个流程,我来给你一一讲解下这几个流程。
    第一阶段:准备阶段
    在这个阶段我们需要确定特征属性,比如上面案例中的“身高”、“体重”、“鞋码”等,并对每个特征属性进行适当划分,然后由人工对一部分数据进行分类,形成训练样本。
    这一阶段是整个朴素贝叶斯分类中唯一需要人工完成的阶段,其质量对整个过程将有重要影响,分类器的质量很大程度上由特征属性、特征属性划分及训练样本质量决定。
    第二阶段:训练阶段
    这个阶段就是生成分类器,主要工作是计算每个类别在训练样本中的出现频率及每个特征属性划分对每个类别的条件概率。
    输入是特征属性和训练样本,输出是分类器。
    第三阶段:应用阶段
    这个阶段是使用分类器对新数据进行分类。输入是分类器和新数据,输出是新数据的分类结果。
    好了,在这次课中你了解了概率论中的贝叶斯原理,朴素贝叶斯的工作原理和工作流程,也对朴素贝叶斯的强大和限制有了认识。下一节中,我将带你实战,亲自掌握 Python 中关于朴素贝叶斯分类器工具的使用。
     
    四、 sklearn 机器学习包
    接下来带你一起使用朴素贝叶斯做下文档分类的项目,最重要的工具就是 sklearn 这个机器学习神器。
    sklearn 的全称叫 Scikit-learn,它给我们提供了 3 个朴素贝叶斯分类算法,分别是高斯朴素贝叶斯(GaussianNB)、多项式朴素贝叶斯(MultinomialNB)和伯努利朴素贝叶斯(BernoulliNB)。
     
    这三种算法适合应用在不同的场景下,我们应该根据特征变量的不同选择不同的算法:
    高斯朴素贝叶斯 :特征变量是连续变量,符合高斯分布,比如说人的身高,物体的长度。
    多项式朴素贝叶斯 :特征变量是离散变量,符合多项分布,在文档分类中特征变量体现在一个单词出现的次数,或者是单词的 TF-IDF 值等。
    伯努利朴素贝叶斯 :特征变量是布尔变量,符合 0/1 分布,在文档分类中特征是单词是否出现。
    伯努利朴素贝叶斯是以文件为粒度,如果该单词在某文件中出现了即为 1,否则为 0。而多项式朴素贝叶斯是以单词为粒度,会计算在某个文件中的具体次数。而高斯朴素贝叶斯适合处理特征变量是连续变量,且符合正态分布(高斯分布)的情况。比如身高、体重这种自然界的现象就比较适合用高斯朴素贝叶斯来处理。而文本分类是使用多项式朴素贝叶斯或者伯努利朴素贝叶斯。
     
    什么是 TF-IDF 值呢?
    我在多项式朴素贝叶斯中提到了“词的 TF-IDF 值”,如何理解这个概念呢?
    TF-IDF 是一个统计方法,用来评估某个词语对于一个文件集或文档库中的其中一份文件的重要程度。
    TF-IDF 实际上是两个词组 Term Frequency 和 Inverse Document Frequency 的总称,两者缩写为 TF 和 IDF,分别代表了词频和逆向文档频率
    词频 TF 计算了一个单词在文档中出现的次数,它认为一个单词的重要性和它在文档中出现的次数呈正比。
    逆向文档频率 IDF ,是指一个单词在文档中的区分度。它认为一个单词出现在的文档数越少,就越能通过这个单词把该文档和其他文档区分开。IDF 越大就代表该单词的区分度越大。
    所以 TF-IDF 实际上是词频 TF 和逆向文档频率 IDF 的乘积 。这样我们倾向于找到 TF 和 IDF 取值都高的单词作为区分,即这个单词在一个文档中出现的次数多,同时又很少出现在其他文档中。这样的单词适合用于分类。
    TF-IDF 如何计算
    首先我们看下词频 TF 和逆向文档概率 IDF 的公式。
    为什么 IDF 的分母中,单词出现的文档数要加 1 呢?因为有些单词可能不会存在文档中,为了避免分母为 0,统一给单词出现的文档数都加 1。
    TF-IDF=TF*IDF。
    你可以看到,TF-IDF 值就是 TF 与 IDF 的乘积, 这样可以更准确地对文档进行分类。比如“我”这样的高频单词,虽然 TF 词频高,但是 IDF 值很低,整体的 TF-IDF 也不高。
    我在这里举个例子。假设一个文件夹里一共有 10 篇文档,其中一篇文档有 1000 个单词,“this”这个单词出现 20 次,“bayes”出现了 5 次。“this”在所有文档中均出现过,而“bayes”只在 2 篇文档中出现过。我们来计算一下这两个词语的 TF-IDF 值。
    针对“this”,计算 TF-IDF 值:
    所以 TF-IDF=0.02*(-0.0414)=-8.28e-4。
    针对“bayes”,计算 TF-IDF 值:
     
    很明显“bayes”的 TF-IDF 值要大于“this”的 TF-IDF 值。这就说明用“bayes”这个单词做区分比单词“this”要好。
    如何求 TF-IDF
    在 sklearn 中我们直接使用 TfidfVectorizer 类,它可以帮我们计算单词 TF-IDF 向量的值。在这个类中,取 sklearn 计算的对数 log 时,底数是 e,不是 10。
    下面我来讲下如何创建 TfidfVectorizer 类。
    TfidfVectorizer 类的创建:
    创建 TfidfVectorizer 的方法是:
    1 TfidfVectorizer(stop_words=stop_words, token_pattern=token_pattern)
    我们在创建的时候,有两个构造参数,可以自定义停用词 stop_words 和规律规则 token_pattern。需要注意的是传递的数据结构,停用词 stop_words 是一个列表 List 类型,而过滤规则 token_pattern 是正则表达式。
    什么是停用词?停用词就是在分类中没有用的词,这些词一般词频 TF 高,但是 IDF 很低,起不到分类的作用。为了节省空间和计算时间,我们把这些词作为停用词 stop words,告诉机器这些词不需要帮我计算。
    当我们创建好 TF-IDF 向量类型时,可以用 fit_transform 帮我们计算,返回给我们文本矩阵,该矩阵表示了每个单词在每个文档中的 TF-IDF 值。
    在我们进行 fit_transform 拟合模型后,我们可以得到更多的 TF-IDF 向量属性,比如,我们可以得到词汇的对应关系(字典类型)和向量的 IDF 值,当然也可以获取设置的停用词 stop_words。
    举个例子,假设我们有 4 个文档:
    文档 1:this is the bayes document;
    文档 2:this is the second second document;
    文档 3:and the third one;
    文档 4:is this the document。
    现在想要计算文档里都有哪些单词,这些单词在不同文档中的 TF-IDF 值是多少呢?
    首先我们创建 TfidfVectorizer 类:
    1 from sklearn.feature_extraction.text import TfidfVectorizer
    2 tfidf_vec = TfidfVectorizer()
    然后我们创建 4 个文档的列表 documents,并让创建好的 tfidf_vec 对 documents 进行拟合,得到 TF-IDF 矩阵:
    1 documents = [
    2     'this is the bayes document',
    3     'this is the second second document',
    4     'and the third one',
    5     'is this the document'
    6 ]
    7 tfidf_matrix = tfidf_vec.fit_transform(documents)
    输出文档中所有不重复的词:
    1 print('不重复的词:', tfidf_vec.get_feature_names())

    运行结果

    1 不重复的词: ['and', 'bayes', 'document', 'is', 'one', 'second', 'the', 'third', 'this']
    输出每个单词对应的 id 值:
    1 print('每个单词的 ID:', tfidf_vec.vocabulary_)
    运行结果
    1 每个单词的 ID: {'this': 8, 'is': 3, 'the': 6, 'bayes': 1, 'document': 2, 'second': 5, 'and': 0, 'third': 7, 'one': 4}
    输出每个单词在每个文档中的 TF-IDF 值,向量里的顺序是按照词语的 id 顺序来的:
    1 print('每个单词的 tfidf 值:', tfidf_matrix.toarray())
    运行结果:
    1 每个单词的 tfidf 值: [[0.         0.63314609 0.40412895 0.40412895 0.         0.
    2   0.33040189 0.         0.40412895]
    3 [0.         0.         0.27230147 0.27230147 0.         0.85322574
    4   0.22262429 0.         0.27230147]
    5 [0.55280532 0.         0.         0.         0.55280532 0.
    6   0.28847675 0.55280532 0.        ]
    7 [0.         0.         0.52210862 0.52210862 0.         0.
    8   0.42685801 0.         0.52210862]]
     
    五、 如何对文档进行分类
    如果我们要对文档进行分类,有两个重要的阶段:
    1.基于分词的数据准备 ,包括分词、单词权重计算、去掉停用词;
    2.应用朴素贝叶斯分类进行分类 ,首先通过训练集得到朴素贝叶斯分类器,然后将分类器应用于测试集,并与实际结果做对比,最终得到测试集的分类准确率。
    下面,我分别对这些模块进行介绍。
     
    模块 1:对文档进行分词
    在准备阶段里,最重要的就是分词。那么如果给文档进行分词呢?英文文档和中文文档所使用的分词工具不同。
    在英文文档中,最常用的是 NTLK 包。NTLK 包中包含了英文的停用词 stop words、分词和标注方法。
    1 import nltk
    2 word_list = nltk.word_tokenize(text) # 分词
    3 nltk.pos_tag(word_list) # 标注单词的词性
    在中文文档中,最常用的是 jieba 包。jieba 包中包含了中文的停用词 stop words 和分词方法。
    import jieba
    word_list = jieba.cut (text) # 中文分词
     
    模块 2:加载停用词表
    我们需要自己读取停用词表文件,从网上可以找到中文常用的停用词保存在 stop_words.txt,然后利用 Python 的文件读取函数读取文件,保存在 stop_words 数组中。
    1 stop_words = [line.strip().decode('utf-8') for line in io.open('stop_words.txt').readlines()]
     
    模块 3:计算单词的权重
    这里我们用到 sklearn 里的 TfidfVectorizer 类,上面我们介绍过它使用的方法。
    直接创建 TfidfVectorizer 类,然后使用 fit_transform 方法进行拟合,得到 TF-IDF 特征空间 features,你可以理解为选出来的分词就是特征。我们计算这些特征在文档上的特征向量,得到特征空间 features。
    1 tf = TfidfVectorizer(stop_words=stop_words, max_df=0.5)
    2 features = tf.fit_transform(train_contents)
    这里 max_df 参数用来描述单词在文档中的最高出现率。假设 max_df=0.5,代表一个单词在 50% 的文档中都出现过了,那么它只携带了非常少的信息,因此就不作为分词统计。
    一般很少设置 min_df,因为 min_df 通常都会很小。
     
    模块 4:生成朴素贝叶斯分类器
    我们将特征训练集的特征空间 train_features,以及训练集对应的分类 train_labels 传递给贝叶斯分类器 clf,它会自动生成一个符合特征空间和对应分类的分类器。
    这里我们采用的是多项式贝叶斯分类器,其中 alpha 为平滑参数。为什么要使用平滑呢?因为如果一个单词在训练样本中没有出现,这个单词的概率就会被计算为 0。但训练集样本只是整体的抽样情况,我们不能因为一个事件没有观察到,就认为整个事件的概率为 0。为了解决这个问题,我们需要做平滑处理。
    当 alpha=1 时,使用的是 Laplace 平滑。Laplace 平滑就是采用加 1 的方式,来统计没有出现过的单词的概率。这样当训练样本很大的时候,加 1 得到的概率变化可以忽略不计,也同时避免了零概率的问题。
    当 0<alpha<1 时,使用的是 Lidstone 平滑。对于 Lidstone 平滑来说,alpha 越小,迭代次数越多,精度越高。我们可以设置 alpha 为 0.001。
    # 多项式贝叶斯分类器
    1 from sklearn.naive_bayes import MultinomialNB  
    2 clf = MultinomialNB(alpha=0.001).fit(train_features, train_labels)
     
    模块 5:使用生成的分类器做预测
    首先我们需要得到测试集的特征矩阵。
    方法是用训练集的分词创建一个 TfidfVectorizer 类,使用同样的 stop_words 和 max_df,然后用这个 TfidfVectorizer 类对测试集的内容进行 fit_transform 拟合,得到测试集的特征矩阵 test_features。
    1 test_tf = TfidfVectorizer(stop_words=stop_words, max_df=0.5, vocabulary=train_vocabulary)
    2 test_features=test_tf.fit_transform(test_contents)
     
    然后我们用训练好的分类器对新数据做预测。
    方法是使用 predict 函数,传入测试集的特征矩阵 test_features,得到分类结果 predicted_labels。predict 函数做的工作就是求解所有后验概率并找出最大的那个。
    1 predicted_labels=clf.predict(test_features)
     
    模块 6:计算准确率
    计算准确率实际上是对分类模型的评估。我们可以调用 sklearn 中的 metrics 包,在 metrics 中提供了 accuracy_score 函数,方便我们对实际结果和预测的结果做对比,给出模型的准确率。
    使用方法如下:
    1 from sklearn import metrics
    2 print metrics.accuracy_score(test_labels, predicted_labels)
     
    搜索关注微信公众号“程序员姜小白”,获取更新精彩内容哦。
  • 相关阅读:
    WCF 第八章 安全 确定替代身份(中)使用AzMan认证
    WCF 第八章 安全 总结
    WCF 第八章 安全 因特网上的安全服务(下) 其他认证模式
    WCF Membership Provider
    WCF 第八章 安全 确定替代身份(下)模仿用户
    WCF 第八章 安全 因特网上的安全服务(上)
    WCF 第九章 诊断
    HTTPS的七个误解(转载)
    WCF 第八章 安全 日志和审计
    基于比较的排序算法集
  • 原文地址:https://www.cnblogs.com/jpcflyer/p/11069659.html
Copyright © 2011-2022 走看看