• 【Python人工智能】Python全栈体系(十九)


    人工智能

    第七章 舆情分析

    一、舆情分析

    • 文本情感分析又称意见挖掘、倾向性分析等。简单而言,是对带有情感色彩的主观性文本进行分析、处理、归纳和推理的过程。互联网产生了大量的诸如人物、事件、产品等有价值的评论信息。这些评论信息表达了人们的各种情感色彩和情感倾向性,如喜、怒、哀、乐和批评、赞扬等。基于此,潜在的用户就可以通过浏览这些主观色彩的评论来了解大众舆论对于某一事件或产品的看法。

    二、情感分析

    • 酒店评论
    预测酒店评论是好评还是差评:
    1. 房间真棒,离大马路很近,非常方便,不错。			好评 0.9954
    2. 房间有点脏,厕所还漏水,空调不制冷,下次再也不来了。	差评 0.99
    3. 地板不太干净,电视没信号,但是空调还可以,总之还行。	好评 0.56
    
    • 1
    • 2
    • 3
    • 4
    • 文本语义分析原理:
      • 先针对训练文本进行分词处理,统计词频,通过词频-逆文档频率算法获得该词对样本语义的贡献,根据每个词的贡献力度,构建有监督分类学习模型。把测试样本交给模型处理,得到测试样本的情感类别。

    三、文本分词

    • 英文分词:
    pip3 install nltk -i
    https://pypi.tuna.tsinghua.edu.cn/simple/
    
    • 1
    • 2
    • 中文分词:
    pip3 install jieba -i
    https://pypi.tuna.tsinghua.edu.cn/simple/
    
    • 1
    • 2

    四、英文分词

    • 英文分词相关API如下,nltk 将会寻找 punkt 资源:
      • ~/nltk_data/tokenizers/punkt/
    import nltk.tokenize as tk
    # 把样本按句子进行拆分 sent_list:句子列表
    sent_list = tk.sent_tokenize(text)
    # 把样本按单子进行拆分 word_list:单词列表
    word_list = tk.word_tokenize(text)
    # 把样本按单词进行拆分 punctTokenizer:分词器对象
    punctTokenizer = tk.WordPunctTokenizer()
    word_list = punctTokenizer.tokenize(text)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    五、案例:英文分词

    • 对下列文本进行分句、分词处理
    doc = "Are you curious about tokenization? Let's see how it works! We need to analyze a couple of sentences with punctuations to see it in action."
    # 分句子
    sents = tk.sent_tokenize(doc)
    for i in range(len(sents)):
    	print(i+1, ':', sents[i])
    """
    1 : Are you curious about tokenization?
    2 : Let's see how it works!
    3 : We need to analyze a couple of sentences with punctuations to see it in action.
    """
    
    # 分单词
    words = tk.word_tokenize(doc)
    for i in range(len(words)):
    	print(i+1, ':', words[i])
    """
    1 : Are
    2 : you
    3 : curious
    4 : about
    5 : tokenization
    6 : ?
    7 : Let
    8 : 's
    9 : see
    10 : how
    11 : it
    12 : works
    13 : !
    14 : We
    15 : need
    16 : to
    17 : analyze
    18 : a
    19 : couple
    20 : of
    21 : sentences
    22 : with
    23 : punctuations
    24 : to
    25 : see
    26 : it
    27 : in
    28 : action
    29 : .
    """
    
    tokenizer = tk.WordPunctTokenizer()
    words = tokenizer.tokenize(doc)
    for i in range(len(words)):
        print(i+1, ':', words[i])
    
    """
    1 : Are
    2 : you
    3 : curious
    4 : about
    5 : tokenization
    6 : ?
    7 : Let
    8 : '
    9 : s
    10 : see
    11 : how
    12 : it
    13 : works
    14 : !
    15 : We
    16 : need
    17 : to
    18 : analyze
    19 : a
    20 : couple
    21 : of
    22 : sentences
    23 : with
    24 : punctuations
    25 : to
    26 : see
    27 : it
    28 : in
    29 : action
    30 : .
    """
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84

    六、文本向量化处理

    • 在训练语义分析模型时,需要以每一段落为一个样本,这一段落的语义为类别标签构建训练样本集。所以急需一种算法可以把一句话(一个样本)转为一个特征向量,需要该向量通过数字表达语义。
    This hotel is very bad. The toilet in this hotel smells bed. The environment of this hotel is very good.
    
    This hotel is very bad. 
    The toilet in this hotel smells bed.
    The environment of this hotel is very good.
    
    • 1
    • 2
    • 3
    • 4
    • 5

    1. 词袋模型

    • 在训练语义分析模型时,需要以每一段落为一个样本,这一段落的语义为类别标签构建训练样本集。
    • 一句话的语义很大程度取决于某个单词出现的次数,所以可以把所有段落中所有可能出现的单词作为特征名,每一个段落为一个样本,而单词在句子中出现的次数为特征值构建样本模型,称为词袋(bow)模型。
    ThishotelisverybadThetoiletinsmellsenvironmentofgood
    111110000000
    110011111000
    111101000111
    • 词袋模型相关 API:
    import sklearn.feature_extraction.text as ft
    
    # 构建词袋模型对象
    cv = ft.CountVectorizer()
    # 训练模型,把句子中所有可能出现的单词作为特征名,每一个句子为一个样本,单词在句子中出现的次数为特征值
    bow = cv.fit_transform(sentences).toarray()
    print(bow)
    # 获取所有特征名
    words = cv.get_features_names()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    import sklearn.feature_extraction.text as ft
    sents = ['This hotel is very bad.', 
    'The toilet in this hotel smells bad.',
    'The environment of this hotel is very good.']
    cv = ft.CountVectorizer()
    bow = cv.fit_transform(sents)
    print(bow)
    print(bow.toarray())
    print(cv.get_feature_names())
    """
      (0, 9)	1
      (0, 3)	1
      (0, 5)	1
      (0, 11)	1
      (0, 0)	1
      (1, 9)	1
      (1, 3)	1
      (1, 0)	1
      (1, 8)	1
      (1, 10)	1
      (1, 4)	1
      (1, 7)	1
      (2, 9)	1
      (2, 3)	1
      (2, 5)	1
      (2, 11)	1
      (2, 8)	1
      (2, 1)	1
      (2, 6)	1
      (2, 2)	1
    [[1 0 0 1 0 1 0 0 0 1 0 1]
     [1 0 0 1 1 0 0 1 1 1 1 0]
     [0 1 1 1 0 1 1 0 1 1 0 1]]
    ['bad', 'environment', 'good', 'hotel', 'in', 'is', 'of', 'smells', 'the', 'this', 'toilet', 'very']
    """
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    2. 词频(TF)

    • 一个单词在一个句子中出现的频率称为词频,即单词在句子中出现的次数除以句子的总次数。词频越高,说明单词对当前样本语义的贡献度越大(即当该单词出现,被分为相应类别的概率越大)。
    • 单词词频相比单词的出现次数可以更加客观的评估单词对样本语义的贡献度。
    这家酒店棒,装修棒,早餐棒,环境棒。	1
    这家酒店烂,烂烂烂,真的烂。			0
    这家酒店装修棒,服务烂。			?
    
    • 1
    • 2
    • 3

    3. 文档频率(DF)与逆文档频率(IDF)

    • 有些词可能在大部分样本中都会出现,例如指示代词、语气助词等。而这些在大多数样本都会出现的单词对判断样本属于哪一个类别没有什么太大作用。需要设计一个算法把这些单词对语义贡献值降低:

    文 档 频 率 : D F = 含 有 某 个 单 词 的 文 档 样 本 数 总 文 档 样 本 数 ( 与 样 本 语 义 贡 献 度 反 相 关 ) 文档频率: DF = \frac{含有某个单词的文档样本数}{总文档样本数}(与样本语义贡献度反相关) DF=
    逆 文 档 频 率 : I D F = l o g ( 总 样 本 数 1 + 含 有 某 个 单 词 的 样 本 数 ) ( 与 样 本 语 义 贡 献 度 正 相 关 ) 逆文档频率: IDF = log\left(\frac{总样本数}{1+含有某个单词的样本数}\right)(与样本语义贡献度正相关) IDF=log(1+)

    4. 词频 - 逆文档频率(TF - IDF)

    • 词频矩阵中的每一个元素乘以相应单词的逆文档频率,就得到了每个单词对每个样本的词频逆文档频率值。其值越大说明该词对样本语义的贡献越大,可以根据每个词的贡献力度,构建学习模型。
    • 获取词频逆文档频率(TF-IDF)矩阵相关 API:
    # 构建词袋模型对象
    cv = ft.CountVectorizer()
    # 训练模型,把句子中所有可能出现的单词作为特征名,每一个句子为一个样本,单词在句子中出现的次数为特征值
    bow = cv.fit_transform(sentences).toarray()
    # 获取TF-IDF模型训练器
    tt = ft.TfidfTransformer()
    tfidf = tt.fit_transform(bow).toarray()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    tt = ft.TfidfTransformer()
    tfidf = tt.fit_transform(bow).toarray()
    print(np.round(tfidf, 3))
    print(cv.get_feature_names())
    """
    [[0.488 0.    0.    0.379 0.    0.488 0.    0.    0.    0.379 0.    0.488]
     [0.345 0.    0.    0.268 0.454 0.    0.    0.454 0.345 0.268 0.454 0.   ]
     [0.    0.429 0.429 0.253 0.    0.326 0.429 0.    0.326 0.253 0.    0.326]]
    ['bad', 'environment', 'good', 'hotel', 'in', 'is', 'of', 'smells', 'the', 'this', 'toilet', 'very']
    """
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    第八章 邮件分类(主题识别)

    • 使用给定的文本数据集(20news)进行主题识别训练,自定义测试集
    import numpy as np
    import pandas as pd
    import sklearn.datasets as sd
    import sklearn.model_selection as ms
    import sklearn.linear_model as lm
    import sklearn.metrics as sm
    
    # 加载数据集
    data = sd.load_files('20news', encoding='latin1')
    len(data.data) # 2968个样本
    """
    2968
    """
    
    import sklearn.feature_extraction.text as ft
    # 整理输入集与输出集 TFIDF 把每一封邮件转成一个特征向量
    cv = ft.CountVectorizer()
    bow = cv.fit_transform(data.data)
    tt = ft.TfidfTransformer()
    tfidf = tt.fit_transform(bow)
    # tfidf.shape # (2968,40605)
    # 拆分测试集与训练集
    train_x, test_x, train_y, test_y = ms.train_test_split(tfidf, data.target, test_size=0.1, random_state=7)
    # 交叉验证
    model = lm.LogisticRegression()
    scores = ms.cross_val_score(model, tfidf, data.target, cv=5, scoring='f1_weighted')
    # f1得分
    print(scores.mean()) # 0.9597980963781605
    # 训练模型
    model.fit(train_x, train_y)
    # 测试模型,评估模型
    pred_test_y = model.predict(test_x)
    print(sm.classification_report(test_y, pred_test_y))
    """
    0.9597980963781605
                  precision    recall  f1-score   support
    
               0       0.81      0.96      0.88        57
               1       0.97      0.89      0.93        65
               2       1.00      0.95      0.97        61
               3       1.00      1.00      1.00        54
               4       1.00      0.95      0.97        60
    
        accuracy                           0.95       297
       macro avg       0.96      0.95      0.95       297
    weighted avg       0.96      0.95      0.95       297
    """
    
    # 整理一组测试样本进行模型测试
    test_data = ["In the last game, the spectator was accidentally hit by a baseball injury and has been hospitalized.",
           "Recently, Lao Wang is studying asymmetric encryption algorithms.",
           "The two-wheeled car is pretty good on the highway."]
    # 把样本按照训练时的方式转换成tfidf矩阵,才可以交给模型进行预测
    bow = cv.transform(test_data)
    test_data = tt.transform(bow)
    pred_test_y = model.predict(test_data)
    print(pred_test_y)
    print(data.target_names)
    """
    [2 0 1]
    ['misc.forsale', 'rec.motorcycles', 'rec.sport.baseball', 'sci.crypt', 'sci.space']
    """
    data.target_names
    """
    ['misc.forsale',
     'rec.motorcycles',
     'rec.sport.baseball',
     'sci.crypt',
     'sci.space']
    """
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70

    第九章 朴素贝叶斯分类模型

    • 朴素贝叶斯分类模型是一种依据统计概率理论而实现的一种分类方式。
    • 朴素贝叶斯是一组功能强大且易于训练的分类器,它使用贝叶斯定理来确定给定一组条件的结果的概率,“朴素”的含义是指所给定的条件都能独立存在和发生. 朴素贝叶斯是多用途分类器,能在很多不同的情景下找到它的应用,例如垃圾邮件过滤、自然语言处理等.

    一、概率

    1. 定义

    • 概率是反映随机事件出现的可能性大小. 随机事件是指在相同条件下,可能出现也可能不出现的事件. 例如:

      (1)抛一枚硬币,可能正面朝上,可能反面朝上,这是随机事件. 正/反面朝上的可能性称为概率;

      (2)掷骰子,掷出的点数为随机事件. 每个点数出现的可能性称为概率;

      (3)一批商品包含良品、次品,随机抽取一件,抽得良品/次品为随机事件. 经过大量反复试验,抽得次品率越来越接近于某个常数,则该常数为概率.

    • 我们可以将随机事件记为A或B,则P(A), P(B)表示事件A或B的概率.

    2. 联合概率与条件概率

    ① 联合概率

    指包含多个条件且所有条件同时成立的概率,记作 P ( A , B ) P ( A , B ) P(A,B) ,或 P ( A B ) P(AB) P(AB),或 P ( A ⋂ B ) P(A \bigcap B) P(AB)

    ② 条件概率

    已知事件B发生的条件下,另一个事件A发生的概率称为条件概率,记为: P ( A ∣ B ) P(A|B) P(AB)

    p(下雨|阴天)

    ③ 事件的独立性

    事件A不影响事件B的发生,称这两个事件独立,记为:
    P ( A B ) = P ( A ) P ( B ) P(AB)=P(A)P(B) P(AB)=P(A)P(B)
    因为A和B不相互影响,则有:
    P ( A ∣ B ) = P ( A ) P(A|B) = P(A) P(AB)=P(A)
    可以理解为,给定或不给定B的条件下,A的概率都一样大.

    3. 先验概率与后验概率

    ① 先验概率

    先验概率也是根据以往经验和分析得到的概率,例如:在没有任何信息前提的情况下,猜测对面来的陌生人姓氏,姓李的概率最大(因为全国李姓为占比最高的姓氏),这便是先验概率.

    ② 后验概率

    后验概率是指在接收了一定条件或信息的情况下的修正概率,例如:在知道对面的人来自“牛家村”的情况下,猜测他姓牛的概率最大,但不排除姓杨、李等等,这便是后验概率.

    ③ 两者的关系

    事情还没有发生,求这件事情发生的可能性的大小,是先验概率(可以理解为由因求果). 事情已经发生,求这件事情发生的原因是由某个因素引起的可能性的大小,是后验概率(由果求因). 先验概率与后验概率有不可分割的联系,后验概率的计算要以先验概率为基础.

    二、贝叶斯定理

    1. 定义

    贝叶斯定理由英国数学家托马斯.贝叶斯 ( Thomas Bayes)提出,用来描述两个条件概率之间的关系,定理描述为:
    P ( A ∣ B ) = P ( A ) P ( B ∣ A ) P ( B ) P(A|B) = \frac{P(A)P(B|A)}{P(B)} P(AB)=P(B)P(A)P(BA)
    其中, P ( A ) P(A) P(A) P ( B ) P(B) P(B)是A事件和B事件发生的概率. P ( A ∣ B ) P(A|B) P(AB)称为条件概率,表示B事件发生条件下,A事件发生的概率. 推导过程:
    P ( A , B ) = P ( B ) P ( A ∣ B ) P ( B , A ) = P ( A ) P ( B ∣ A ) P(A,B) =P(B)P(A|B)\\ P(B,A) =P(A)P(B|A) P(A,B)=P(B)P(AB)P(B,A)=P(A)P(BA)
    其中 P ( A , B ) P(A,B) P(A,B)称为联合概率,指事件B发生的概率,乘以事件A在事件B发生的条件下发生的概率. 因为 P ( A , B ) = P ( B , A ) P(A,B)=P(B,A) P(A,B)=P(B,A), 所以有:
    P ( B ) P ( A ∣ B ) = P ( A ) P ( B ∣ A ) P(B)P(A|B)=P(A)P(B|A) P(B)P(AB)=P(A)P(BA)
    两边同时除以P(B),则得到贝叶斯定理的表达式. 其中, P ( A ) P(A) P(A)是先验概率, P ( A ∣ B ) P(A|B) P(AB)是已知B发生后A的条件概率,也被称作后验概率.

    2. 贝叶斯定理示例

    • 假设一个学校中 60%的男生 和40%的女生 ,女生穿裤子的人数和穿裙子的人数相等,所有的男生都穿裤子,一个人随机在远处眺望,看一个穿裤子的学生,请问这个学生是女生的概率:

      p(女) = 0.4

      p(裤子|女) = 0.5

      p(裤子) = 0.8

      P(女|裤子) = 0.4 * 0.5 / 0.8 = 0.25

    P ( A ∣ B ) = P ( A ) P ( B ∣ A ) P ( B ) P(A|B) = \frac{P(A)P(B|A)}{P(B)} P(AB)=P(B)P(A)P(BA)

    3. 需求

    • 观察这组数据:
    天气情况穿衣风格约女朋友==>心情
    0(晴天)0(休闲)0(约了)==>0(高兴)
    01(风骚)1(没约)==>0
    1(多云)10==>0
    02(破旧)1==>1(郁闷)
    2(雨天)20==>0
    ==>
    010==>?
    • 根据这组数据如何预测:晴天、穿着休闲、没有约女朋友时的心情?
      0 0 1 => ?
    • 通过上述训练样本可以整理相同特征值的样本,计算属于某类别的概率即可:
      • 晴天、穿着休闲、没有约女朋友的条件下高兴的概率
        • P(高兴|晴,休,没约)
      • 晴天、穿着休闲、没有约女朋友的条件下郁闷的概率
        • P(郁闷|晴,休,没约)

    4. 贝叶斯预测心情

    • 根据贝叶斯定理,如何预测:晴天、穿着休闲、没有约女朋友时的心情?
      P ( 高 兴 ∣ 晴 天 , 休 闲 , 没 约 ) = P ( 晴 天 , 休 闲 , 没 约 ∣ 高 兴 ) P ( 高 兴 ) P ( 晴 天 , 休 闲 , 没 约 ) P(高兴|晴天,休闲,没约) = \frac{P(晴天,休闲,没约|高兴)P(高兴)}{P(晴天,休闲,没约)} P()=P()P()P()
      P ( 郁 闷 ∣ 晴 天 , 休 闲 , 没 约 ) = P ( 晴 天 , 休 闲 , 没 约 ∣ 郁 闷 ) P ( 郁 闷 ) P ( 晴 天 , 休 闲 , 没 约 ) P(郁闷|晴天,休闲,没约) = \frac{P(晴天,休闲,没约|郁闷)P(郁闷)}{P(晴天,休闲,没约)} P()=P()P()P()
    • 即比较:
      = > P ( 晴 天 , 休 闲 , 没 约 ∣ 高 兴 ) P ( 高 兴 ) => P(晴天,休闲,没约|高兴)P(高兴) =>P()P()
      = > P ( 晴 天 , 休 闲 , 没 约 ∣ 郁 闷 ) P ( 郁 闷 ) => P(晴天,休闲,没约|郁闷)P(郁闷) =>P()P()
    • 根据条件独立假设(朴素的概念),特征之间没有因果关系,则:
      = > P ( 晴 天 ∣ 高 兴 ) P 休 闲 ∣ 高 兴 ) P ( 没 约 ∣ 高 兴 ) P ( 高 兴 ) => P(晴天|高兴)P休闲|高兴)P(没约|高兴)P(高兴) =>P()P)P()P()
      = > P ( 晴 天 ∣ 郁 闷 ) P 休 闲 ∣ 郁 闷 ) P ( 没 约 ∣ 郁 闷 ) P ( 郁 闷 ) => P(晴天|郁闷)P休闲|郁闷)P(没约|郁闷)P(郁闷) =>P()P)P()P()
    • 由此可得,在训练阶段统计计算所需要的概率,经过计算后择其大者为最终结果。

    5. 朴素贝叶斯实现

    • 贝叶斯分类器相关 API:
    import sklearn.naive_bayes as nb
    # 创建高斯朴素贝叶斯分类器对象
    model = nb.GaussianNB()
    model = nb.MultinomialNB()
    model.fit(x, y) 
    result = model.predict(samples)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • GaussianNB 更适合服从高斯分布的训练样本

    • MultinomialNB 更适合服从多项分布的训练样本

    • 在sklearn中,提供了三个朴素贝叶斯分类器,分别是:

      • GaussianNB(高斯朴素贝叶斯分类器):适合用于样本的值是连续的,数据呈正态分布的情况(比如人的身高、城市家庭收入、一次考试的成绩等等)
      • MultinominalNB(多项式朴素贝叶斯分类器):适合用于大部分属性为离散值的数据集
      • BernoulliNB(伯努利朴素贝叶斯分类器):适合用于特征值为二元离散值或是稀疏的多元离散值的数据集
    • 该示例中,样本的值为连续值,且呈正态分布,所以采用GaussianNB模型. 代码如下:

    # 朴素贝叶斯分类示例
    import numpy as np
    import sklearn.naive_bayes as nb
    import matplotlib.pyplot as mp
    
    # 输入,输出
    x, y = [], []
    
    # 读取数据文件
    with open("../data/multiple1.txt", "r") as f:
        for line in f.readlines():
            data = [float(substr) for substr in line.split(",")]
            x.append(data[:-1])  # 输入样本:取从第一列到倒数第二列
            y.append(data[-1])  # 输出样本:取最后一列
    
    x = np.array(x)
    y = np.array(y, dtype=int)
    
    # 创建高斯朴素贝叶斯分类器对象
    model = nb.GaussianNB()
    model.fit(x, y)  # 训练
    
    # 计算显示范围
    left = x[:, 0].min() - 1
    right = x[:, 0].max() + 1
    
    buttom = x[:, 1].min() - 1
    top = x[:, 1].max() + 1
    
    grid_x, grid_y = np.meshgrid(np.arange(left, right, 0.01),
                                 np.arange(buttom, top, 0.01))
    
    mesh_x = np.column_stack((grid_x.ravel(), grid_y.ravel()))
    mesh_z = model.predict(mesh_x)
    mesh_z = mesh_z.reshape(grid_x.shape)
    
    mp.figure('Naive Bayes Classification', facecolor='lightgray')
    mp.title('Naive Bayes Classification', fontsize=20)
    mp.xlabel('x', fontsize=14)
    mp.ylabel('y', fontsize=14)
    mp.tick_params(labelsize=10)
    mp.pcolormesh(grid_x, grid_y, mesh_z, cmap='gray')
    mp.scatter(x[:, 0], x[:, 1], c=y, cmap='brg', s=80)
    mp.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 执行结果:
      在这里插入图片描述

    6. 邮件分类实现

    import numpy as np
    import pandas as pd
    import sklearn.datasets as sd
    import sklearn.model_selection as ms
    import sklearn.linear_model as lm
    import sklearn.metrics as sm
    
    # 加载数据集
    data = sd.load_files('20news', encoding='latin1')
    
    import sklearn.feature_extraction.text as ft
    # 整理输入集与输出集 TFIDF 把每一封邮件转成一个特征向量
    cv = ft.CountVectorizer()
    bow = cv.fit_transform(data.data)
    tt = ft.TfidfTransformer()
    tfidf = tt.fit_transform(bow)
    # tfidf.shape # (2968,40605)
    # 拆分测试集与训练集
    train_x, test_x, train_y, test_y = ms.train_test_split(tfidf, data.target, test_size=0.1, random_state=7)
    # 交叉验证
    # 使用朴素贝叶斯
    import sklearn.naive_bayes as nb
    model = nb.MultinomialNB()
    scores = ms.cross_val_score(model, tfidf, data.target, cv=5, scoring='f1_weighted')
    # f1得分
    print(scores.mean())
    # 训练模型
    model.fit(train_x, train_y)
    # 测试模型,评估模型
    pred_test_y = model.predict(test_x)
    print(sm.classification_report(test_y, pred_test_y))
    """
    0.9458384770112502
                  precision    recall  f1-score   support
    
               0       1.00      0.84      0.91        57
               1       0.94      0.94      0.94        65
               2       0.95      0.97      0.96        61
               3       0.90      1.00      0.95        54
               4       0.97      1.00      0.98        60
    
        accuracy                           0.95       297
       macro avg       0.95      0.95      0.95       297
    weighted avg       0.95      0.95      0.95       297
    """
    # 整理一组测试样本进行模型测试
    test_data = ["In the last game, the spectator was accidentally hit by a baseball injury and has been hospitalized.",
           "Recently, Lao Wang is studying asymmetric encryption algorithms.",
           "The two-wheeled car is pretty good on the highway.",
           "Next year, China will explore Mars."]
    # 把样本按照训练时的方式转换成tfidf矩阵,才可以交给模型进行预测
    bow = cv.transform(test_data)
    test_data = tt.transform(bow)
    pred_test_y = model.predict(test_data)
    print(pred_test_y)
    print(data.target_names)
    """
    [2 3 1 4]
    ['misc.forsale', 'rec.motorcycles', 'rec.sport.baseball', 'sci.crypt', 'sci.space']
    """
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    7. 总结

    7.1 什么是朴素贝叶斯
    • 朴素贝叶斯法是基于贝叶斯定理与特征条件独立假设的分类方法。“朴素”的含义为:假设问题的特征变量都是相互独立地作用于决策变量的,即问题的特征之间都是互不相关的。
    7.2 朴素贝叶斯分类的特点

    ① 优点

    • 逻辑性简单
    • 算法较为稳定。当数据呈现不同的特点时,朴素贝叶斯的分类性能不会有太大的差异。
    • 当样本特征之间的关系相对比较独立时,朴素贝叶斯分类算法会有较好的效果。

    ② 缺点

    • 特征的独立性在很多情况下是很难满足的,因为样本特征之间往往都存在着相互关联,如果在分类过程中出现这种问题,会导致分类的效果大大降低。
    7.3 什么情况下使用朴素贝叶斯
    • 根据先验概率计算后验概率的情况,且样本特征之间独立性较强。
  • 相关阅读:
    贪心算法归纳
    java和vue的大学生奖学金助学金系统奖学金系统助学金系统
    跳闸、合闸位置监视继电器HJTHW-E002J/DC220V
    PyQt6 GUI界面设计和Nuitka包生成exe程序(全笔记)
    [面试直通]操作系统核心之存储系统(上)
    数电学习(十、脉冲波形的产生和整形)(二)
    力扣第46天--- 第583题、第72题
    字节跳动2021首发485道Java岗面试题(含答案)
    基于SSM的邮箱客户端的设计与实现
    【软考】11.1 生命周期/CMM/开发模型
  • 原文地址:https://blog.csdn.net/sgsgkxkx/article/details/125438255