朴素贝叶斯分类最适合的场景就是文本分类、情感分析和垃圾邮件识别。其中情感分析和垃圾邮件识别都是通过文本来进行判断。所以朴素贝叶斯也常用于自然语言处理 NLP 的工具。

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 如何计算


些单词可能不会存在文档中,为了避免分母为 0,统一给单词出现的文档数都加 1。

举个例子
假设一个文件夹里一共有 10 篇文档,其中一篇文档有 1000 个单词,“this”这个单词出现 20 次,“bayes”出现了 5 次。“this”在所有文档中均出现过,而“bayes”只在 2 篇文档中出现过。

针对“this”,计算 TF-IDF 值:

所以 TF-IDF=0.02*(-0.0414)=-8.28e-4。
针对“bayes”,计算 TF-IDF 值:

TF-IDF=0.005*0.5229=2.61e-3。

很明显“bayes”的 TF-IDF 值要大于“this”的 TF-IDF 值。这就说明用“bayes”这个单词做区分比单词“this”要好。

如何求 TF-IDF
在 sklearn 中我们直接使用 TfidfVectorizer 类,它可以帮我们计算单词 TF-IDF 向量的值。

在这个类中,取 sklearn 计算的对数 log 时,底数是 e,不是 10。
创建 TfidfVectorizer 的方法是:

TfidfVectorizer(stop_words=stop_words, token_pattern=token_pattern)



当我们创建好 TF-IDF 向量类型时,可以用 fit_transform 帮我们计算,返回给我们文本矩阵,该矩阵表示了每个单词在每个文档中的 TF-IDF 值。

在我们进行 fit_transform 拟合模型后,我们可以得到更多的 TF-IDF 向量属性,比如,我们可以得到词汇的对应关系(字典类型)和向量的 IDF 值,当然也可以获取设置的停用词 stop_words。



现在想要计算文档里都有哪些单词,这些单词在不同文档中的 TF-IDF 值是多少呢?
首先我们创建 TfidfVectorizer 类:

from sklearn.feature_extraction.text import TfidfVectorizer
tfidf_vec = TfidfVectorizer()
documents = ['this is the bayes document','this is the second second document','and the third one','is this the document'
]
tfidf_matrix = tfidf_vec.fit_transform(documents)
print('不重复的词:', tfidf_vec.get_feature_names())
print('每个单词的 ID:', tfidf_vec.vocabulary_)
#输出每个单词在每个文档中的 TF-IDF 值,向量里的顺序是按照词语的 id 顺序来的:
print('每个单词的 tfidf 值:', tfidf_matrix.toarray())输出
不重复的词: ['and', 'bayes', 'document', 'is', 'one', 'second', 'the', 'third', 'this']
每个单词的 ID: {'this': 8, 'is': 3, 'the': 6, 'bayes': 1, 'document': 2, 'second': 5, 'and': 0, 'third': 7, 'one': 4}
每个单词的 tfidf 值: [[0.         0.63314609 0.40412895 0.40412895 0.         0.0.33040189 0.         0.40412895][0.         0.         0.27230147 0.27230147 0.         0.853225740.22262429 0.         0.27230147][0.55280532 0.         0.         0.         0.55280532 0.0.28847675 0.55280532 0.        ][0.         0.         0.52210862 0.52210862 0.         0.0.42685801 0.         0.52210862]]

如何对文档进行分类(以下六个模块只作示意)

1、基于分词的数据准备,包括分词、单词权重计算、去掉停用词; 2、应用朴素贝叶斯分类进行分类,首先通过训练集得到朴素贝叶斯分类器,然后将分类器应用于测试集,并与实际结果做对比,最终得到测试集的分类准确率。

模块 1:对文档进行分词
在准备阶段里,最重要的就是分词。那么如果给文档进行分词呢?英文文档和中文文档所使用的分词工具不同。

在英文文档中,最常用的是 NTLK 包。NTLK 包中包含了英文的停用词 stop words、分词和标注方法。

import nltk
word_list = nltk.word_tokenize(text) # 分词
nltk.pos_tag(word_list) # 标注单词的词性

在中文文档中,最常用的是 jieba 包。jieba 包中包含了中文的停用词 stop words 和分词方法。

import jieba
word_list = jieba.cut (text) # 中文分词

模块 2:加载停用词表
我们需要自己读取停用词表文件,从网上可以找到中文常用的停用词保存在 stop_words.txt,然后利用 Python 的文件读取函数读取文件保存在 stop_words 数组中。

#加r可以帮助解析转意
with open(r'C:/Users/baihua/Desktop/stopword.txt', 'rb') as f:STOP_WORDS = [line.strip() for line in f.readlines()]

模块 3:计算单词的权重

直接创建 TfidfVectorizer 类,然后使用 fit_transform 方法进行拟合,得到 TF-IDF 特征空间 features,你可以理解为选出来的分词就是特征。我们计算这些特征在文档上的特征向量,得到特征空间 features。

test_tf = TfidfVectorizer(stop_words=stop_words, max_df=0.5, vocabulary=train_vocabulary)
test_features=test_tf.fit_transform(test_contents)

这里 max_df 参数用来描述单词在文档中的最高出现率。假设 max_df=0.5,代表一个单词在 50% 的文档中都出现过了,那么它只携带了非常少的信息,因此就不作为分词统计。

模块 4:生成朴素贝叶斯分类器
我们将特征训练集的特征空间 train_features,以及训练集对应的分类 train_labels 传递给贝叶斯分类器 clf,它会自动生成一个符合特征空间和对应分类的分类器。
这里我们采用的是多项式贝叶斯分类器,其中 alpha 为平滑参数。为什么要使用平滑呢?因为如果一个单词在训练样本中没有出现,这个单词的概率就会被计算为 0。为了解决这个问题,我们需要做平滑处理。

当 alpha=1 时,使用的是 Laplace 平滑。Laplace 平滑就是采用加 1 的方式,来统计没有出现过的单词的概率。

当 0<alpha<1 时,使用的是 Lidstone 平滑。对于 Lidstone 平滑来说,alpha 越小,迭代次数越多,精度越高。我们可以设置 alpha 为 0.001。

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

模块 5:使用生成的分类器做预测
首先我们需要得到测试集的特征矩阵。

test_tf = TfidfVectorizer(stop_words=stop_words, max_df=0.5, vocabulary=train_vocabulary)
test_features=test_tf.fit_transform(test_contents)

然后我们用训练好的分类器对新数据做预测。
方法是使用 predict 函数,传入测试集的特征矩阵 test_features,得到分类结果 predicted_labels。predict 函数做的工作就是求解所有后验概率并找出最大的那个。

predicted_labels=clf.predict(test_features)

模块 6:计算准确率
我们可以调用 sklearn 中的 metrics 包,在 metrics 中提供了 accuracy_score 函数,方便我们对实际结果和预测的结果做对比,给出模型的准确率。使用方法如下:

from sklearn import metrics
print metrics.accuracy_score(test_labels, predicted_labels)

总结
一般来说 NTLK 包适用于英文文档,而 jieba 适用于中文文档。我们可以根据文档选择不同的包,对文档提取分词。这些分词就是贝叶斯分类中最重要的特征属性。基于这些分词,我们得到分词的权重,即特征矩阵。

练习

在这个链接下下载数据集:https://github.com/cystanford/text_classification

train_contents=[]
train_labels=[]
test_contents=[]
test_labels=[]
#  导入文件
import os
import io
start=os.listdir(r'C:/Users/baihua/Desktop/text classification/train')
for item in start:test_path='C:/Users/baihua/Desktop/text classification/test/'+item+'/'train_path='C:/Users/baihua/Desktop/text classification/train/'+item+'/'for file in os.listdir(test_path):with open(test_path+file,encoding="GBK") as f:test_contents.append(f.readline())#print(test_contents)test_labels.append(item)for file in os.listdir(train_path):with open(train_path+file,encoding='gb18030', errors='ignore') as f:train_contents.append(f.readline())train_labels.append(item)
print(len(train_contents),len(test_contents))
# 导入stop word
import jieba
from sklearn import metrics
from sklearn.naive_bayes import MultinomialNB
#stop_words = [line.strip() for line in io.open(r'C:/Users/baihua/Desktop/stopword.txt').readlines()]
with open(r'C:/Users/baihua/Desktop/stopword.txt', 'rb') as f:stop_words = [line.strip() for line in f.readlines()]# 分词方式使用jieba,计算单词的权重
tf = TfidfVectorizer(tokenizer=jieba.cut,stop_words=stop_words, max_df=0.5)
train_features = tf.fit_transform(train_contents)
print(train_features.shape)#模块 4:生成朴素贝叶斯分类器
# 多项式贝叶斯分类器
clf = MultinomialNB(alpha=0.001).fit(train_features, train_labels)#模块 5:使用生成的分类器做预测
test_tf = TfidfVectorizer(tokenizer=jieba.cut,stop_words=stop_words, max_df=0.5, vocabulary=tf.vocabulary_)
test_features=test_tf.fit_transform(test_contents)
predicted_labels=clf.predict(test_features)
#模块六,计算准确性
from sklearn import metrics
print (metrics.accuracy_score(test_labels, predicted_labels))
#print(test_features.shape)
#print(metrics.accuracy_score(test_labels, predicted_labels))

参考文献
数据分析实战45讲
在线获取文本进行文本处理

朴素贝叶斯分类实战:对文档进行分类相关推荐

  1. 实战:手把手教你用朴素贝叶斯对文档进行分类

    朴素贝叶斯分类最适合的场景就是文本分类.情感分析和垃圾邮件识别.其中情感分析和垃圾邮件识别都是通过文本来进行判断.所以朴素贝叶斯也常用于自然语言处理 NLP 的工具. sklearn 机器学习包 sk ...

  2. 基于sklearn的朴素贝叶斯_朴素贝叶斯分类实战:对文档进行分类

    朴素贝叶斯分类最适合的场景就是文本分类.情感分析和垃圾邮件识别.其中情感分析和垃圾邮件识别都是通过文本来进行判断.所以朴素贝叶斯也常用于自然语言处理 NLP 的工具. sklearn 机器学习包 sk ...

  3. OpenCV计算机视觉实战(Python)| 10、项目实战:文档扫描OCR识别

    文章目录 简介 总结 1. 介绍 2. 流程 3. 程序 4. 知识点总结 简介 本节为<OpenCV计算机视觉实战(Python)>版第10讲,项目实战:文档扫描OCR识别,的总结. 总 ...

  4. 都在强力进阶学习 springboot 实战派文档

    不仅如此,本文还对比讲解了多种同类技术的使用和区别,读者可以根据自己的喜好进行选择. 开发模式:本文讲解了历史悠久,但现在依然被广泛使用的分层应用开发模式 MVC(ModelView Controll ...

  5. 花188购买的0基础短视频入门实战培训文档,学了一周的总结。

    花188购买的0基础短视频入门实战培训文档,学了一周的总结. 大家好,我是我赢助手,专注于自媒体短视频去水印.去重和文案提取运营! 为了更加专业的给大家讲讲短视频和自媒体,也为了能了解0基础怎么搞定短 ...

  6. 最新ChatGPT GPT-4 NLU实战之文档问答类ChatPDF功能(附ipynb与python源码及视频)——开源DataWhale发布入门ChatGPT技术新手从0到1必备使用指南手册(五)

    目录 前言 最新ChatGPT GPT-4 自然语言理解NLU实战之文档问答类ChatPDF功能 引言 ChatGPT 接口 Qdrant数据库Embedding存储 核心代码 测试 其它NLU应用及 ...

  7. 朴素贝叶斯分类-实战篇-如何进行文本分类

    微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 文章目录 1,对文档分词 2,计算单词权重 2.1,单词的 TF-IDF 值 2.2,TfidfVe ...

  8. java t9 字母组合_太赞了!美团T9终于整理出Java架构之完美设计实战开源文档

    软件架构师是每个程序员职业生涯中内功心法修炼的终极目标.要达到这个目标需要具备"十八般武艺,八十种技巧",本书正是继<Java代码与架构之完美优化--实战经典>< ...

  9. 全新java架构技术框架Quarkus实战神仙文档

    前言 Quarkus是一款有别于传统Java架构的新技术框架.它建立在我们熟知的技术栈上,使用了诸多成熟的技术,如JPA.JAX-RS.EclipseVert.x.Eclipse MicroProfi ...

最新文章

  1. 计算机视觉常用图像数据集标记平台
  2. mysql的字符串函数大全_MySQL的字符串函数大全
  3. Android使用SQLite数据库(1)
  4. Caddy-基于go的微型serve用来做反向代理和Gateway
  5. 解读服务器虚拟化的十大误区
  6. 女程序员 一直从事着软件研发的工作
  7. 使用Java泛型和反射机制编写Excel文件生成和解析的通用工具类
  8. iQOO Neo6入网:骁龙8旗舰平台+80W快充
  9. Windows上安装运行 cnpm, 来代替 npm
  10. 网络编程之 信号捕捉器(函数指针与回调函数)
  11. java 输出一个爱心_java基础 之 几个常用的类
  12. markdown格式的文章如何转换为可以发布在微信公众号上的内容
  13. InitializeSecurityDescriptor、InitializeAcl、AddAccessAllowedAce、SetSecurityDescriptorDacl
  14. Android Gradle构建脚本
  15. 阿里云虚拟主机、企业邮箱免费申请
  16. sklearn 纠偏
  17. Vue - 适配iPhoneX微信浏览器
  18. AVL_全选_取消全选_打印_ZMM1035
  19. qt creator使用vcpkg
  20. 提高影响力:职权+威信

热门文章

  1. @font-face详细用法+实例——Web响应式前端学习笔记
  2. laravel redis_Redis 之服务器集群配置
  3. 映射文件_Hibernate 映射文件
  4. mysql5.7主从同步与读写分离
  5. Azkaban报错:Missing required property ‘azkaban.native.lib’
  6. 进阶Linux大佬的奠基石
  7. RT-Thread Pin设备驱动API应用介绍
  8. mysql数据库内置函数大全_MySQL数据库——内置函数
  9. python考试编程题九道_一道逻辑推理题的程序实现(纯属娱乐)
  10. Mysql价格降低20%应该怎么写_mysql优化20条原则