当前位置: 首页 > news >正文

【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]))

训练算法:从词向量计算概率

上面是将一组单词转换为数字的过程,接下来看如何使用数字计算概率。

现在已经知道一个词是否出现在一篇文档中,也知道该文档所属的类别,我们就可以计算贝叶斯公式:

p(c_{i}|w)=\frac{p(w|c_{i})p(c_{i})}{p(w)}

我们使用上述公式,对每个类计算该值,然后比较这两个概率值的大小。首先可以通过类别i(侮辱性留言或非侮辱性留言)中文档数除以总的文档数来计算概率P(c_{i})。接下来计算P(w|c_{i}),这里就要用到朴素贝叶斯假设。如果将w展开为一个个独立特征,那么就可以将上述概率写作P(w_{0},w_{1},w_{2},w_{3},w_{4}...w_{n}|c_{i})。这里假设所有词都相互独立,该假设也称为条件独立性假设,它意味着可以使用P(w_{0}|c_{i})P(w_{1}|c_{i})P(w_{2}|c_{i})...P(w_{n}|c_{i})来计算上述概率,这就极大地简化了计算过程。

函数的伪代码如下:

计算每个类别中的文档数目

对每篇训练文档:

    对每个类别:

        如果词条出现在文档中->增加该词条的计数值

        增加所有词条的计数值

对每个类别:

    对每个词条:

        将该词条的数目除以总词条数目得到条件概率

返回每个类别的条件概率

下面,开始实现上述伪代码:

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)。对于多分类问题,则需要对代码进行修改。

计算P(w_{i}|c_{1})P(w_{i}|c_{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。下面是给定文档类别条件下词汇表中单词出现的频率。

测试算法:根据现实情况修改分类器

利用贝叶斯 分类器对文档进行分类时,要计算多个概率的乘积以获得文档属于某个类别的概率,即计算P(w_{0}|1)P(w_{1}|1)P(w_{2}|1)。如果其中一个概率值为0,那么最后的乘积也为0.为降低这种影响,可以将所有词的出现初始化为1,并将分母初始化为2.

修改代码:

    p0Num=ones(numWords)p1Num=ones(numWords)p0Denom=2.0p1Denom=2.0

另一个问题是下溢出,这是由于太多很小的数相乘造成的。当计算乘积时P(w_{0}|c_{i})P(w_{1}|c_{i})P(w_{2}|c_{i})...P(w_{n}|c_{i}),由于大部分因子都非常小,所以程序会下溢出或者得到不正确的答案。一种解决办法是对乘积取自然对数。在代数中有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太慢&#xff0c…...

刷题——快速排序

【全网最清晰快速排序&#xff0c;看完快排思想和代码全部通透&#xff0c;不通透你打我&#xff01;-哔哩哔哩】 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和翻墙在本质上是不同的。想要真正实现翻墙&#xff0c;需要选择部署在墙外的VPN服务。VPN也能隐藏用户的真实IP地址 要实现Python对网页数据的定时实时采集和输出&#xff0c;可以使用Python的定时任务调度模块。其中一个常用的库是APScheduler。您可以编写一个函数&#…...

自然语言处理(NLP)

自然语言处理&#xff08;NLP&#xff09;是计算机科学与人工智能领域的一个重要研究方向&#xff0c;它致力于让计算机能够理解、分析、处理和生成人类语言。在NLP领域&#xff0c;存在着许多常见的任务&#xff0c;这些任务通常对应着不同的算法和技术。以下将详细列举几个NL…...

Spring Boot集成Spire.doc实现对word的操作

1.什么是spire.doc? Spire.Doc for Java 是一款专业的 Java Word 组件&#xff0c;开发人员使用它可以轻松地将 Word 文档创建、读取、编辑、转换和打印等功能集成到自己的 Java 应用程序中。作为一款完全独立的组件&#xff0c;Spire.Doc for Java 的运行环境无需安装 Micro…...

在Spring Boot中优化if-else语句

在Spring Boot中&#xff0c;优化if-else语句是提升代码质量、增强可读性和可维护性的重要手段。过多的if-else语句不仅会使代码变得复杂难懂&#xff0c;还可能导致代码难以扩展和维护。以下将介绍七种在Spring Boot中优化if-else语句的实战方法&#xff0c;每种方法都将结合示…...

【Django】开源前端库bootstrap,常用

文章目录 下载bootstrap源文件到本地项目引入bootstrap文件 官网&#xff1a;https://www.bootcss.com/V4版本入口&#xff1a;https://v4.bootcss.com/V5版本入口&#xff1a;https://v5.bootcss.com/ 这里使用成熟的V4版本&#xff0c;中文文档地址&#xff1a;https://v4.b…...

2024后端开发面试题总结

一、前言 上一篇离职贴发布之后仿佛登上了热门&#xff0c;就连曾经阿里的师兄都看到了我的分享&#xff0c;这波流量真是受宠若惊&#xff01; 回到正题&#xff0c;文章火之后&#xff0c;一些同学急切想要让我分享一下面试内容&#xff0c;回忆了几个晚上顺便总结一下&#…...

opencascade AIS_Manipulator源码学习

前言 AIS_Manipulator 是 OpenCASCADE 库中的一个类&#xff0c;用于在3D空间中对其他交互对象或一组对象进行局部变换。该类提供了直观的操控方式&#xff0c;使用户可以通过鼠标进行平移、缩放和旋转等操作。 详细功能 交互对象类&#xff0c;通过鼠标操控另一个交互对象…...

Hadoop、Hive、HBase、数据集成、Scala阶段测试

姓名&#xff1a; 总分&#xff1a;Hadoop、Hive、HBase、数据集成、Scala阶段测试 一、选择题&#xff08;共20道&#xff0c;每道0.5分&#xff09; 1、下面哪个程序负责HDFS数据存储&#xff08; C &#xff09; A. NameNode B. Jobtracher C. DataNode D. Sec…...

go语言day19 使用git上传包文件到github Gin框架入门

git分布式版本控制系统_git切换head指针-CSDN博客 获取请求参数并和struct结构体绑定_哔哩哔哩_bilibili &#xff08;gin框架&#xff09; GO: 引入GIn框架_go 引入 gin-CSDN博客 使用git上传包文件 1&#xff09;创建一个github账户&#xff0c;进入Repositories个人仓…...

Ubuntu升级软件或系统

Ubuntu升级软件或系统 升级Ubuntu系统通常是一个相对简单的过程&#xff0c;但在进行操作之前&#xff0c;请务必备份重要数据以防万一。下面是升级Ubuntu系统的一般步骤&#xff1a; 使用软件更新工具升级系统 打开终端&#xff1a; 按下 Ctrl Alt T 组合键打开终端。 更…...

【Redis】Centos7 安装 redis(详细教程)

查看当前 Redis 版本&#xff1a; 当前的 redis 版本太老了&#xff0c;选择安装 Redis5。 一、使用 yum 安装 1、首先安装 scl 源 yum install centos-release-scl-rh 由于我之前已经安装过了&#xff0c;所以加载速度比较快&#xff0c;且显示已经安装成功&#xff0c;是最…...

Hakuin:一款自动化SQL盲注(BSQLI)安全检测工具

关于Hakuin Hakuin是一款功能强大的SQL盲注漏洞安全检测工具&#xff0c;该工具专门针对BSQLi设计&#xff0c;可以帮助广大研究人员优化BSQLi测试用例&#xff0c;并以自动化的形式完成针对目标Web应用程序的漏洞扫描与检测任务。 该工具允许用户以轻松高效的形式对目标Web应…...

在 Postman 中设置全局 token

目录 问题描述解决方案 问题描述 在使用 Postman 进行接口测试时&#xff0c;经常会遇到在 Header 中添加 token 的情况。当接口数量较多时&#xff0c;需要为每个接口进行设置&#xff0c;而且当 token 失效时需要重新获取并设置&#xff0c;这样一来效率较低。 解决方案 下…...

Linux C编程:打造一个插件系统

title: ‘Linux C编程:打造一个插件系统’ date: 2017-03-07 21:16:36 tags: linux C layout: post comments: true 运行环境&#xff1a;linux 使用语言&#xff1a;c 或者c 插件&#xff0c;很多人用过&#xff0c;比如游戏插件&#xff0c;编辑器插件这些&#xff0c; 最著…...

基于毫米波生物感知雷达+STM32设计的独居老人居家监护系统(微信小程序)(192)

基于毫米波生物感知雷达设计的独居老人居家监护系统(微信小程序)(192) 文章目录 一、前言1.1 项目介绍【1】项目功能介绍【2】项目硬件模块组成1.2 设计思路【1】整体设计思路【2】60G毫米波生物感知雷达原理【3】ESP8266模块配置【4】供电方式1.3 项目开发背景【1】选题的意义…...

C++——类和对象(下)

目录 一、再探构造函数 1.基本定义以及用法 2.必须在初始化列表初始化的成员变量 3.成员变量声明位置的缺省值&#xff08;C11&#xff09; 4.成员变量初始化顺序 二、隐式类型转换 三、static成员 四、友元 五、内部类 六、匿名对象 七、日期类实现 一、再探构造函数…...

Android中集成前端页面探索(Capacitor 或 Cordova 插件)待完善......

探索目标&#xff1a;Android中集成前端页面 之前使用的webview加载html页面&#xff0c;使用bridge的方式进行原生安卓和html页面的通信的方式&#xff0c;探索capacitor-android插件是如何操作的 capacitor-android用途 Capacitor 是一个用于构建现代跨平台应用程序的开源框…...

玩转CSS:用ul li +JS 模拟select,避坑浏览器不兼容。

玩转CSS&#xff1a;用ul li JS 模拟select&#xff0c;避坑浏览器不兼容。 在前端的工作中&#xff0c;经常会遇到 selcet控件&#xff0c;但我们用css来写它的样式时候&#xff0c;总是不那么令人满意&#xff0c;各种浏览器不兼容啊有没有&#xff1f; 那么&#xff0c;我…...

介绍下PolarDB

业务中用的是阿里云自研的PolarDB&#xff0c;分析下PolarDB的架构。 认识PolarDB 介绍 PolarDB是阿里云自研的&#xff0c;兼容MySQL、PostageSQL以及支持MPP的PolarDB-X的高可用、高扩展性的数据库。 架构 部署 云起实验室 - 阿里云开发者社区 - 阿里云 (aliyun.com) 数…...

基于微信小程序+SpringBoot+Vue的儿童预防接种预约系统(带1w+文档)

基于微信小程序SpringBootVue的儿童预防接种预约系统(带1w文档) 基于微信小程序SpringBootVue的儿童预防接种预约系统(带1w文档) 开发合适的儿童预防接种预约微信小程序&#xff0c;可以方便管理人员对儿童预防接种预约微信小程序的管理&#xff0c;提高信息管理工作效率及查询…...

go语言day15 goroutine

Golang-100-Days/Day16-20(Go语言基础进阶)/day17_Go语言并发Goroutine.md at master rubyhan1314/Golang-100-Days GitHub 第2讲-调度器的由来和分析_哔哩哔哩_bilibili 一个进程最多可以创建多少个线程&#xff1f;-CSDN博客 引入协程 go语言中内置了协程goroutine&#…...

Mindspore框架循环神经网络RNN模型实现情感分类|(六)模型加载和推理(情感分类模型资源下载)

Mindspore框架循环神经网络RNN模型实现情感分类 Mindspore框架循环神经网络RNN模型实现情感分类|&#xff08;一&#xff09;IMDB影评数据集准备 Mindspore框架循环神经网络RNN模型实现情感分类|&#xff08;二&#xff09;预训练词向量 Mindspore框架循环神经网络RNN模型实现…...

System类

System类常见方法 ① exit 退出当前程序 public static void main(String[] args) {System.out.println("ok1");//0表示状态&#xff0c;即正常退出System.exit(0);System.out.println("ok2");} ② arraycopy 复制数组元素 复制的数组元素个数必须<原数…...