精华内容
下载资源
问答
  • 朴素贝叶斯算法实例
    2018-10-30 18:01:00
     1 # -*- coding: utf-8 -*-
     2 """
     3 Created on Tue Oct 28 14:40:38 2018
     4 
     5 @author: zhen
     6 """
     7 from sklearn.datasets import fetch_20newsgroups
     8 from sklearn.model_selection import train_test_split
     9 from sklearn.feature_extraction.text import CountVectorizer
    10 from sklearn.naive_bayes import MultinomialNB
    11 from sklearn.metrics import classification_report
    12 # 数据获取
    13 news = fetch_20newsgroups(subset='all')
    14 
    15 # 数据预处理:分割训练集和测试集
    16 x_train, x_test, y_train, y_test = train_test_split(news.data, news.target, test_size=0.25, random_state=33)
    17 # 文本特征向量化
    18 vec = CountVectorizer()
    19 x_train = vec.fit_transform(x_train)
    20 x_test = vec.transform(x_test)
    21 
    22 # 使用朴素贝叶斯进行训练(多项式模型)
    23 mnb = MultinomialNB()
    24 mnb.fit(x_train, y_train)
    25 y_predict = mnb.predict(x_test)
    26 
    27 # 获取预测结果
    28 print(classification_report(y_test, y_predict, target_names = news.target_names))
    29 print("the accuracy of MultinomialNB is:", mnb.score(x_test, y_test))

    结果:

      

     

    转载于:https://www.cnblogs.com/yszd/p/9878491.html

    更多相关内容
  • 《机器学习》算法实例-朴素贝叶斯算法-屏蔽社区留言板的侮辱言论 构建一个快速过滤器来屏蔽在线社区留言板上的侮辱性言论。如果某条留言使用了负面或者侮辱性的语言,那么就将该留言标识为内容不当。对此问题建立两...
  • 用matlab实现的朴素贝叶斯算法,亲测可用。
  • 本文实例讲述了Python实现的朴素贝叶斯算法。分享给大家供大家参考,具体如下: 代码主要参考机器学习实战那本书,发现最近老外的书确实比中国人写的好,由浅入深,代码通俗易懂,不多说上代码: #encoding:utf-8 '...
  • (一)贝叶斯原理中的几个概念 先验概率 通过经验来判断事情发生的概率,比如说某一种疾病的发病率是万分之一,就是先验概率。再比如南方的梅雨季是 6-7 月,就是通过往年的气候总结出来的经验,这个时候下雨的...

    (一)贝叶斯原理中的几个概念

    1. 先验概率
      通过经验来判断事情发生的概率,比如说某一种疾病的发病率是万分之一,就是先验概率。再比如南方的梅雨季是 6-7 月,就是通过往年的气候总结出来的经验,这个时候下雨的概率就比其他时间高出很多。

    2. 后验概率
      后验概率就是发生结果之后,推测原因的概率。比如说某人查出来了患有“某种病”,那么患病的原因可能是 A、B 或 C。患有“某种病”是因为原因 A 的概率就是后验概率。它是属于条件概率的一种。

    3. 条件概率
      事件 A 在另外一个事件 B 已经发生条件下的发生概率,表示为 P(A|B),读作“在 B 发生的条件下 A 发生的概率”。比如原因 A 的条件下,患有“某种病”的概率,就是条件概率。

      求后验概率就是贝叶斯原理要求的

    (二)朴素贝叶斯

    它是一种简单但极为强大的预测建模算法。之所以称为朴素贝叶斯,是因为它假设每个输入变量是独立的。这是一个强硬的假设,实际情况并不一定,但是这项技术对于绝大部分的复杂问题仍然非常有效。

    朴素贝叶斯模型由两种类型的概率组成:

    1、每个类别的概率P(Cj);2、每个属性的条件概率P(Ai|Cj)。

    (三)朴素贝叶斯分类工作原理

    1. 离散数据
      问题:身高”高“,体重”中“,鞋码“中”,请问这个人是男是女?
      在这里插入图片描述
      由图可知,一共有三个属性,分别为:身高A1,体重A2,鞋码A3,两个类别,分别为:男性C1,女性C2。我们只需要求得P(C1|A1A2A3) 和 P(C2|A1A2A3) 的概率即可,然后比较下哪个分类的可能性大,就是哪个分类结果,等价于求 P(A1A2A3|Cj)P(Cj) 最大值。
      我们假定 Ai 之间是相互独立的,那么:P(A1A2A3|Cj)=P(A1|Cj)P(A2|Cj)P(A3|Cj)

    2. 连续数据

      问题:请问身高180,体重120,鞋码41,这个人是男还是女呢?
      在这里插入图片描述
      由于身高、体重、鞋码都是连续变量,不能采用离散变量的方法计算概率。可以假设男性和女性的身高、体重、鞋码都是正态分布,通过样本计算出均值方差,也就是得到正态分布的密度函数。有了密度函数,就可以把值代入,算出某一点的密度函数的值。比如,男性的身高是均值 179.5、标准差为 3.697 的正态分布。所以男性的身高为 180 的概率为 0.1069。怎么计算得出的呢? 你可以使用 EXCEL 的 NORMDIST(x,mean,standard_dev,cumulative) 函数,一共有 4 个参数:
      (1)x:正态分布中,需要计算的数值;
      (2)Mean:正态分布的平均值;
      (3)Standard_dev:正态分布的标准差;
      (4)Cumulative:取值为逻辑值,即 False 或 True。它决定了函数的形式。当为 TRUE 时,函数结果为累积分布;为 False 时,函数结果为概率密度。
      然后通过P(A1A2A3|Cj)=P(A1|Cj)P(A2|Cj)P(A3|Cj),比较C1,C2情况下的概率,哪个分类的可能性大,就是哪个分类结果。

    (四)贝叶斯原理,贝叶斯分类和朴素贝叶斯三者之间的区别

    贝叶斯原理是最大的概念,它解决了概率论中“逆向概率”的问题,在这个理论基础上,人们设计出了贝叶斯分类器,朴素贝叶斯分类是贝叶斯分类器中的一种,也是最简单,最常用的分类器。朴素贝叶斯之所以朴素是因为它假设属性是相互独立的,因此对实际情况有所约束,如果属性之间存在关联,分类准确率会降低。不过好在对于大部分情况下,朴素贝叶斯的分类效果都不错。
    在这里插入图片描述
    (五)朴素贝叶斯分类器工作流程
    在这里插入图片描述
    (六)朴素贝叶斯分类案例——对文档进行分类
    在这里插入图片描述
    项目概述:
    在这里插入图片描述

    1. 对文档进行分词,加载停用词
    # 中文文本分类
    import os
    import jieba
    import warnings
    from sklearn.feature_extraction.text import TfidfVectorizer
    from sklearn.naive_bayes import MultinomialNB
    from sklearn import metrics
    
    warnings.filterwarnings('ignore')
    
    def cut_words(file_path):
        """
        对文本进行切词
        :param file_path: txt文本路径
        :return: 用空格分词的字符串
        """
        text_with_spaces = ''
        text=open(file_path, 'r', encoding='gb18030').read()
        textcut = jieba.cut(text)
        for word in textcut:
            text_with_spaces += word + ' '
        return text_with_spaces
    
    def loadfile(file_dir, label):
        """
        将路径下的所有文件加载
        :param file_dir: 保存txt文件目录
        :param label: 文档标签
        :return: 分词后的文档列表和标签
        """
        file_list = os.listdir(file_dir)
        words_list = []
        labels_list = []
        for file in file_list:
            file_path = file_dir + '/' + file
            words_list.append(cut_words(file_path))
            labels_list.append(label)                                                                                                                 
        return words_list, labels_list
    
    # 训练数据
    train_words_list1, train_labels1 = loadfile('C:/Users/1/Downloads/text_classification-master/text_classification-master/text classification/train/女性', '女性')
    train_words_list2, train_labels2 = loadfile('C:/Users/1/Downloads/text_classification-master/text_classification-master/text classification/train/体育', '体育')
    train_words_list3, train_labels3 = loadfile('C:/Users/1/Downloads/text_classification-master/text_classification-master/text classification/train/文学', '文学')
    train_words_list4, train_labels4 = loadfile('C:/Users/1/Downloads/text_classification-master/text_classification-master/text classification/train/校园', '校园')
    
    train_words_list = train_words_list1 + train_words_list2 + train_words_list3 + train_words_list4
    train_labels = train_labels1 + train_labels2 + train_labels3 + train_labels4
    
    # 测试数据
    test_words_list1, test_labels1 = loadfile('C:/Users/1/Downloads/text_classification-master/text_classification-master/text classification/test/女性', '女性')
    test_words_list2, test_labels2 = loadfile('C:/Users/1/Downloads/text_classification-master/text_classification-master/text classification/test/体育', '体育')
    test_words_list3, test_labels3 = loadfile('C:/Users/1/Downloads/text_classification-master/text_classification-master/text classification/test/文学', '文学')
    test_words_list4, test_labels4 = loadfile('C:/Users/1/Downloads/text_classification-master/text_classification-master/text classification/test/校园', '校园')
    
    test_words_list = test_words_list1 + test_words_list2 + test_words_list3 + test_words_list4
    test_labels = test_labels1 + test_labels2 + test_labels3 + test_labels4
    
    #加载停用词表
    stop_words = open('C:/Users/1/Downloads/text_classification-master/text_classification-master/text classification/stop/stopword.txt', 'r', encoding='utf-8').read()
    stop_words = stop_words.encode('utf-8').decode('utf-8-sig') # 列表头部\ufeff处理
    stop_words = stop_words.split('\n') # 根据分隔符分隔
    
    
    1. 计算单词的权重
    # 计算单词权重
    tf = TfidfVectorizer(stop_words=stop_words, max_df=0.5)
    
    train_features = tf.fit_transform(train_words_list)
    test_features = tf.transform(test_words_list) 
    

    3.生成朴素贝叶斯分类器
    sklearn 的全称叫 Scikit-learn,它给我们提供了 3 个朴素贝叶斯分类算法,分别是高斯朴素贝叶斯(GaussianNB)、多项式朴素贝叶斯(MultinomialNB)和伯努利朴素贝叶斯(BernoulliNB)。这三种算法适合应用在不同的场景下,我们应该根据特征变量的不同选择不同的算法:高斯朴素贝叶斯:特征变量是连续变量,符合高斯分布,比如说人的身高,物体的长度。多项式朴素贝叶斯:特征变量是离散变量,符合多项分布,在文档分类中特征变量体现在一个单词出现的次数,或者是单词的 TF-IDF 值等。伯努利朴素贝叶斯:特征变量是布尔变量,符合 0/1 分布,在文档分类中特征是单词是否出现。

    # 多项式贝叶斯分类器
    from sklearn.naive_bayes import MultinomialNB  
    clf = MultinomialNB(alpha=0.001).fit(train_features, train_labels)
    

    4.分类器做预测

    predicted_labels=clf.predict(test_features)
    

    5.计算正确率

    print('准确率为:', metrics.accuracy_score(test_labels, predicted_labels))
    

    运算结果:

    准确率为: 0.91
    
    展开全文
  • 朴素贝叶斯算法 — 超详细公式讲解+代码实例

    万次阅读 多人点赞 2020-08-19 21:56:58
    朴素贝叶斯法是基于贝叶斯定理与特征条件独立性假设的分类方法。对于给定的训练集,首先基于特征条件独立假设学习输入输出的联合概率分布(朴素贝叶斯...学习朴素贝叶斯算法之前,我们先搞定下面这些基本概念和数学公式

    👔 朴素贝叶斯算法 Naive Bayes


    💡 思维导图

    1. 朴素贝叶斯法概述

    朴素贝叶斯法是基于贝叶斯定理与特征条件独立性假设的分类方法。对于给定的训练集,首先基于特征条件独立假设学习输入输出的联合概率分布(朴素贝叶斯法这种通过学习得到模型的机制,显然属于生成模型);然后基于此模型,对给定的输入 x,利用贝叶斯定理求出后验概率最大的输出 y。

    学习朴素贝叶斯算法之前,我们先搞定下面这些基本概念和数学公式 👇

    2. 朴素贝叶斯法的基本公式

    ① 联合概率分布

    联合概率表示为包含多个条件并且所有的条件都同时成立的概率,记作 P ( X = a , Y = b ) P(X=a,Y=b) P(X=a,Y=b) P ( a , b ) P(a,b) P(a,b) P ( a b ) P(ab) P(ab)

    联合概率分布就是联合概率在样本空间中的分布情况

    ② 条件概率 conditional probability

    有一个装了 7 块石头的罐子,其中 3 块是白色的,4 块是黑色的。如果从罐子中随机取出一块石头,那么是白色石头的可能性是多少?

    显然,取出白色石头的概率为 3/7 ,取到黑色石头的概率是 4/7 。我们使用 P(white) 来表示取到白色石头的概率,其概率值可以通过白色石头数目除以总的石头数目来得到。

    如果这 7 块石头如下图所示,放在两个桶中,那么上述概率应该如何计算

    要计算 P(white) 或者 P(black) ,显然,石头所在桶的信息是会改变结果的,这就是条件概率 conditional probability。假定计算的是从 B 桶取到白色石头的概率,这个概率可以记作 P(white|bucketB) ,我们称之为 “在已知石头出自 B 桶的条件下,取出白色石头的概率”。

    很容易得到,P(white|bucketA) 值为 2/4 ,P(white|bucketB) 的值为 1/3 。

    条件概率的计算公式如下:

    放到我们这个例子中来: P(white|bucketB) = P(white and bucketB) / P(bucketB)

    公式解读:

    • P(white|bucketB):在已知石头出自 B 桶的条件下,取出白色石头的概率
    • P(white and bucketB):取出 B 桶中 白色石头的概率 = 1 / 7
    • P(bucketB):取出 B 桶中石头的概率 3 / 7

    ④ 贝叶斯定理

    另外一种有效计算条件概率的方法称为贝叶斯定理。贝叶斯定理告诉我们如何交换条件概率中的条件与结果,即如果已知 P(X|Y),要求 P(Y|X):

    ⭐⭐⭐ P ( Y ∣ X ) = P ( X ∣ Y ) P ( Y ) P ( X ) P(Y|X) = \frac{P(X|Y) P(Y) } {P(X)} P(YX)=P(X)P(XY)P(Y)

    这里的每个概率都有其特定的名称:

    • P ( Y ) P(Y) P(Y)先验概率先验概率(prior probability)是指事情还没有发生,求这件事情发生的可能性的大小,是先验概率。它往往作为"由因求果"问题中的"因"出现。

    • P ( Y ∣ X ) P(Y|X) P(YX)后验概率后验概率是指事情已经发生,求这件事情发生的原因是由某个因素引起的可能性的大小。后验概率的计算要以先验概率为基础

    • P ( X ∣ Y ) P(X|Y) P(XY) :条件概率,又叫似然概率,一般是通过历史数据统计得到。一般不把它叫做先验概率,但从定义上也符合先验定义。

    ④ 朴素贝叶斯分类器

    朴素贝叶斯法通过训练数据集学习联合概率分布 P ( X , Y ) P(X,Y) P(X,Y),其实就是学习先验概率分布和条件概率分布:

    • 先验概率分布:

    • 条件概率分布:

    于是由条件概率公式 P ( X ∣ Y ) = P ( X , Y ) P ( Y ) P(X|Y) = \frac{P(X,Y)}{P(Y)} P(XY)=P(Y)P(X,Y) 可以求出联合概率分布 P ( X , Y ) P(X,Y) P(X,Y)

    💡 条件独立性假设就是各个特征之间互不影响,每个特征都是条件独立的。这一假设使得朴素贝叶斯法变得简单,但是有时候会牺牲一定的分类准确率。

    朴素贝叶斯法分类时,对给定的输入 x,通过上述学习到的模型计算后验概率分布 P ( Y = c k ∣ X = x ) P(Y = c_k|X = x) P(Y=ckX=x)将后验概率最大的类作为 x 的类的输出。后验概率根据贝叶斯定理进行计算:

    💡 对分母上的 P ( X = x ) P(X = x) P(X=x) 应用了全概率公式

    将条件独立性假设 4.3 带入上式:

    这就是朴素贝叶斯分类的基本公式 👆

    朴素贝叶斯分类器就是取后验概率最大时的分类:

    显然,上式中的分母对于所有类别来说都是一样的,对计算结果不会产生影响,所以,朴素贝叶斯分类器可以简化为:⭐⭐⭐

    其实朴素贝叶斯分类器的后验概率最大化等价于0-1损失函数时的期望风险最小化。

    3. 朴素贝叶斯算法

    朴素贝叶斯算法基于不同的概率估计方法具有不同的形式。概率估计方法有以下两种:

    • 极大似然估计
    • 贝叶斯估计

    ① 极大似然估计

    可以用极大似然估计法去估计相应的概率。

    • 先验概率 P ( Y = c k ) P(Y = c_k) P(Y=ck) 的极大似然估计是:

    • 设第 j 个特征 x ( j ) x^{(j)} x(j) 可能取值的集合为 a j 1 , a j 2 . . . . . . a j S j {a_{j1},a_{j2}......a_{jS_j}} aj1,aj2......ajSj S j S_j Sj 表示第 j 个特征可能取值有 S j S_j Sj 个。比如特征 1 可能取值有 2 个,则 S 1 = 2 S_1 = 2 S1=2),条件概率 P ( X ( j ) = a j l ∣ Y = c k ) P(X^{(j)} = a_{jl} | Y = c_k) P(X(j)=ajlY=ck) 的极大似然估计是:

      其中, x i ( j ) x_i^{(j)} xi(j) 表示第 i 个样本的第 j 个特征; a j l a_{jl} ajl 表示第 j 个特征可能取的第 l l l 个值(比如特征 1 可能取值有 2 个,则 l l l 可以为 1 或 2); I I I 为指示函数

    基于极大似然估计法,⭐ 朴素贝叶斯算法如下:

    💬 举个例子

    ② 贝叶斯估计

    用极大似然估计可能会出现所要估计的概率为 0 的情况,这会影响到后验概率的计算结果,使分类产生偏差。解决这一问题的方法是采用贝叶斯估计。

    • 条件概率的贝叶斯估计

      其中, λ ≥ 0 λ ≥ 0 λ0。当 λ = 0 λ = 0 λ=0 时就是极大似然估计。常取 λ = 1 λ = 1 λ=1,这时称为拉普拉斯平滑 Laplacian smoothing

    • 先验概率的贝叶斯估计

      K K K 的含义和 S j S_j Sj 相同,即表示分类的个数。

    💬 举个例子:数据同上例 4.1,按照拉普拉斯平滑估计概率:

    4. 实例:使用朴素贝叶斯算法辨别文档中的侮辱性词汇

    该实例来源于《机器学习实战》这本书,撸一遍《统计学习方法》后再看这本书上的算法,真的是豁然开朗 😎

    项目概述:使用朴素贝叶斯构建一个快速过滤器来屏蔽侮辱性文档。如果某篇文档使用了负面或者侮辱性的语言,那么就将该文档标识为侮辱性文档。对此问题建立两个类别: 侮辱类和非侮辱类,使用 1 和 0 分别表示。

    ① 将文本转换成 0-1 序列

    目的:我们需要把文档中的每个单词利用 0 和 1 来表示,这样方便我们进行处理

    首先手动输入文档数据集的,一个列表代表一篇文档:

    ② 利用极大似然估计计算条件概率和先验概率

    import numpy as np
    
    # 先验概率
    def trainNB0(trainMatrix, trainCategory):
        """
        Desc:
            返回每个类别对应的先验概率和条件概率
        Params:
            trainMatrix: 训练数据集,即各个文档对应的 0-1 序列
            trainCategory: 训练数据集的类别,即各个文档对应的分类
        Return:
            p0Vect: 去重词汇表中每个单词在侮辱性文档中出现的概率
            p1Vect:去重词汇表中每个单词在非侮辱性文档中出现的概率
        """
        numTrainDocs = len(trainMatrix) # 文件数
        numWords = len(trainMatrix[0]) # 单词数
        
        # 先验概率 👇
        pAbusive = sum(trainCategory) / float(numTrainDocs) # 侮辱性文件的出现概率,即 trainCategory 中所有 1 的个数(0 1 相加即得 1 的个数)
        
        
        # 条件概率 👇
        
        # (非)侮辱性单词在每个文件中出现的次数列表
        # 比如说 p0Num = [1,3,12,....] 表示第 2 个文档中出现了 3 次非侮辱词汇
        p0Num = np.zeros(numWords) # [0,0,0,.....] 非侮辱性单词在每个文件中出现的次数列表
        p1Num = np.zeros(numWords) # [0,0,0,.....] 侮辱性单词出在每个文件中出现的次数列表
        
        # (非)侮辱性单词在(非)侮辱性文档出现的总数
        p0Denom = 0.0 # 0 非侮辱性词汇在所有非侮辱的文档的出现总数
        p1Denom = 0.0 # 1 侮辱性词汇在所有侮辱性的文档的出现总数
        
        for i in range(numTrainDocs):
            # 是否是侮辱性文件
            if trainCategory[i] == 1:
                # 如果是侮辱性文件,对侮辱性文件的向量进行相加,表示在所有侮辱性文件中,去重词汇表中各个词汇出现的次数
                p1Num +=  trainMatrix[i]
                # 对向量中的所有元素进行求和,表示在所有侮辱性文件中,去重词汇表中所有词汇出现的次数之和
                p1Denom += sum(trainMatrix[i])
            else:
                # 如果是非侮辱性文件,对非侮辱性文件的向量进行相加,表示在所有非侮辱性文件中,去重词汇表中各个词汇出现的次数
                p0Num += trainMatrix[i]
                # 对向量中的所有元素进行求和,表示在所有非侮辱性文件中去重词汇表中所有词汇出现的次数之和
                p0Denom += sum(trainMatrix[i])
                
        # 在类别 1 即侮辱性文档的条件下,去重词汇表中每个单词出现的概率
        p1Vect = p1Num / p1Denom
        
        # 在类别 0 即非侮辱性文档的条件下,去重词汇表中每个单词出现的概率
        p0Vect = p0Num / p0Denom
        
        return pAbusive, p0Vect, p1Vect
    

    🏃‍ 测试代码:

    pAbusive, p0Vect, p1Vect = trainNB0(trainMat, classVec)
    

    😒 可以看到,基于极大似然估计的朴素贝叶斯算法的结果差强人意

    这是因为在利用基于极大似然估计的朴素贝叶斯分类器对文档进行分类时,要计算多个概率的乘积以获得文档属于某个类别的概率,比如计算 P ( X 1 ( 1 ) ∣ Y = 1 ) ∗ P ( X 1 ( 2 ) ∣ Y = 1 ) ∗ P ( X 1 ( 3 ) ∣ Y = 1 ) ∗ . . . . . . P(X^{(1)}_1|Y=1) * P(X^{(2)}_1|Y=1) * P(X^{(3)}_1|Y=1) *...... P(X1(1)Y=1)P(X1(2)Y=1)P(X1(3)Y=1)......如果其中一个概率值为 0,那么最后的乘积也为 0为降低这种影响,接下来我们采用贝叶斯估计对上述算法做一下微小的修改 👇

    ③ 利用贝叶斯估计优化算法

    基于拉普拉斯平滑(λ = 1),在条件概率的计算公式的分子分母上分别加上 λ 和 S j λ S_jλ Sjλ S j S_j Sj 表示分类的个数,此处只有两个分类,所以 S j = 2 S_j = 2 Sj=2

    即将条件概率和先验概率的分子初始化为 1,将分母初始化为 2 :

    # (非)侮辱性单词在每个文件中出现的次数列表
    # 比如说 p0Num = [1,3,12,....] 表示第 2 个文档中出现了 3 次非侮辱词汇
    p0Num = np.ones(numWords) # [1,1,1,.....] 非侮辱性单词在每个文件中出现的次数列表
    p1Num = np.ones(numWords) # [1,1,1,.....] 侮辱性单词出在每个文件中出现的次数列表
    
    # (非)侮辱性单词在(非)侮辱性文档出现的总数
    p0Denom = 2.0 # 0 非侮辱性词汇在所有非侮辱的文档的出现总数
    p1Denom = 2.0 # 1 侮辱性词汇在所有侮辱性的文档的出现总数
    

    OK,修改好之后我们再来运行一下:

    💡 p1Vect 中 第 11 个数值最大,即表示去重词汇表中第 11 个位置的单词即 stupid 是在侮辱性文档中出现概率最大的词:

    然而,至此,我们的代码仍然不是完美的,还需要解决一个问题:下溢出问题 👇

    ④ 解决下溢出问题

    🔺 下溢出问题:这是由于太多很小的数相乘造成的。比如计算乘积 P ( X 1 ( 1 ) ∣ Y = 1 ) ∗ P ( X 1 ( 2 ) ∣ Y = 1 ) ∗ P ( X 1 ( 3 ) ∣ Y = 1 ) ∗ . . . . . . P(X^{(1)}_1|Y=1) * P(X^{(2)}_1|Y=1) * P(X^{(3)}_1|Y=1) *...... P(X1(1)Y=1)P(X1(2)Y=1)P(X1(3)Y=1)...... 时,由于大部分因子都非常小,所以程序会下溢出或者得到不正确的答案。(😱 用 Python 尝试相乘许多很小的数,最后四舍五入后会得到 0)。

    💡 一种解决办法是对乘积取自然对数。在代数中有 ln(A * B) = ln(A) + ln(B), 于是通过求对数可以避免下溢出或者浮点数舍入导致的错误。同时,采用自然对数进行处理不会有任何损失。

    下图给出了函数 F(x)ln(F(x)) 的曲线。可以看出,它们在相同区域内同时增加或者减少,并且在相同点上取到极值。它们的取值虽然不同,但不影响最终结果。

    ✍ 继续修改代码如下:

    p1Vect = np.log(p1Num / p1Denom)
    p0Vect = np.log(p0Num / p0Denom)
    

    当然,这样获取到的条件概率就是对数形式,所以在接下来的朴素贝叶斯分类器中我们也要为其做相应的修改。

    🏃‍ 测试修改后的代码:

    OK,问题解决完毕,接下来就可以来构建完整的朴素贝叶斯分类器了 👇

    ⑤ 编写朴素贝叶斯分类器

    回顾一下朴素贝叶斯分类器:

    我们将其改写为对数形式:

    ✍ 朴素贝叶斯分类器的代码如下:

    # 朴素贝叶斯分类器
    def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
        """
        Desc:
            输入某篇文档的0-1序列 vec2Classify,输出该篇所属的类别(侮辱性文档 1,非侮辱性文档 0)
        Args:
            vec2Classify: 某篇文档的 0-1 序列
            p0Vec:在类别 0 即非侮辱性文档的条件下,去重词汇表中每个单词出现的概率(对数形式)
            p1Vec:在类别 1 即侮辱性文档的条件下,去重词汇表中每个单词出现的概率(对数形式)
            pClass1: 该篇文档是侮辱性文件的概率(先验概率),注意转换成对数形式
        Return:
            类别 1/0
        """
        p1 = sum(vec2Classify * p1Vec) + np.log(pClass1) 
        p0 = sum(vec2Classify * p0Vec) + np.log(1.0 - pClass1) 
        if p1 > p0:
            return 1
        else:
            return 0
    

    🏃‍ 测试分类器:

    # 测试朴素贝叶斯分类器
    def test(testDoc):
        """
        Args:
            testDoc: 测试文档
        """
        # 1. 加载数据集
        postingList, classVec = loadDataSet()
        # 2. 创建去重词汇表
        vocabList = createVocabList(postingList) # 去重后的词汇表
        # 3. 创建每篇文档对应的 0-1 序列
        trainMat = []
        for doc in postingList:
            trainMat.append(setOfWords2Vec(vocabList, doc))
        # 4. 计算条件概率和先验概率
        pAbusive, p0Vect, p1Vect = trainNB0(trainMat, classVec)
        # 5. 朴素贝叶斯分类器
        thisDoc = setOfWords2Vec(vocabList, testDoc) # 将测试文档转换成 0-1 序列
        print(testDoc, 'classified as: ', classifyNB(thisDoc, p0Vect, p1Vect, pAbusive))
    

    📚 References

    展开全文
  • 朴素贝叶斯算法&应用实例

    万次阅读 2019-01-28 08:56:24
    朴素贝叶斯中的朴素是指假设各个特征之间相互独立,不会互相影响,所以称为朴素贝叶斯。正是因为这个假设,使得算法的模型简单且容易理解,虽然牺牲了一点准确性,但是如果模型训练的好,也能得到不错的分类效果。 ...

    https://www.toutiao.com/a6650068891382841859/

     

    2019-01-24 22:23:40

    朴素贝叶斯

    朴素贝叶斯中的朴素是指假设各个特征之间相互独立,不会互相影响,所以称为朴素贝叶斯。正是因为这个假设,使得算法的模型简单且容易理解,虽然牺牲了一点准确性,但是如果模型训练的好,也能得到不错的分类效果。

    朴素贝叶斯算法&应用实例

     

    公式简单推导

    下面我们简单看一下公式的推导过程

    朴素贝叶斯算法&应用实例

     

    评测指标

    我们得出分类的结果后,怎么来评测我们训练的模型的好与不好呢?我们通常「准确度」「精确率」「召回率」这几个指标来进行判断模型的好坏。下边我们用一个简单的例子来说明这几个指标是怎么计算的。

    下面我们看一个表。

    朴素贝叶斯算法&应用实例

     

    表中表示实际上科技类的文章有 40 篇,财经类的有 30 篇,然而预测的结果科技类的有 35 篇,其中 30 篇预测正确了,有 5 篇预测错误了;预测结果财经类的有 35 篇,其中 25 篇预测正确了,10 篇预测错误了。

    • 准确度

    表示预测正确的文章数比上总的文章数:(30+25)/(40+30)=78%

    • 精确率

    表示每一类预测正确的数量比上预测的该类文章总数量,比如科技类精确率:30/(30+5)=85%

    • 召回率

    表示每一类预测正确的数量比上实际该类的总数量,比如科技类:30/40=75%

    应用实例

    上边我们已经了解了朴素贝叶斯公式及推导过程,下边我们来看一下在实际的新闻分类中的应用。

    元数据的准备,我们的元数据是网上找来的一些各类的新闻,这里为了简单,我们只选取了科技、财经和体育三类数量不等的新闻,并且都已知他们的类别。然后通过中文结巴分词

    对每篇新闻进行分词。这里我们用到的是gihub上的一个开源的python库,有兴趣的可以了解一下。

    下面我们来看一下代码的具体实现。

    首先我们先把汉字的文章转成每个词所对应的数字id的形式,方便我们后边的操作和计算。

    Convert.py

    import os
    import sys
    import random
    import re
    ​
    inputPath = sys.argv[1]
    outputFile = sys.argv[2]
    #训练集所占百分比
    trainPercent = 0.8
    wordDict = {}
    wordList = []
    ​
    trainOutputFile = open('%s.train' % outputFile, "w")
    testOutputFile = open('%s.test' % outputFile, "w")
    ​
    for fileName in os.listdir(inputPath):
     tag = 0
     if fileName.find('technology') != -1:
     tag = 1
     elif fileName.find('business') != -1:
     tag = 2
     elif fileName.find('sport') != -1:
     tag = 3
    ​
     outFile = trainOutputFile
     rd = random.random()
     if rd >= trainPercent:
     outFile = testOutputFile
    ​
     inputFile = open(inputPath+'/'+fileName, "r")
     content = inputFile.read().strip()
     content = content.decode('utf-8', 'ignore')
     content = content.replace('
    ', ' ')
     r1 = u'[a-zA-Z0-9’!"#$%&'()*+,-./:;<=>?@,。?★、…【】《》?“”‘’![\]^_`{|}~]+'
     content = re.sub(r1, '', content)
     outFile.write(str(tag)+' ')
     words = content.split(' ')
     for word in words:
     if word not in wordDict:
     wordList.append(word)
     wordDict[word] = len(wordList)
    ​
     outFile.write(str(wordDict[word]) + ' ')
    ​
     inputFile.close()
    ​
    trainOutputFile.close()
    testOutputFile.close()

    朴素贝叶斯实现过程

    NB.py

    #Usage:
    #Training: NB.py 1 TrainingDataFile ModelFile
    #Testing: NB.py 0 TestDataFile ModelFile OutFile
    ​
    import sys
    import os
    import math
    ​
    ​
    DefaultFreq = 0.1
    TrainingDataFile = "nb_data.train"
    ModelFile = "nb_data.model"
    TestDataFile = "nb_data.test"
    TestOutFile = "nb_data.out"
    ClassFeaDic = {}
    ClassFreq = {}
    WordDic = {}
    ClassFeaProb = {}
    ClassDefaultProb = {}
    ClassProb = {}
    ​
    #加载数据
    def LoadData():
     i =0
     infile = open(TrainingDataFile, 'r')
     sline = infile.readline().strip()
     while len(sline) > 0:
     pos = sline.find("#")
     if pos > 0:
     sline = sline[:pos].strip()
     words = sline.split(' ')
     if len(words) < 1:
     print("Format error!")
     break
     classid = int(words[0])
     if classid not in ClassFeaDic:
     ClassFeaDic[classid] = {}
     ClassFeaProb[classid] = {}
     ClassFreq[classid] = 0
     ClassFreq[classid] += 1
     words = words[1:]
     for word in words:
     if len(word) < 1:
     continue
     wid = int(word)
     if wid not in WordDic:
     WordDic[wid] = 1
     if wid not in ClassFeaDic[classid]:
     ClassFeaDic[classid][wid] = 1
     else:
     ClassFeaDic[classid][wid] += 1
     i += 1
     sline = infile.readline().strip()
     infile.close()
     print(i, "instances loaded!")
     print(len(ClassFreq), "classes!", len(WordDic), "words!")
    ​
    #计算模型
    def ComputeModel():
     sum = 0.0
     for freq in ClassFreq.values():
     sum += freq
     for classid in ClassFreq.keys():
     ClassProb[classid] = (float)(ClassFreq[classid])/(float)(sum)
     for classid in ClassFeaDic.keys():
     sum = 0.0
     for wid in ClassFeaDic[classid].keys():
     sum += ClassFeaDic[classid][wid]
     newsum = (float)(sum + 1)
     for wid in ClassFeaDic[classid].keys():
     ClassFeaProb[classid][wid] = (float)(ClassFeaDic[classid][wid]+DefaultFreq)/newsum
     ClassDefaultProb[classid] = (float)(DefaultFreq) / newsum
     return
    ​
    #保存模型
    def SaveModel():
     outfile = open(ModelFile, 'w')
     for classid in ClassFreq.keys():
     outfile.write(str(classid))
     outfile.write(' ')
     outfile.write(str(ClassProb[classid]))
     outfile.write(' ')
     outfile.write(str(ClassDefaultProb[classid]))
     outfile.write(' ' )
     outfile.write('
    ')
     for classid in ClassFeaDic.keys():
     for wid in ClassFeaDic[classid].keys():
     outfile.write(str(wid)+' '+str(ClassFeaProb[classid][wid]))
     outfile.write(' ')
     outfile.write('
    ')
     outfile.close()
    ​
    #加载模型
    def LoadModel():
     global WordDic
     WordDic = {}
     global ClassFeaProb
     ClassFeaProb = {}
     global ClassDefaultProb
     ClassDefaultProb = {}
     global ClassProb
     ClassProb = {}
     infile = open(ModelFile, 'r')
     sline = infile.readline().strip()
     items = sline.split(' ')
     if len(items) < 6:
     print("Model format error!")
     return
     i = 0
     while i < len(items):
     classid = int(items[i])
     ClassFeaProb[classid] = {}
     i += 1
     if i >= len(items):
     print("Model format error!")
     return
     ClassProb[classid] = float(items[i])
     i += 1
     if i >= len(items):
     print("Model format error!")
     return
     ClassDefaultProb[classid] = float(items[i])
     i += 1
     for classid in ClassProb.keys():
     sline = infile.readline().strip()
     items = sline.split(' ')
     i = 0
     while i < len(items):
     wid = int(items[i])
     if wid not in WordDic:
     WordDic[wid] = 1
     i += 1
     if i >= len(items):
     print("Model format error!")
     return
     ClassFeaProb[classid][wid] = float(items[i])
     i += 1
     infile.close()
     print(len(ClassProb), "classes!", len(WordDic), "words!")
    ​
    #预测类别
    def Predict():
     global WordDic
     global ClassFeaProb
     global ClassDefaultProb
     global ClassProb
    ​
     TrueLabelList = []
     PredLabelList = []
     i =0
     infile = open(TestDataFile, 'r')
     outfile = open(TestOutFile, 'w')
     sline = infile.readline().strip()
     scoreDic = {}
     iline = 0
     while len(sline) > 0:
     iline += 1
     if iline % 10 == 0:
     print(iline," lines finished!
    ")
     pos = sline.find("#")
     if pos > 0:
     sline = sline[:pos].strip()
     words = sline.split(' ')
     if len(words) < 1:
     print("Format error!")
     break
     classid = int(words[0])
     TrueLabelList.append(classid)
     words = words[1:]
     for classid in ClassProb.keys():
     scoreDic[classid] = math.log(ClassProb[classid])
     for word in words:
     if len(word) < 1:
     continue
     wid = int(word)
     if wid not in WordDic:
     continue
     for classid in ClassProb.keys():
     if wid not in ClassFeaProb[classid]:
     scoreDic[classid] += math.log(ClassDefaultProb[classid])
     else:
     scoreDic[classid] += math.log(ClassFeaProb[classid][wid])
     i += 1
     maxProb = max(scoreDic.values())
     for classid in scoreDic.keys():
     if scoreDic[classid] == maxProb:
     PredLabelList.append(classid)
     sline = infile.readline().strip()
     infile.close()
     outfile.close()
     print(len(PredLabelList),len(TrueLabelList))
     return TrueLabelList,PredLabelList
    ​
    #计算准确度
    def Evaluate(TrueList, PredList):
     accuracy = 0
     i = 0
     while i < len(TrueList):
     if TrueList[i] == PredList[i]:
     accuracy += 1
     i += 1
     accuracy = (float)(accuracy)/(float)(len(TrueList))
     print("Accuracy:",accuracy)
    ​
    #计算精确率和召回率
    def CalPreRec(TrueList,PredList,classid):
     correctNum = 0
     allNum = 0
     predNum = 0
     i = 0
     while i < len(TrueList):
     if TrueList[i] == classid:
     allNum += 1
     if PredList[i] == TrueList[i]:
     correctNum += 1
     if PredList[i] == classid:
     predNum += 1
     i += 1
     return (float)(correctNum)/(float)(predNum),(float)(correctNum)/(float)(allNum)
    ​
    #main framework
    if sys.argv[1] == '1':
     print("start training:")
     LoadData()
     ComputeModel()
     SaveModel()
    elif sys.argv[1] == '0':
     print("start testing:")
    ​
     LoadModel()
     TList,PList = Predict()
     i = 0
     outfile = open(TestOutFile, 'w')
     while i < len(TList):
     outfile.write(str(TList[i]))
     outfile.write(' ')
     outfile.write(str(PList[i]))
     outfile.write('
    ')
     i += 1
     outfile.close()
     Evaluate(TList,PList)
     for classid in ClassProb.keys():
     pre,rec = CalPreRec(TList, PList,classid)
     print("Precision and recall for Class",classid,":",pre,rec)
    else:
     print("Usage incorrect!")
    ​
    展开全文
  • 朴素贝叶斯分类算法简单实例

    千次阅读 2021-08-18 08:55:16
    这篇文章我尽可能用直白的话语总结一下我们学习会上讲到的朴素贝叶斯分类算法,希望有利于他人理解。 1 分类问题综述 对于分类问题,其实谁都不会陌生,日常生活中我们每天都进行着分类过程。例如,当你看到...
  • 主要为大家详细介绍了Python实现朴素贝叶斯算法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 本文实例讲述了朴素贝叶斯分类算法原理与Python实现与使用方法。分享给大家供大家参考,具体如下: 朴素贝叶斯分类算法 1、朴素贝叶斯分类算法原理 1.1、概述 贝叶斯分类算法是一大类分类算法的总称 贝叶斯分类算法...
  • 本节主要介绍数据挖掘中常见的分类方法决策树和朴素贝叶斯算法。 决策树算法 决策树(Decision Tree,DT)分类法是一个简单且广泛使用的分类技术。 决策树是一个树状预测模型,它是由结点和有向边组成的层次结构。...
  • 基于朴素贝叶斯分类器的文本分类算法 (C语言.txt 两个人吵架先说对不起的人并不是 认输了并不是原谅了他只是比对方更珍惜这份感情#include <stdio.h> #include <string.h> #include <direct.h> //_getcwd, _chdir) #...
  • 朴素贝叶斯算法以及案例

    千次阅读 2020-08-13 21:16:55
    朴素贝叶斯算法以及案例 大家好,我是W 这次给大家带来朴素贝叶斯算法,贝叶斯分类是一类分类算法的总称,其基础都是贝叶斯定理。要理解该算法就需要先理解其背后的概率知识,我会尽量详细地给大家讲解清楚。所以...
  • 朴素贝叶斯算法的代码实例实现(python)

    万次阅读 多人点赞 2018-09-12 09:41:32
    这个问题提出了预测之后的结果,而朴素贝叶斯正好可以满足这一点,网上大多是直接调用API进行预测,实际上最好还是自己实现朴素贝叶斯朴素贝叶斯公式:P(B|A)=P(A|B)P(B)/P(A),而本文中,公式即为,P(C|...
  • 本文实例为大家分享了Python朴素贝叶斯实例代码,供大家参考,具体内容如下 #-*- coding: utf-8 -*- #添加中文注释 from numpy import * #过滤网站的恶意留言 #样本数据 def loadDataSet(): postingList=[['my', '...
  • 朴素贝叶斯算法(带例题解释)

    万次阅读 多人点赞 2020-02-23 23:18:04
    朴素贝叶斯算法(Naive Bayesian algorithm) 是应用最为广泛的分类算法之一,在垃圾邮件分类等场景展露出了非常优秀的性能。 朴素贝叶斯公式来历 朴素贝叶斯,名字中的朴素二字就代表着该算法对概率事件做了很大的...
  • 主要介绍了Java实现的朴素贝叶斯算法,结合实例形式分析了基于java的朴素贝叶斯算法定义及样本数据训练操作相关使用技巧,需要的朋友可以参考下
  • 朴素贝叶斯分类 贝叶斯原理的由来:贝叶斯为了解决一个叫“逆向概率”问题写了一篇文章,尝试解答在缺乏太多可靠证据的情况下,怎样做出更符合数学逻辑的推测。 逆向概率:逆向概率是相对正向概率而言。正向概率的...
  • 本文实例讲述了朴素贝叶斯算法的python实现方法。分享给大家供大家参考。具体实现方法如下: 朴素贝叶斯算法优缺点 优点:在数据较少的情况下依然有效,可以处理多类别问题 缺点:对输入数据的准备方式敏感 适用数据...
  • #====================调用朴素贝叶斯算法进行分类=============================== from sklearn.naive_bayes import MultinomialNB clf = MultinomialNB() clf.fit(x_train,y_train) # 预测 result = clf....
  • 朴素贝叶斯算法

    2018-08-21 09:23:13
    朴素贝叶斯算法实例,python3可运行,每行代码均有详细解释,适用初学贝叶斯者.
  • 朴素贝叶斯

    2021-03-02 10:57:44
    朴素贝叶斯
  • 朴素贝叶斯(Hidden Naive Bayes,HNB)算法是一种结构扩展后的朴素贝叶斯分类改进算法,其分类精确率较原算法有了很大的提高,但是在分类过程中,HNB算法没有考虑测试实例的各个特征属性的不同取值对分类的贡献程度。...
  • 朴素贝叶斯算法 & 应用实例

    千次阅读 2017-10-20 10:29:10
    一、朴素贝叶斯算法介绍 朴素贝叶斯,之所以称为朴素,是因为其中引入了几个假设(不用担心,下文会提及)。而正因为这几个假设的引入,使得模型简单易理解,同时如果训练得当,往往能收获不错的分类效果,因此这...
  • 该论文中详细介绍了基于朴素贝叶斯的垃圾邮件分类过程,以及五折交叉验证的评价指标,并包含完整的代码,python格式,是一个学习朴素贝叶斯方法不错的实例
  • 朴素贝叶斯算法原理讲解

    万次阅读 2020-11-06 11:35:49
    朴素贝叶斯算法原理讲解 1 算法抽象性解释 NaïveBayes算法,又叫朴素贝叶斯算法,是基于贝叶斯定理与特征条件独立假设的分类方法。 名称由来:朴素,即特征条ming件独立;贝叶斯:基于贝叶斯定理。所谓朴素,就是在...
  • 本文实例讲述了PHP实现机器学习之朴素贝叶斯算法。分享给大家供大家参考,具体如下: 机器学习已经在我们的生活中变得随处可见了。比如从你在家的时候温控器开始工作到智能汽车以及我们口袋中的智能手机。机器学习看...
  • 主要为大家详细介绍了python实现基于朴素贝叶斯的垃圾分类算法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,000
精华内容 4,800
关键字:

朴素贝叶斯算法实例