【Python机器学习】朴素贝叶斯——使用Python进行文本分类
目录
准备文本:从文本中构建词向量
训练算法:从词向量计算概率
测试算法:根据现实情况修改分类器
准备数据:文档词袋模型
要从文本中获取特征,需要先拆分文本。这里的特征是来自文本的词条,一个词条是字符的任意组合。可以把词条想象为单词,也可以使用非单词词条,如URL、IP地址或者任意其他字符串。然后将每一个文本片段表示为一个词条向量,其中值为1表示词条出现在文本中,0表示词条未出现。
以社区的留言板为例。为了不影响社区的发展,我们要屏蔽侮辱性的言论,所以要构建一个快速过滤器,如果发现某条留言使用了负面或者侮辱性的语言,那么就将该留言标识为内容不当。过滤这类内容是一个很常见的需求。对此问题建立两个类别:侮辱性和非侮辱性,使用1和0分别表示。
下面是将文本转换为数字向量的过程,然后基于这些向量来计算条件概率,并在此基础上构建分类器,最后是一些利用Python实现朴素贝叶斯过程中需要考虑的问题。
准备文本:从文本中构建词向量
我们将把文本看成单词向量或者词条向量,也就是说将句子转换成向量。考虑出现在所有文档中的所有单词,再决定将哪些词纳入词汇表或者说所要的词汇集合,然后必须要将每一篇文档转换成词汇表上的向量。
def loadDataSet():postingList=[['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],['stop', 'posting', 'stupid', 'worthless', 'garbage'],['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]classVec = [0,1,0,1,0,1] #1 is abusive, 0 notreturn postingList,classVecdef createVocabList(dataSet):#创建一个空集vocabSet=set([])for document in dataSet:#创建两个集合的并集vocabSet=vocabSet|set(document)return list(vocabSet)def setOfWords2Vec(vocabList,inputSet):#创建一个其中包含元素都是0的向量returnVec=[0]*len(vocabList)for word in inputSet:if word in vocabList:#如果词汇出现在词汇表中,向量对应值为1,否则为0returnVec[vocabList.index(word)]=1else:print('%s 这个单词不在词汇表中!')return returnVec
上述代码中,第一个函数loadDataSet()创建了一些实验样本。该函数返回的第一个变量是进行词条切割后的文档集合,这些文档来自够累爱好者留言板。这些留言文本被切分成一系列的此条集合,标点符号从文本中去掉。loadDataSet()返回的第二个变量是一个类别标签的集合。这里有两类:侮辱性和非侮辱性。这些文本的类别由人工标注,这些标注信息用于训练程序一遍自动检测侮辱性留言。
createVocabList(dataSet)会创建一个包含在所有文档中出现的不重复词的列表,为此使用了Python的set数据类型。将词条列表输给set构造函数,set就会返回一个不重复词表。
获得词表后,使用setOfWords2Vec(vocabList,inputSet),该函数的输入参数为词汇表及某个文档,输出的是文档向量,向量的每一元素为1或0,分别表示词汇表中的单词在输入文档中是否出现。
观察效果:
listOPosts,listClasses=loadDataSet()
myVocabList=createVocabList(listOPosts)
print(myVocabList)

检查词表,可以看到这里没有重复的单词。
看下setOfWords2Vec()效果:
print(setOfWords2Vec(myVocabList,listOPosts[0]))
print(setOfWords2Vec(myVocabList,listOPosts[3]))

训练算法:从词向量计算概率
上面是将一组单词转换为数字的过程,接下来看如何使用数字计算概率。
现在已经知道一个词是否出现在一篇文档中,也知道该文档所属的类别,我们就可以计算贝叶斯公式:
我们使用上述公式,对每个类计算该值,然后比较这两个概率值的大小。首先可以通过类别i(侮辱性留言或非侮辱性留言)中文档数除以总的文档数来计算概率。接下来计算
,这里就要用到朴素贝叶斯假设。如果将w展开为一个个独立特征,那么就可以将上述概率写作
。这里假设所有词都相互独立,该假设也称为条件独立性假设,它意味着可以使用
来计算上述概率,这就极大地简化了计算过程。
函数的伪代码如下:
计算每个类别中的文档数目
对每篇训练文档:
对每个类别:
如果词条出现在文档中->增加该词条的计数值
增加所有词条的计数值
对每个类别:
对每个词条:
将该词条的数目除以总词条数目得到条件概率
返回每个类别的条件概率
下面,开始实现上述伪代码:
def trainNBO(trainMatrix,trainCategory):numTrainDocs=len(trainMatrix)numWords=len(trainMatrix[0])pAbusive=sum(trainCategory)/float(numTrainDocs)#初始化概率p0Num=zeros(numWords)p1Num=zeros(numWords)p0Denom=0.0p1Denom=0.0#对每篇训练文档for i in range(numTrainDocs):#如果词条出现在文档中if trainCategory[i]==1:p1Num=p1Num+trainMatrix[i]p1Denom=p1Denom+sum(trainMatrix[i])else:p0Num=p0Num+trainMatrix[i]p0Denom=p0Denom+sum(trainMatrix[i])#对每个元素做除法p1Vect=p1Num/p1Denomp0Vect=p0Num/p0Denomreturn p0Vect,p1Vect,pAbusive
代码函数中的输入参数为文档矩阵trainMatrix以及由每篇文档类别标签所构成的向量trainCategory。首先,计算文档属于侮辱性文档(class=1)的概率,即P(1)。因为这是一个二类分类问题,所以可以通过1-P(1)得到P(0)。对于多分类问题,则需要对代码进行修改。
计算和
,需要初始化程序中的分子变量和分母变量。由于w中元素非常多,因此可以使用NumPy数组快速计算这些值。分母变量是一个元素个数等于词汇表大小的NumPy素组。在gor循环中,要遍历训练集trainMatrix中所有的文档。一旦某个词语(侮辱性或者正常词语)在某一文档出现,则该词对应的个数(p1Num或者p0Num)就加一。而且在所有的文档中,该文档的总次数也相应加一。对于两个类别都要进行同样的处理。
最后,对每个元素除以该类别中的总次数。利用NumPy很好实现,用一个数组除以浮点数即可,最后函数会返回两个向量和一个概率。
运行:
listOPosts,listClasses=loadDataSet()
myVocabList=createVocabList(listOPosts)
trainMat=[]
for postinDoc in listOPosts:trainMat.append(setOfWords2Vec(myVocabList,postinDoc))
p0V,p1V,pAb=trainNBO(trainMat,listClasses)
print(pAb)
print(p0V)

这就是任意文档属于侮辱性文档的概率。
我们发现文档属于侮辱性文档的概率pAb为0.5。下面是给定文档类别条件下词汇表中单词出现的频率。
测试算法:根据现实情况修改分类器
利用贝叶斯 分类器对文档进行分类时,要计算多个概率的乘积以获得文档属于某个类别的概率,即计算。如果其中一个概率值为0,那么最后的乘积也为0.为降低这种影响,可以将所有词的出现初始化为1,并将分母初始化为2.
修改代码:
p0Num=ones(numWords)p1Num=ones(numWords)p0Denom=2.0p1Denom=2.0
另一个问题是下溢出,这是由于太多很小的数相乘造成的。当计算乘积时,由于大部分因子都非常小,所以程序会下溢出或者得到不正确的答案。一种解决办法是对乘积取自然对数。在代数中有ln(a*b)=ln(a)+ln(b),于是通过求对数可以避免下溢出或者浮点数舍入导致的错误。同时,采用自然对数进行处理不会有任何损失。
修改代码:
p1Vect=log(p1Num/p1Denom)p0Vect=log(p0Num/p0Denom)
现在已经准备好构造完整的分类器了。当使用NumPy向量处理功能时,这会十分简单:
def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1):#元素相乘p1=sum(vec2Classify*p1Vec)+log(pClass1)p0=sum(vec2Classify*p0Vec)+log(1.0-pClass1)if p1>p0:return 1else:return 0def testingNB():listOPosts,listClasses=loadDataSet()myVocabList=createVocabList(listOPosts)trainMat=[]for postinDoc in listOPosts:trainMat.append(setOfWords2Vec(myVocabList, postinDoc))p0V, p1V, pAb = trainNBO(trainMat, listClasses)testEntry=['love','my','dalmation']thisDoc=array(setOfWords2Vec(myVocabList,testEntry))print(testEntry,'classified as :',classifyNB(thisDoc,p0V,p1V,pAb))testEntry=['stupid','garbage']thisDoc=array(setOfWords2Vec(myVocabList,testEntry))print(testEntry,'classified as :',classifyNB(thisDoc,p0V,p1V,pAb))
classifyNB()函数有4个输入参数:要分类的向量vec2Classify,以及使用函数trainNB0()计算得到的三个概率值。使用NumPy的数组来计算两个向量相乘的结果。这里的相乘是指对应元素相乘,即先将两个向量中的第一个元素相乘,然后将第二个元素相乘,以此类推。接下来将词汇表中所有词的对应值相加,然后将该值加到类别的对数概率上。最后,比较类别的概率返回大概率对应的类别标签。
代码的第二个函数是一个便利函数,该函数封装所有操作,以节省时间。
运行结果:

上述例子展示了朴素贝叶斯分类器的工作原理。
准备数据:文档词袋模型
我们将每个词的出现与否作为一个特征,这可以被表述了词集模型。如果一个词在文档中出现不止一次,这可能意味着包含该词是否出现在文档中所不能表达的某种信息,这种方法被称为词袋模型。在词袋中,每个单词可以出现多次,而在词集中,每个词只能出现一次。为了适应词袋模型,需要对上面的setOfWords2Vec()稍作修改,修改后的函数称为bagOfWords2Vec()。
def bagOfWords2Vec(vocabList,inputSet):#创建一个其中包含元素都是0的向量returnVec=[0]*len(vocabList)for word in inputSet:if word in vocabList:#如果词汇出现在词汇表中,向量加1returnVec[vocabList.index(word)]=returnVec[vocabList.index(word)]+1return returnVec
相关文章:
【Python机器学习】朴素贝叶斯——使用Python进行文本分类
目录 准备文本:从文本中构建词向量 训练算法:从词向量计算概率 测试算法:根据现实情况修改分类器 准备数据:文档词袋模型 要从文本中获取特征,需要先拆分文本。这里的特征是来自文本的词条,一个词条是字…...
【linux】Shell脚本三剑客之grep和egrep命令的详细用法攻略
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全…...
Spring条件装配:灵活配置你的应用
文章目录 摘要1. 条件装配概述1.1 什么是条件装配1.2 为什么需要条件装配 2. 使用Conditional注解2.1 Conditional注解简介2.2 编写自定义条件类2.3 应用Conditional注解 3. 内置的条件注解3.1 ConditionalOnClass3.2 ConditionalOnMissingBean3.3 ConditionalOnProperty 4. 使…...
【前端 08】简单学习js字符串
JavaScript中的String对象详解 在JavaScript中,字符串(String)是一种非常基础且常用的数据类型,用于表示文本数据。虽然JavaScript中的字符串是原始数据类型,但它们的行为类似于对象,因为JavaScript为字符…...
【LLM】-07-提示工程-聊天机器人
目录 1、给定身份 1.1、基础代码 1.2、聊天机器人 2、构建上下文 3、订餐机器人 3.1、窗口可视化 3.2、构建机器人 3.3、创建JSON摘要 利用会话形式,与具有个性化特性(或专门为特定任务或行为设计)的聊天机器人进行深度对话。 在 Ch…...
AvaloniaUI的学习
相关网站 github:https://github.com/AvaloniaUI/Avalonia 官方中文文档:https://docs.avaloniaui.net/zh-Hans/docs/welcome IDE选择 VS2022VSCodeRider 以上三种我都尝试过,体验Rider最好。VS2022的提示功能不好,VSCode太慢,…...
刷题——快速排序
【全网最清晰快速排序,看完快排思想和代码全部通透,不通透你打我!-哔哩哔哩】 https://b23.tv/8GxEKIk 代码详解如上 #include <iostream> using namespace std;int getPort(int* a, int low, int high) {int port a[low];while(low…...
VPN,实时数据显示,多线程,pip,venv
VPN和翻墙在本质上是不同的。想要真正实现翻墙,需要选择部署在墙外的VPN服务。VPN也能隐藏用户的真实IP地址 要实现Python对网页数据的定时实时采集和输出,可以使用Python的定时任务调度模块。其中一个常用的库是APScheduler。您可以编写一个函数&#…...
自然语言处理(NLP)
自然语言处理(NLP)是计算机科学与人工智能领域的一个重要研究方向,它致力于让计算机能够理解、分析、处理和生成人类语言。在NLP领域,存在着许多常见的任务,这些任务通常对应着不同的算法和技术。以下将详细列举几个NL…...
Spring Boot集成Spire.doc实现对word的操作
1.什么是spire.doc? Spire.Doc for Java 是一款专业的 Java Word 组件,开发人员使用它可以轻松地将 Word 文档创建、读取、编辑、转换和打印等功能集成到自己的 Java 应用程序中。作为一款完全独立的组件,Spire.Doc for Java 的运行环境无需安装 Micro…...
在Spring Boot中优化if-else语句
在Spring Boot中,优化if-else语句是提升代码质量、增强可读性和可维护性的重要手段。过多的if-else语句不仅会使代码变得复杂难懂,还可能导致代码难以扩展和维护。以下将介绍七种在Spring Boot中优化if-else语句的实战方法,每种方法都将结合示…...
【Django】开源前端库bootstrap,常用
文章目录 下载bootstrap源文件到本地项目引入bootstrap文件 官网:https://www.bootcss.com/V4版本入口:https://v4.bootcss.com/V5版本入口:https://v5.bootcss.com/ 这里使用成熟的V4版本,中文文档地址:https://v4.b…...
2024后端开发面试题总结
一、前言 上一篇离职贴发布之后仿佛登上了热门,就连曾经阿里的师兄都看到了我的分享,这波流量真是受宠若惊! 回到正题,文章火之后,一些同学急切想要让我分享一下面试内容,回忆了几个晚上顺便总结一下&#…...
opencascade AIS_Manipulator源码学习
前言 AIS_Manipulator 是 OpenCASCADE 库中的一个类,用于在3D空间中对其他交互对象或一组对象进行局部变换。该类提供了直观的操控方式,使用户可以通过鼠标进行平移、缩放和旋转等操作。 详细功能 交互对象类,通过鼠标操控另一个交互对象…...
Hadoop、Hive、HBase、数据集成、Scala阶段测试
姓名: 总分:Hadoop、Hive、HBase、数据集成、Scala阶段测试 一、选择题(共20道,每道0.5分) 1、下面哪个程序负责HDFS数据存储( C ) A. NameNode B. Jobtracher C. DataNode D. Sec…...
go语言day19 使用git上传包文件到github Gin框架入门
git分布式版本控制系统_git切换head指针-CSDN博客 获取请求参数并和struct结构体绑定_哔哩哔哩_bilibili (gin框架) GO: 引入GIn框架_go 引入 gin-CSDN博客 使用git上传包文件 1)创建一个github账户,进入Repositories个人仓…...
Ubuntu升级软件或系统
Ubuntu升级软件或系统 升级Ubuntu系统通常是一个相对简单的过程,但在进行操作之前,请务必备份重要数据以防万一。下面是升级Ubuntu系统的一般步骤: 使用软件更新工具升级系统 打开终端: 按下 Ctrl Alt T 组合键打开终端。 更…...
【Redis】Centos7 安装 redis(详细教程)
查看当前 Redis 版本: 当前的 redis 版本太老了,选择安装 Redis5。 一、使用 yum 安装 1、首先安装 scl 源 yum install centos-release-scl-rh 由于我之前已经安装过了,所以加载速度比较快,且显示已经安装成功,是最…...
Hakuin:一款自动化SQL盲注(BSQLI)安全检测工具
关于Hakuin Hakuin是一款功能强大的SQL盲注漏洞安全检测工具,该工具专门针对BSQLi设计,可以帮助广大研究人员优化BSQLi测试用例,并以自动化的形式完成针对目标Web应用程序的漏洞扫描与检测任务。 该工具允许用户以轻松高效的形式对目标Web应…...
在 Postman 中设置全局 token
目录 问题描述解决方案 问题描述 在使用 Postman 进行接口测试时,经常会遇到在 Header 中添加 token 的情况。当接口数量较多时,需要为每个接口进行设置,而且当 token 失效时需要重新获取并设置,这样一来效率较低。 解决方案 下…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
