Advertisement

【NLP】朴素贝叶斯及其Python实现

阅读量:

文本分类(Document Classification / Document Categorization)

分类方法1——基于规则(Hand-coded)

  • 精度高
  • 开销大

分类方法2——机器学习(Machine learning)

是一种计算机算法,该算法通过对数据做自动分析来获得规律,并利用这些规律对未知数据进行预测 。它是人工智能的一个分支。

有监督学习 无监督的学习
训练集包括输入和由人工标注的输出 其训练集没有人为标注的输出
分类器(classifier) 聚类(cluster)

常用的分类器有:朴素贝叶斯KNN决策树SVM神经网络 等。

朴素贝叶斯(Naïve Bayes)

朴素贝叶斯的原理
在这里插入图片描述
朴素贝叶斯的优缺点

  • 优:朴素贝叶斯假设了数据集属性之间相互独立 ,因此算法的逻辑性得到极大的简化 ,这使得朴素贝叶斯十分稳定,即比较健壮
  • 缺:属性的独立性条件同时也是朴素贝叶斯的不足之处,毕竟在实际中,数据集的属性之间往往存在这样那样的关联很难满足这种属性的独立性 ,分类效果也会因此大大降低。

朴素贝叶斯的理解

  1. 属性独立性 是Naïve Bayes的前提 也是关键
  2. 这种独立性也代表着:属性无权重,它们对于决策结果的影响是平等的
  3. 贝叶斯方法的特点是结合先验概率和后验概率 ,即避免了只使用先验概率的主观偏见 ,也避免了单独使用样本信息的过拟合现象 ——通过下面的简单例子,你就能理解这句话了 >_<

如何基于这些原理实现Naïve Bayes分类器?

通俗地说,就是根据已有的数据集,得到先验概率** 和各种属性对于各种决策的条件概率 (可以理解为每种属性对每种决策的影响的大小);面对新的场景,对于每一种决策结果,进行一串连乘 ,推选出概率最高者为最终决策。**

一个超级简单的例子

在这里插入图片描述
Chinese、Beijing、Tokyo等为相互独立的属性
求第五组(text5)属于那一类(c / j) ?

手写解
在这里插入图片描述
代码解

复制代码
    text1 = "Chinese Beijing Chinese"                   # 分类为c
    text2 = "Chinese Chinese Shanghai"                  # 分类为c
    text3 = "Chinese Macao"                             # 分类为c
    text4 = "Tokyo Japan Chinese"                       # 分类为j
    text5 = "Chinese Chinese Chinese Tokyo Japan"       # 分类为什么?
    
    
    import re
    pattern = re.compile('\w+')
    # 获取单词list
    C = pattern.findall(text1) + pattern.findall(text2) + pattern.findall(text3)	
    J = pattern.findall(text4)														
    All = C + J
    # 词频
    from nltk import *
    fd_c = FreqDist(C)
    fd_j = FreqDist(J)
    fd_all = FreqDist(All)
    
    # 先验概率
    pc = 3 / 4
    pj = 1 / 4
    
    def Naive_Bayes_classifier(text):
    pc = 1
    pj = 1
    pc *= 3 / 4
    pj *= 1 / 4
    for each in text5.split(' '):
        pc *= ((fd_c[each] + 1) / (len(C) + len(fd_all)))
        pj *= ((fd_j[each] + 1) / (len(J) + len(fd_all)))
    print('分类为c的后验概率正比于', pc)
    print('分类为j的后验概率正比于', pj)
    print('最终该text的分类为(最终决策):', 'c' if pc > pj else 'j')
    
    
    Naive_Bayes_classifier(text5)
    
    
    python
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/UixELeT6lchpCBFn31fomKbj527O.png)
在这里插入图片描述

NLTK提供的朴素贝叶斯分类器

复制代码
    ############################### 基于NLTK的朴素贝叶斯分类器实现人名分类 #############################
    
    from nltk.corpus import names		# 直接利用nltk提供的语料库
    print(names.fileids())				# 这个names语料库有两个文件:['female.txt', 'male.txt']
    name_sex = [(name, 'male') for name in names.words('male.txt')] + [(name, 'female') for name in names.words('female.txt')]
    
    # 把这些带标签的名字随机化
    import random
    random.shuffle(name_sex)
    
    # 获取特征———以名字的最后一个字母作为特征
    def get_features(word):
    return {'last_name': word[-1]}
    
    # 生成特征集合
    # tip:格式为[({描述:属性特征}, 类别), ({描述:特征}, 类别), ({描述:属性特征}, 类别)...]
    feature_set = [(get_features(name), sex) for (name, sex) in name_sex]
    
    # 获得训练集和测试集
    train_set = feature_set[500:]
    test_set = feature_set[:500]
    
    # 训练分类器
    import nltk
    classifier = nltk.NaiveBayesClassifier.train(test_set)
    
    # 输入名字,使用分类器实现分类(实际上是预测)
    name = input('>_< 请输入名字: ')
    print('>_< 我猜测ta的性别是: ', classifier.classify(get_features(name)))
    
    
    python
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/WBljdRaGCrEU48pmIh97LTSn5V2Y.png)
在这里插入图片描述

评估:

复制代码
    print(nltk.classify.accuracy(classifier, test_set))			# 0.746
    
    
    python
    
    

上面在获取特征时(get_features)获取的是“名字的最后一个字母”,所以0.746这个评估结果完全在预料之中

如果将整个名字作为特征:def get_features(word): return {'whole_name': word}

评估结果可达到0.998


检查分类器的有效特征

复制代码
    classifier.show_most_informative_features(5)
    
    
    java
    
    
在这里插入图片描述

全部评论 (0)

还没有任何评论哟~