查看原文
其他

朴素贝叶斯算法——以20Newsgroups数据集为例

爬虫俱乐部 Stata and Python数据分析 2022-03-15

本文作者:陈   鼎 中南财经政法大学统计与数学学院

文字编辑:任   哲

技术总编:张馨月

爬虫俱乐部云端课程

  爬虫俱乐部于2020年暑期在线上举办的Stata与Python编程技术训练营和Stata数据分析法律与制度专题训练营在不久前已经圆满结束啦~应广大学员需求,我们的课程现已在腾讯课堂全面上线,且继续提供答疑服务。现在关注公众号并在朋友圈转发推文《来腾讯课堂学Stata和Python啦》或《8月Stata数据分析法律与制度专场来啦!》,即可获得600元课程优惠券,集赞50个再领200元课程优惠券!(截图发至本公众号后台领取)原价2400元的课程,现在只要1600元!   

朴素贝叶斯分类器是由英国数学家托马斯·贝叶斯提出的。该模型使用概率统计的知识对样本数据集进行分类,通过计算条件概率进行最终决策。朴素贝叶斯分类器的基本思想是,若在给定条件下,预测的某个样本属于某个类别的条件概率最大,则将该样本判定为该类别。朴素贝叶斯分类器在数据集较大的情况下表现出较高的准确率,同时算法本身也较为简单。在之前的推文《基于贝叶斯定理的算法——朴素贝叶斯分类》中,我们对该算法进行过简单了解。今天,本文基于20Newsgroups数据集,利用朴素贝叶斯算法,对20Newsgroups数据集进行文本分类,并对其分类结果进行简要阐述。

一、算法简介

(一)朴素贝叶斯模型

设有样本数据集D = {d1,d2,d3,.....,dn},对应样本数据的特征属性为X = {x1,x2,x3,.....,xn1},类变量为Y = {y1,y2,y3,.....,yn2}(即我们所预测的分类结果可以是第ym类(m=1,2,3,...,n2))。样本数据的特征属性之间相互独立,由贝叶斯公式可知,在给定特征值(x1,x2,x3,....,xn1)的条件下,我们预测的样本属于第ym类(m=1,2,3,...,n2)的条件概率为:
分析上述公式,容易得出,在给定一个样本的状态下,P(x1,x2,x3,....,xn1)的概率值是固定不变的,与类变量无关。因此,要想比较在某个给定样本下该样本属于不同类别的后验概率,仅需比较P(x1,x2,x3,...,xn1|ym)P(ym)部分即可。因此,我们有如下判别公式:
在朴素贝叶斯模型中,不同的特征属性相互独立,因此,上述公式等价于:
需注意,如果某个属性值在训练集中没有与某个类别同时出现过,以上述判别公式计算后验概率时,将出现概率为0的问题。为了避免其他属性携带的信息被训练集的不充分所抹去,常用拉普拉斯平滑给予修正。
α的系数一般为1,Ni为在ym类别中xi特征出现的次数,N为在ym类别下所有特征出现的次数和,m为训练样本中统计的特征个数。显然,拉普拉斯修正避免了因为训练集样本的不充分导致的概率估计值为0的问题。

(二)20Newsgroups数据集与文本分类

20Newsgroups数据集收录了共18000篇新闻文章(D={d1,d2,....,d18000}),涉及20种新闻分类(Y={y1,y2,y3,..,y20})。该数据集常用于文本分类,即在给定的一篇文章中,统计文章中出现的重点词频数,根据重点词的频数分布判定文章所属的类别。数据集中的新闻文本内容及新闻分类如图所示:
图1.数据集的新闻文本内容
图2.数据集的新闻分类(即y1,y2,...,y20)

二、代码实现

(一)导入数据集

from sklearn.datasets import fetch_20newsgroups #导入模块
news_data = fetch_20newsgroups(subset="all") #读取数据

(二)划分训练集,测试集

将导入的20Newsgroups数据集划分为训练集与测试集,利用训练集训练模型,用测试集测试模型的预测结果与预测精度。通常使用sklearn.model_selection模块中的train_test_split方法对数据集进行划分,实现过程如下:
from sklearn.model_selection import train_test_split #导入模块
x_train,x_test,y_train,y_test = train_test_split(news.data,news.target,test_size=0.25)
其中,各变量及参数的含义如下:
变量
含义
x_train
训练集中的新闻文本数据
x_test
测试集中的新闻文本数据
y_train
训练集中的数据特征对应的新闻分类结果
y_test
测试集中的数据特征对应的新闻分类结果
test_size
用于设定测试集占数据集的样本比例,test_size=0.25表示测试集占总数据集比例的25%

(三)数据的预处理——特征工程

特征工程,是将原始数据转化为特征的过程。这些特征可以更好地向预测模型描述潜在问题,从而提高模型对未见数据的准确性。特征工程直接影响着模型的预测结果。在本案例中,我们需要将新闻文本数据进行特征工程处理,即将新闻文本进行分词,统计每个词的出现频数,将具有代表性的词汇与文本分类结果对应。
常用于文本分类的特征工程为Tfidf(Term Frequency-Inverse Document Frequency, 词频-逆文件频率)。它是一种常见的加权统计方法,用于评估每个词汇对每篇文章的重要程度。其基本思想为:如果某个词在某一篇文章中出现的频率较高,而在其他文章中很少出现,则认为这个词具有很好的类别区分能力。我们导入sklearn.feature_extraction.text中的TfidfVectorizer方法,即可对新闻文本数据进行重点词抽取。
from sklearn.feature_extraction.text import TfidfVectorizer
tf = TfidfVectorizer() #实例化
x_train = tf.fit_transform(x_train) #将训练集中的新闻文本数据进行特征抽取,返回一个sparse矩阵
x_test = tf.transform(x_test) #将测试集中的新闻文本数据进行特征抽取,返回一个sparse矩阵

(四)使用朴素贝叶斯分类器进行分类

首先,导入所需的API模块。
from sklearn.naive_bayes import MultinomialNB

实例化一个朴素贝叶斯分类器,并将我们的训练集特征与训练集特征对应的分类结果导入到模型中,供分类器学习。
bayes = MultinomialNB(alpha=1.0) #alpha为拉普拉斯修正的α
bayes.fit(x_train,y_train)

传入测试集,进行预测,并打印预测结果与预测精度。
y_predict = bayes.predict(x_test)
print("测试集的预测结果为:",y_predict)
print("模型的预测准确率为:",bayes.score(x_test,y_test))
图3.显示预测结果与预测精度

分析上述预测结果与预测精度可以看出,测试集中的第一篇文章被分类为第11类,第二篇文章被分类为第17类……,模型预测的准确率为84.65%,属于相对可以接受的范围。
到这里,我们就完成了朴素贝叶斯算法的基本实现。最后,我们来简单总结一下它的优缺点。
该算法的优点在于:
(1)朴素贝叶斯发源于古典概率统计理论,很好地利用了先验信息,具有相对稳定的分类效率;
(2)对缺失值数据不太敏感,算法较为简单,具有一定的鲁棒性;
(3)分类的速度相对较快,准确率也相对较高。
但是,朴素贝叶斯分类器也有如下几个缺点:
(1)依赖于利用训练集来计算先验概率,如果训练集的表现不佳,则对模型的预测结果也会有一定影响;
(2)朴素贝叶斯分类器假设每个特征之间是相互独立的,但是在文本分类中,不同词之间的出现频率往往不是互相独立的;
(3)朴素贝叶斯分类器没有超参数供我们进行调参,模型相对较难优化。

三、源码

from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import train_test_split
from sklearn.datasets import fetch_20newsgroups

def naive_bayes():
#1.读取数据
news_data = fetch_20newsgroups(subset="all")
#2.划分训练集,测试集
x_train,x_test,y_train,y_test = train_test_split(news_data.data,news_data.target,test_size=0.25)
#3.进行特征抽取
tf = TfidfVectorizer()
x_train = tf.fit_transform(x_train)
x_test = tf.transform(x_test)
#4.进行朴素贝叶斯算法分类
bayes = MultinomialNB(alpha=1.0)
bayes.fit(x_train,y_train)
y_predict = bayes.predict(x_test)
print("测试集的预测结果为:",y_predict)
print("模型的预测准确率为:",bayes.score(x_test,y_test))

if __name__ == '__main__':
naive_bayes()





对我们的推文累计打赏超过1000元,我们即可给您开具发票,发票类别为“咨询费”。用心做事,不负您的支持!

往期推文推荐

【爬虫实战】利用scrapy框架爬取豆瓣图书信息

《我和我的家乡》影评高频词原来是这些!

一位大学党委书记的自我结束——风波里的学者本真

Seminar | JPX400指数的公司治理效应
Seminar | 企业社会责任披露如何影响企业绩效?
【爬虫实战】恒大的底气?--恒大楼盘数量爬取
Python遇上Stata--IPyStata介绍
变量类型转换之encode&decode命令
Seminar | 主动型基金:我还行吗?

Seminar | CEO的哪些特征和能力更重要?

用词云图看Sustainability期刊热门题目

用Python把新婚祝福打满公屏!

震惊!知名数据分析软件竟被某度翻译“亲切称呼”为“斯塔塔”

喜临涛门,月满人圆

Python3.8新秀海象符成功出道
“合”我在一起—merge
在Sustainability上发文最多的原来是这些高校

Python中的这些运算符你真的会用吗?

字符串函数总动员

关于我们


微信公众号“Stata and Python数据分析”分享实用的stata、python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。

此外,欢迎大家踊跃投稿,介绍一些关于stata和python的数据处理和分析技巧。
投稿邮箱:statatraining@163.com
投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存