【机器学习】Lesson 4 - 朴素贝叶斯(NB)文本分类

目录

背景

一、适用数据集

1. 数据集选择

1.1 适用领域

1.2 数据集维度(特征数)

1.3 数据行数

2. 本文数据集介绍

2.1 数据集特征

2.2 数据格式

3. 数据集下载

二、算法原理

1. 朴素贝叶斯定理

2. 算法逻辑

3. 运行步骤

4. 更多延申模型

三、代码

1. 导入所需包&数据

2. 数据预处理

3. 数据探索

3.1 特征工程

3.2 异常值处理

4. 数据准备

4.1 文本处理

4.2 矢量化

5. 模型建构

6. 模型评价


背景

朴素贝叶斯(Naive Bayes)是一种基于贝叶斯定理(即条件概率)的简单高效的分类算法,广泛应用于文本分类和其他监督学习任务。朴素贝叶斯算法假设特征之间相互独立,这一假设使得算法运算简洁,适合处理高维度数据。

本文将使用朴素贝叶斯对垃圾邮件进行分类,数据集以及完整跑通代码见文首绑定资源。

一、适用数据集

朴素贝叶斯算法具有高效性和良好的扩展性,适合处理高维度(数千到数万特征)和大规模(数千到百万级数据行)的数据集,特别是在特征相对独立的情况下,性能会更加优越。在实际应用中,具体的维度和数据行数量还需根据可用的计算资源和任务复杂性进行评估。

1. 数据集选择

朴素贝叶斯(NB)适用于文本分类问题,练习时在选择数据集是可参考以下 3 个方面。反过来,如果在为项目选择合适的算法模型时,数据集符合以下条件时,可考虑选用朴素贝叶斯进行分析处理。

1.1 适用领域

文本分类

  • 垃圾邮件过滤:朴素贝叶斯是邮件分类中的经典方法,可以有效区分垃圾邮件和正常邮件。其假设每个词语独立贡献信息,有助于快速判断邮件的类别。
  • 情感分析:可用于情感分析任务,特别是判断评论或社交媒体上的文本情绪(如积极或消极)。这种任务的文本数据特征可以独立统计,因此朴素贝叶斯通常表现较好。
  • 文档主题识别:朴素贝叶斯广泛应用于文档主题识别任务中,通过统计每个类别的关键词出现概率,帮助区分文档的主要主题。比如,将一批文档区分为“技术”、“金融”、“健康”等类别。

内容推荐:在简单推荐系统中用于根据用户历史行为对内容进行分类和推荐,尤其是文本型内容。例如,对一组产品描述或影评进行分类,为用户推荐相关产品。

医疗诊断:在医学应用中,用于对症状组合的分类和预测,例如根据病人症状预测疾病类型。其优势在于能通过独立假设快速处理较多的特征,适合于诊断大量症状的医学数据。

欺诈检测:用于检测金融交易的欺诈行为,通过朴素贝叶斯快速学习欺诈模式并做出分类,例如区分正常交易和可疑交易。

语言识别和拼写纠正:用于语言识别任务中,区分文本语言类型(如英语和法语)。在拼写纠正中,基于历史数据统计拼写错误的发生概率,识别最可能的正确拼写。

1.2 数据集维度(特征数)

朴素贝叶斯能够有效处理数千到数万甚至更多的特征。尤其在文本分类中,特征数通常较高(如词汇表中的单词数)。

1.3 数据行数

朴素贝叶斯能够处理千级、万级到百万级的数据行,许多文本分类任务中的数据集(如电子邮件、社交媒体数据等)都能在此范围内良好工作。

由于其基于概率的计算方式,朴素贝叶斯的训练时间复杂度为 O(n \cdot d),其中 n 是样本数量,d 是特征数量。这使得它在内存和计算资源有限的情况下依然能高效运行。

2. 本文数据集介绍

SMS Spam Collection Dataset 包含来自真实用户的短信,是一个广泛用于文本分类和机器学习研究的经典数据集,专门用于垃圾短信(spam)和正常短信(ham)的分类。常被用于测试各种机器学习算法,尤其是朴素贝叶斯算法。

2.1 数据集特征

  • 样本数量:数据集中包含 5,572 条短信记录。
  • 特征描述
    • Target:短信的类别,取值为 "spam" 或 "ham"。
    • Text:短信的文本内容。

2.2 数据格式

数据集通常以 CSV 格式存储,每行对应一条短信记录。具体的列结构如下:

TargetText
hamGo until jurong point, crazy.. Available only in bugis n great world la e buffet... Cine there got amore wat...
spamFree entry in 2 a wkly comp to win FA Cup final tkts 21st May 2005. Text FA to 87121 to receive entry question(std txt rate)T&C's apply 08452810075over18's

3. 数据集下载

数据集下载地址:https://www.kaggle.com/datasets/uciml/sms-spam-collection-dataset

也可以在文章绑定资源中直接下载获取。

二、算法原理

1. 朴素贝叶斯定理

朴素贝叶斯基于贝叶斯定理:

P(A \mid B) = \frac{P(B \mid A) \cdot P(A)}{P(B)}

其中,P(A∣B) 是在已知条件 B 下事件 A 的后验概率。对于朴素贝叶斯算法,算法通过最大化后验概率来判断类别标签。朴素假设意味着各特征之间独立,因此可以将联合概率简化为各个特征的独立概率的乘积,这样大大减少了计算复杂度。得到联合概率分布后,概率估计方法可以是极大似然估计或贝叶斯估计。

2. 算法逻辑

朴素贝叶斯法的基本假设是条件独立性,


这是一个较强的假设。由于这一假设,模型包含的条件概率的数量大为减少,朴素贝叶斯法的学习与预测大为简化。因而朴素贝叶斯法高效,且易于实现。其缺点是分类的性能不一定很高。

朴素贝叶斯法利用贝叶斯定理与学到的联合概率模型进行分类预测。


 
将输入 x 分到后验概率最大的类 y。

后验概率最大等价于0-1损失函数时的期望风险最小化。

3. 运行步骤

朴素贝叶斯算法的步骤如下:

  1. 计算各类别的先验概率:统计每个类别在训练数据中出现的频率。
  2. 计算每个特征在各类别下的条件概率:假设特征间独立,计算每个特征在特定类别下出现的概率。
  3. 应用贝叶斯定理:将样本数据代入公式,计算后验概率,并选择具有最大后验概率的类别作为分类结果。

4. 更多延申模型

朴素贝叶斯对应的包名称为 naive_bayes,在其下可以选用所种模型:

模型名称可导入包名称
高斯贝叶斯GaussianNB
多项式贝叶斯MultinomialNB
伯努利贝叶斯BernoulliNB

如选用多项式贝叶斯模型时,代码如下:

from sklearn.naive_bayes import MultinomialNB

三、代码

本篇代码包含多张图片以及完整注释,建议在文章绑定资源中下载完整代码查看。

1. 导入所需包&数据

## 数据处理类
import numpy as np 
import pandas as pd 
import warnings## 数据可视化类
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline## 自然语言处理类
import re #处理文本字符串,如查找、替换、分割和匹配
import nltk #文本预处理(如分词、词干提取、停用词过滤)、词性标注、命名实体识别、情感分析等各种自然语言处理任务
from nltk.corpus import stopwords #文本预处理
from nltk.tokenize import word_tokenize #分割文本
from nltk.stem.porter import PorterStemmer #词干提取算法
from nltk.stem import WordNetLemmatizer #去标点符号from sklearn.preprocessing import MinMaxScaler,LabelEncoder 
# MinMaxScaler 能将类别型数据转换为数字
# LabelEncoder 进行特征放缩
from sklearn.feature_extraction.text import TfidfVectorizer 
# TfidfVectorizer 将原生文档转化为txt矩阵## 分析算法类
from sklearn.naive_bayes import MultinomialNB #朴素贝叶斯## 算法优化类
from sklearn.pipeline import Pipeline #流水线操作
from sklearn.model_selection import GridSearchCV,cross_val_score,train_test_split 
# GridSearchCV 网格搜索,cross_val_score 交叉验证,train_test_split 数据划分## 算法评分类
from sklearn import metrics
from sklearn.metrics import precision_score, recall_score, plot_confusion_matrix, classification_report, accuracy_score, f1_score#自行加载数据完成
#查看数据集基本结构信息
data.info()

2. 数据预处理

# 去除后面三列无意义列
to_drop = ["Unnamed: 2","Unnamed: 3","Unnamed: 4"]
data = data.drop(data[to_drop], axis=1)# 重命名前两列 
data.rename(columns = {"v1":"Target", "v2":"Text"}, inplace = True)
data.head()

3. 数据探索

plt.figure(figsize=(6,4))
fg = sns.countplot(x= data["Target"])
fg.set_title("Count Plot of Classes")
fg.set_xlabel("Classes")
fg.set_ylabel("Number of Data points")

3.1 特征工程

#添加列:字符数、单词数和句子数
data["No_of_Characters"] = data["Text"].apply(len)data["No_of_Words"]=data.apply(lambda row: nltk.word_tokenize(row["Text"]), axis=1).apply(len)
# 创建新列"No_of_Words",apply 将一个函数应用到 DataFrame 的每一行(axis=1),定义了一个匿名函数lambda接受行作为输入
# 使用 word_tokenize 函数对该行中的 Text 列进行分词,返回一个单词列表,使用 apply(len) 计算分词结果的长度,即单词的数量data["No_of_sentence"]=data.apply(lambda row: nltk.sent_tokenize(row["Text"]), axis=1).apply(len)
# sent_tokenize 函数返回的是句子列表data.describe().T # .T 是 DataFrame 的转置操作,将行和列互换plt.figure(figsize=(12,8))
fg = sns.pairplot(data=data, hue="Target")
plt.show(fg)

3.2 异常值处理

data = data[(data["No_of_Characters"]<350)]
data.shapeplt.figure(figsize=(12,8))
fg = sns.pairplot(data=data, hue="Target")
plt.show(fg)

4. 数据准备

由于本篇数据为文本处理,故需要先对长文本格式进行批量处理,才能使用算法模型进行预测评估。

4.1 文本处理

# 查看数据
print("\033[1m\u001b[45;1m The First 5 Texts:\033[0m",*data["Text"][:5], sep = "\n")# 编写数据清理函数
def Clean(Text):sms = re.sub('[^a-zA-Z]', ' ', Text) #Replacing all non-alphabetic characters with a spacesms = sms.lower() #converting to lowecasesms = sms.split()sms = ' '.join(sms)return smsdata["Clean_Text"] = data["Text"].apply(Clean)# 查看清理后数据
print("\033[1m\u001b[45;1m The First 5 Texts after cleaning:\033[0m",*data["Clean_Text"][:5], sep = "\n")data["Tokenize_Text"]=data.apply(lambda row: nltk.word_tokenize(row["Clean_Text"]), axis=1)print("\033[1m\u001b[45;1m The First 5 Texts after Tokenizing:\033[0m",*data["Tokenize_Text"][:5], sep = "\n")# 删除停用词
def remove_stopwords(text):stop_words = set(stopwords.words("english"))filtered_text = [word for word in text if word not in stop_words]return filtered_textdata["Nostopword_Text"] = data["Tokenize_Text"].apply(remove_stopwords)print("\033[1m\u001b[45;1m The First 5 Texts after removing the stopwords:\033[0m",*data["Nostopword_Text"][:5], sep = "\n")lemmatizer = WordNetLemmatizer()
# lemmatize string
def lemmatize_word(text):#word_tokens = word_tokenize(text)# provide context i.e. part-of-speechlemmas = [lemmatizer.lemmatize(word, pos ='v') for word in text]return lemmasdata["Lemmatized_Text"] = data["Nostopword_Text"].apply(lemmatize_word)
print("\033[1m\u001b[45;1m The First 5 Texts after lemitization:\033[0m",*data["Lemmatized_Text"][:5], sep = "\n")

4.2 矢量化

由于文字其实无法被读取,需要将文本内容进行向量化转换,便于

#词频 (TF) = (文档中某个词的频率)/(文档中词的总数) 
#逆文档频率 (IDF) = log( (文档总数)/(包含词 t 的文档数) 
#I将使用 TfidfVectorizer() 对预处理后的数据进行矢量化。#创建文本特征语料库
corpus= []
for i in data["Lemmatized_Text"]:msg = ' '.join([row for row in i])corpus.append(msg)corpus[:5]
print("\033[1m\u001b[45;1m The First 5 lines in corpus :\033[0m",*corpus[:5], sep = "\n")# 矢量化
tfidf = TfidfVectorizer()
X = tfidf.fit_transform(corpus).toarray()
# 查看特征
X.dtype# 对目标进行标签编码并将其用作 y
label_encoder = LabelEncoder()
data["Target"] = label_encoder.fit_transform(data["Target"])

5. 模型建构

y = data["Target"] 
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)nb_model = MultinomialNB()
nb_model.fit(X_train, y_train)
y_pred_nb = nb_model.predict(X_test)
accuracy_nb = accuracy_score(y_test, y_pred_nb)
print(f"朴素贝叶斯分类准确率: {accuracy_nb:.4f}")#交叉验证
# 使用准确率作为评估标准
scores = cross_val_score(MultinomialNB(),X_train, y_train, cv=5, scoring='accuracy')# 输出交叉验证的平均准确率和标准差
print(f"朴素贝叶斯 - 交叉验证准确率: {scores.mean():.2f} ± {scores.std():.2f}")# 使用加权F1得分作为评估标准
scores = cross_val_score(MultinomialNB(), X_train, y_train, cv=5, scoring='f1_weighted')# 输出加权F1得分的平均值和标准差
print(f"朴素贝叶斯 - 加权F1得分: {scores.mean():.2f} ± {scores.std():.2f}")

6. 模型评价

precision =[]
recall =[]
f1_score = []
trainset_accuracy = []
testset_accuracy = []pred_train = nb_model.predict(X_train)
pred_test = nb_model.predict(X_test)
prec = metrics.precision_score(y_test, pred_test)
recal = metrics.recall_score(y_test, pred_test)
f1_s = metrics.f1_score(y_test, pred_test)
train_accuracy = nb_model.score(X_train,y_train)
test_accuracy = nb_model.score(X_test,y_test)#评分
precision.append(prec)
recall.append(recal)
f1_score.append(f1_s)
trainset_accuracy.append(train_accuracy)
testset_accuracy.append(test_accuracy)# 初始化列表的数据
data = {'Precision':precision,
'Recall':recall,
'F1score':f1_score,
'Accuracy on Testset':testset_accuracy,
'Accuracy on Trainset':trainset_accuracy}#创建表格
Results = pd.DataFrame(data, index =["NaiveBayes"])Results.style.background_gradient()# 创建混淆矩阵
fig, ax = plt.subplots()  # 创建一个单独的子图
plot_confusion_matrix(nb_model, X_test, y_test, ax=ax)
ax.title.set_text(type(nb_model).__name__)  # 设置标题为模型的类名
plt.tight_layout()  
plt.show()

准确性报告返回表格如下:

分析可以得到以下结论:

  1. Precision(准确率):模型在测试集上预测正类的准确率是100%,表示被模型识别为【正类】的样本 100% 的确是【正类】。

  2. Recall(召回率):召回率为 0.705882,说明是【正类】的所有样本中,模型只识别出了大约 70.59%。这相对较低,表明模型有较高的漏报率。

  3. F1 Score:F1分数是 0.827586,它结合了准确率和召回率,是一个综合度量指标。尽管模型在准确率上表现出色,但因为召回率较低,F1分数中等。

  4. 测试集上的准确率:模型在测试集上的总体准确率为 0.963964,说明在所有测试样本中,大约96.4%的样本被正确分类。这个值较高,表明模型在未见数据上的表现不错。

  5. 训练集上的准确率:训练集的准确率为 0.976341,略高于测试集准确率,但差距不大。训练和测试集之间的准确率差异较小,表明模型没有明显的过拟合,性能在训练和测试中较为一致。

综合分析

总体准确率显示出模型的整体分类能力较强,没有明显过拟合,如果目标是减少误报(例如在精确识别很重要的场景下),模型的表现已经非常出色。如果更关注全面识别正类样本(如在健康诊断中),则召回率需要进一步优化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/58414.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软考教材重点内容 信息安全工程师 第1章 网络信息安全概述

第 1 章 网络信息安全概述 1.1.1 网络信息安全相关概念 狭义上的网络信息安全特指网络信息系统的各组成要素符合安全属性的要求&#xff0c;即机密性、完整性、可用性、抗抵赖性、可控性。 广义上的网络信息安全是涉及国家安全、城市安全、经济安全、社会安全、生产安全、人身安…

使用Vue3和Vue2进行开发的区别

使用Vue3和Vue2进行开发的区别 笔者虽然老早就是用vue3进行开发了&#xff0c;但是上次有人问道使用vue3进行开发跟使用vue2进行开发的区别有哪些这个问题的时候&#xff0c;回答的还是有些琐碎&#xff0c;干脆今天专门整理一下&#xff0c;做个记录。 一、再也不用set了 众所…

项目开发流程规范文档

项目开发流程规范文档 目标: 明确项目组中需求管理人员, 交互设计, 美工以及开发之间的工作输入输出产物. 明确各岗位职责. 以免造成开发, 产品经理以及项目经理之间理解不到位, 沟通成本过高,返工造成资源浪费. 所有环节产生的文档都可以作为项目交付的资源. 而不是事后再补文…

在docker里创建 bridge 网络联通不同容器

1.网络创建&#xff1a; docker network create --subnet192.168.1.0/24 --gateway192.168.1.1 uav_management 2.查看网络&#xff1a; docker network ls 3.给已经创建的容器分配ip: docker network connect --ip 192.168.1.10 uav_management 容器名/容器id 示例&#xf…

【极限编程(XP)】

极限编程&#xff08;XP&#xff09;简介 定义与核心价值观&#xff1a;极限编程&#xff08;Extreme Programming&#xff0c;XP&#xff09;是一种轻量级、敏捷的软件开发方法。它强调团队合作、客户参与、持续测试和快速反馈等价值观&#xff0c;旨在提高软件开发的效率和质…

低代码用户中心:简化开发,提升效率的新时代

随着数字化转型的加速&#xff0c;企业对于快速交付高质量应用的需求日益增长。在这个背景下&#xff0c;低代码开发平台应运而生&#xff0c;成为越来越多企业和开发者的首选工具。今天&#xff0c;我们将聚焦于低代码用户中心&#xff0c;探讨其如何帮助开发者简化流程、提升…

Docker在CentOS上的安装与配置

前言 随着云计算和微服务架构的兴起&#xff0c;Docker作为一种轻量级的容器技术&#xff0c;已经成为现代软件开发和运维中的重要工具。本文旨在为初学者提供一份详尽的指南&#xff0c;帮助他们在CentOS系统上安装和配置Docker及相关组件&#xff0c;如Docker Compose和私有…

Redis 权限控制(ACL)|ACL 命令详解、ACL 持久化

官网文档地址&#xff1a;https://redis.io/docs/latest/operate/oss_and_stack/management/security/acl/ 使用版本&#xff1a;Redis7.4.1 什么是 ACL&#xff1f; ACL&#xff08;Access Control List&#xff09;&#xff0c;权限控制列表&#xff0c;是 Redis 提供的一种…

淘宝反爬虫机制的主要手段有哪些?

淘宝的反爬虫机制主要有以下手段&#xff1a; 一、用户身份识别与验证&#xff1a; User-Agent 识别&#xff1a;通过检测 HTTP 请求头中的 User-Agent 字段来判断请求是否来自合法的浏览器。正常用户使用不同浏览器访问时&#xff0c;User-Agent 会有所不同&#xff0c;而爬虫…

2024最新gewe开发微信机器人教程说明

微信时代&#xff0c;越来越多的业务/服务沟通已直接在微信上完成&#xff0c;但在沟通效率及员工管理方面却存在如下问题&#xff1a; 1、现有的微信功能&#xff0c;已无法满足与客户沟通时的高效率要求 2、当员工掌管的微信号若干或更多时&#xff0c;迫切需要有个汇总工具…

Java项目实战II基于Spring Boot的智慧生活商城系统的设计与实现(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。 一、前言 随着科技的飞速发展&#xff0c;人们的…

如何使用Langchain集成Kimi AI(Moonshot AI)

如何使用Langchain集成Kimi&#xff08;Moonshot AI&#xff09; 一、获取API密钥1. 注册账号2. 获取密钥 二、环境配置三、上手四、整合一下五、检验一下成果六、官方网站 一、获取API密钥 1. 注册账号 毕竟只有注册过帐号才能拿到key~ Moonshot 登陆 2. 获取密钥 用户中心…

前端开发模板Pear Admin Layui

目录 基本资料学习笔记04-Pear-Admin-Layui模板运行05-Pear-Admin-Layui-GIT方式代...06-Pear-Admin与Vue对比 & 07-Pear-Admin与Vue对比补充09-Pear-Admin-CRUD练习-数据库表创建12-Pear-Admin-CRUD练习-引入其它依赖 & 13-Pear-Admin-CRUD练习-三层架构以及常见配置 …

新世联科技:NG2-A-7在DAC空气捕集提取CO2的应用

一、DAC空气捕集提取CO2的介绍 直接空气碳捕获&#xff08;Direct Air Capture&#xff0c;简称DAC&#xff09;是一种直接从大气中提取二氧化碳的技术。 二、DAC空气捕集提取CO2的前景 从大气中提取的这种二氧化碳可以作为循环经济的一部分以各种不同方式使用。未来&#xf…

uni-app 封装图表功能

文章目录 需求分析1. 秋云 uchars2. Echarts 需求 在 uni-app 中使用图表功能&#xff0c;两种推荐的图表工具 分析 在 Dcloud市场 搜索Echarts关键词&#xff0c;会出现几款图表工具&#xff0c;通过大家的下载量&#xff0c;可以看到秋云这个库是比较受欢迎的&#xff0c;其…

详细解读个性化定制大杀器IP-Adapter代码

Diffusion models代码解读&#xff1a;入门与实战 前言&#xff1a;IP-Adapter作为Diffusion Models最成功的技术之一&#xff0c;已经在诸多互联网应用中落地。介绍IP-Adapter原理和应用的博客有很多&#xff0c;但是逐行详细解读代码的博客很少。这篇博客从细节出发&#xff…

数据采集之scrapy框架2

本博文使用自动化爬虫框架完成微信开放社区文档信息的爬取&#xff08;重点理解 scrapy 框架自动化爬 虫构建过程&#xff0c;能够分析 LinkExtractor 和 Rule 规则的基本用法&#xff09; 包结构目录如下图所示&#xff1a; 主要代码&#xff1a; &#xff08; items.p…

深⼊理解指针(2)

目录 1. const修饰指针及变量 2. 野指针 3. assert断⾔ 4. 指针的传址调⽤ 一 const修饰指针及变量&#xff08;const是场属性——不能改变的属性&#xff09; 1 const修饰变量 那怎么证明被const修饰的变量本质还是变量呢&#xff1f; 上面我们绕过n&#xff0c;使…

每日科技资讯:2024年11月06日【龙】农历十月初六 ---文末送书

目录 1.OpenAI因算力瓶颈暂缓GPT-5发布 合作芯片开发寻求突破2.现在&#xff0c;&#x1d54f; 允许被你屏蔽的人继续查看你的帖子3.硬刚Intel与AMD&#xff01;NVIDIA明年推出PC芯片4.苹果停止签署 iOS 18.0.1&#xff0c;不再允许从 18.1 降级5.Nvidia 加入道琼斯指数成份股 …

swoole扩展安装--入门篇

对于php来说&#xff0c;swoole是个强大的补充扩展。这是我第3次写swoole扩展安装&#xff0c;这次基于opencloudos8系统&#xff0c;php使用8.2。 安装swoole扩展首先想到的是用宝塔来安装&#xff0c;毕竟安装方便&#xff0c;还能统一管理。虽然获得swoole版本不是最新的&am…