数据挖掘实战-基于机器学习的垃圾邮件检测模型(文末送书)

news2024/11/25 2:25:54

 

🤵‍♂️ 个人主页:@艾派森的个人主页

✍🏻作者简介:Python学习者
🐋 希望大家多多支持,我们一起进步!😄
如果文章对你有帮助的话,
欢迎评论 💬点赞👍🏻 收藏 📂加关注+


目录

1.项目背景

2.数据集介绍

3.技术工具

4.实验步骤

4.1导入数据

4.2数据预处理

4.3数据可视化

4.4特征工程

4.5构建模型

4.6模型评估

 文末推荐与福利


1.项目背景

        随着互联网的普及和电子邮件的广泛使用,垃圾邮件的问题逐渐凸显。垃圾邮件不仅占据了用户的宝贵时间,还可能涉及到安全隐患,如恶意软件传播、网络钓鱼等。因此,有效地检测和过滤垃圾邮件成为了保障用户体验和网络安全的重要任务之一。

        传统的垃圾邮件过滤方法通常采用规则引擎,通过事先定义一系列规则来识别垃圾邮件。然而,这种方法往往难以应对垃圾邮件攻击的多样性和不断变化的特征。为了提高垃圾邮件检测的准确性和适应性,近年来,研究者们逐渐将机器学习引入到垃圾邮件检测领域。

        机器学习技术通过对大量邮件数据的学习,能够自动发现并利用隐藏在数据中的模式和特征。这为垃圾邮件检测提供了一种更加灵活和自适应的解决方案。在这一背景下,本实验旨在通过构建基于机器学习的垃圾邮件检测模型,提高垃圾邮件过滤的准确性和效率。

2.数据集介绍

        数据集来源于Kaggle,原始数据集共有5572条,2个变量,具体含义解释如下:

Target:邮件的类型,'ham' or 'spam'。

Text:邮件的文本内容。

3.技术工具

Python版本:3.9

代码编辑器:jupyter notebook

4.实验步骤

4.1导入数据

导入第三方库并加载数据

# 导包
import warnings
import matplotlib.pyplot as plt
import missingno as msno
import seaborn as sns
import numpy as np 
import pandas as pd
import re
import nltk
from nltk.corpus import stopwords
from nltk.stem.porter import PorterStemmer
from nltk.stem import WordNetLemmatizer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline    
from sklearn.naive_bayes import MultinomialNB
from sklearn.ensemble import RandomForestClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.model_selection import cross_val_score
from matplotlib.colors import ListedColormap
from sklearn import metrics

# 加载数据
df = pd.read_csv("spam_ham.csv",encoding='latin1')
df.head()

查看数据大小

查看数据基本信息 

查看描述性统计

4.2数据预处理

统计缺失值

 从结果来看,原始数据集不存在缺失值

检测是否存在重复值

删除重复值

4.3数据可视化

查看Target目标变量 

# 检查目标列以便进一步分析
fig = sns.countplot(x=df['Target'])
fig.set_title('Count of Classes', fontsize=2, color='green')
fig.set_xlabel('Classes', fontsize=16, color='red')
fig.set_ylabel('Number of data', fontsize=16, color='red')

# 添加注释
for p in fig.patches:
    fig.annotate(f'{p.get_height()}', (p.get_x() + p.get_width() / 2., p.get_height()),
                 ha='center', va='center', fontsize=15, color='black', xytext=(0, 10),
                 textcoords='offset points')

plt.show()

上面的计数图清楚地突出了数据的显著不平衡。 

Text词云图

from wordcloud import WordCloud
text = ' '.join(df['Text'])
wordcloud = WordCloud(width=800, height=400, background_color='black').generate(text)
plt.figure(figsize=(10, 6))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis('off')
plt.title('Word Cloud for Text Column')
plt.tight_layout()
plt.show()

4.4特征工程

为了追求全面的数据探索,我引入了新的功能:

No_of_Characters:表示文本消息中的字符数。

No_of_Words:表示文本消息中存在的字数。

No_of_Sentences:反映文本消息中句子的数量。

# 创建一个新的字符列计数
df['No_of_Character'] = df['Text'].apply(len)
df['No_of_Words'] = df.apply(lambda row: nltk.word_tokenize(row['Text']),axis=1).apply(len)
df['No_of_Sentences'] = df.apply(lambda row: nltk.sent_tokenize(row['Text']),axis=1).apply(len)
# 检查数据描述
df.describe().T

plt.figure(figsize=(15,12))
sns.pairplot(data=df,hue='Target')
plt.show()

在检查成对图时,很明显有一些异常值,都在“ham”类内。这很有趣,因为这些异常值可能传达了相同的信息,特别是短信的长度。在下一步中,我计划通过对这些异常值之一实施上限来解决这个问题,有效地处理它们的影响。

# 丢弃异常值
df = df[(df['No_of_Character']<350)]
df.shape

# 检查后
plt.figure(figsize=(15,12))
sns.pairplot(data=df, hue='Target')
plt.show()

当然,有时重新访问和可视化数据不仅仅是为了发现新的东西,而是为了欣赏信息的美学。毕竟,谁能抗拒情节中那些充满活力和多样性的色彩的诱惑呢?

在NLP中,清理数据非常重要。对计算机来说,文本只是一堆符号,它不知道单词的意思。因此,为了帮助计算机更好地处理文本,我们必须让它更干净。

我们是这样做的:首先,我们只保留字母表中的字母。这意味着我们要去掉标点和数字。之后,我们把所有的字母都变成小写。清理后的文本将用于处理的下一个步骤。

# 让我在清洗之前检查一下样本文本
print("\033[1m\u001b[45;1m The First 5 Texts:\033[0m",*df["Text"][:5], sep = "\n")

# 创建一个函数来清理文本
def clean(Text):
    sms = re.sub('[^a-zA-Z]',' ',Text) # 替换所有非字母
# 带空格的字符
    sms = sms.lower()
    sms = sms.split()
    sms = ' '.join(sms)
    return sms
df.loc[:,'Clean_text'] = df['Text'].apply(clean)
# 清洁后检查
print("\033[1m\u001b[45;1m The First 5 After Cleaning Texts:\033[0m",*df["Clean_text"][:5], sep = "\n")

分词就是将复杂的数据分解为更小的部分,称为标记(token)。这有点像把段落分成句子,然后把这些句子分成单独的单词。在这一步中,我特别将Clean_Text拆分为单词。这有助于我们更有效地分析和处理文本。

df.loc[:,'Tokenize_text'] = df.apply(lambda row: nltk.word_tokenize(row['Clean_text']),axis=1)
#标记文本后检查
print("\033[1m\u001b[45;1m The First 5 After Tokenize Texts:\033[0m",*df["Tokenize_text"].loc[:5], sep = "\n")

停用词(Stopwords)是指在语言中经常出现但不能给意思带来太多帮助的单词(比如few、is、an等)。虽然它们对句子的结构很重要,但它们在NLP的语言处理中没有多大价值。为了简化处理过程并删除不必要的重复,我将删除这些停用词。NLTK库提供了一组默认停词,我们将从文本中排除这些停词。

# 创建去除停用词函数
def remove_stopwords(text):
    stop_word = set(stopwords.words('english'))
    filtered_text = [word for word in text if word not in stop_word]
    return filtered_text
df.loc[:,'Nostopword_text'] = df['Tokenize_text'].apply(remove_stopwords)
# 检查Nostopwords文本后的内容
print("\033[1m\u001b[45;1m The First 5 After Nostopword Texts:\033[0m",*df["Nostopword_text"].loc[:5], sep = "\n")

词干涉及到一个词的核心形式,通常被称为词根。去掉前缀或后缀后剩下的就是这个词根。这就像是回到了这个词的起源。语言随着时间的推移而变化,许多语言相互扩展。例如,英语起源于拉丁语。所以,当我们词干一个词,我们本质上是把它带回到它的基本形式。

另一方面,词源化也将一个词转换成它的词根形式。关键的区别在于确保这个词根在我们正在使用的语言中仍然有效,在我们的示例中是英语。选择词序化可以保证输出仍然是英语。

import spacy

# 加载英语语言模型
nlp = spacy.load("en_core_web_sm")

# 按词序排列单词表
def lemmatize_words(words):
    doc = nlp(" ".join(words))
    lemmas = [token.lemma_ for token in doc]
    return lemmas

# 对"Nostopword_text"列应用排列规则
df.loc[:, "Lemmatized_Text"] = df["Nostopword_text"].apply(lemmatize_words)

# 打印按字母顺序排列的文本
print("\033[1m\u001b[45;1m The First 5 Texts after lemmatization:\033[0m", *df["Lemmatized_Text"][:5], sep="\n")

TF-IDF在NLP中表示Term Frequency - Inverse Document Frequency。在NLP中,我们需要将清理后的文本转换为数字,其中一种方法是将每个单词表示为矩阵。这个过程也被称为词嵌入或词矢量化。

以下是使用TfidfVectorizer()对数据进行矢量化的关键步骤:

创建语料库:这意味着收集一组按语料库排列的文本。

转换为向量形式:将语料库转换为数字向量格式。

标签编码:为“Target”列中的类分配数字标签。

注意:到目前为止,我们一直在数据中构建列以进行解释。

# 构建文本特征编码为矢量化形式的语料库
corpus = []
for i in df['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()
#Let's have a look at our feature 
X.dtype

#标签编码目标并使用它作为y
label_encoder = LabelEncoder()
df.loc[:,"Target"] = label_encoder.fit_transform(df["Target"])

4.5构建模型

步骤涉及模型建设

设置特点及目标:识别特征和目标变量,将它们分配给X和y。

分为测试集和训练集:将数据集分为训练集和测试集,以评估模型的性能。

训练模型:

使用训练数据拟合所有模型。

准确性交叉验证:

在训练集上使用交叉验证来评估模型,以确定其准确性。

#将标签和特征的值设置为y和X(我们已经在向量化中做了X…)
y = df['Target']
# 分割测试集和训练集
X_train, X_test, y_train, y_test = train_test_split(X,y, test_size=0.2,random_state=45)
from sklearn.preprocessing import LabelEncoder

# LabelEncoder将字符串标签转换为数值
label_encoder = LabelEncoder()
y_train_encoded = label_encoder.fit_transform(y_train)

# 对分类器进行测试
classifiers = [MultinomialNB(),
               RandomForestClassifier(),
               KNeighborsClassifier(),
               SVC()]

for idx, cls in enumerate(classifiers):
    cls.fit(X_train, y_train_encoded)

# 管道和模型类型的字典,便于参考
pipe_dict = {0: "NaiveBayes", 1: "RandomForest", 2: "KNeighbours", 3: "SVC"}
# 交叉验证
for i, model in enumerate(classifiers):
    cv_score = cross_val_score(model, X_train, y_train_encoded, scoring="accuracy", cv=10)
    print("%s: %f " % (pipe_dict[i], cv_score.mean()))

4.6模型评估

# LabelEncoder将字符串标签转换为数值
label_encoder = LabelEncoder()
y_train_encoded = label_encoder.fit_transform(y_train)
y_test_encoded = label_encoder.transform(y_test)  # transform for test labels

# 模型评价
# 创建各种分数的列表
precision = []
recall = []
f1_score = []
trainset_accuracy = []
testset_accuracy = []

for model in classifiers:
    pred_train = model.predict(X_train)
    pred_test = model.predict(X_test)
    prec = metrics.precision_score(y_test_encoded, pred_test)
    recal = metrics.recall_score(y_test_encoded, pred_test)
    f1_s = metrics.f1_score(y_test_encoded, pred_test)
    train_accuracy = model.score(X_train, y_train_encoded)
    test_accuracy = model.score(X_test, y_test_encoded)

    # 追加分数
    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}
# 创建pandas数据框架。
Results = pd.DataFrame(data, index =["NaiveBayes", "RandomForest", "KNeighbours","SVC"])
cmap2 = ListedColormap(["#E2CCFF","green"])
Results.style.background_gradient(cmap=cmap2)

from sklearn.metrics import confusion_matrix

cmap = ListedColormap(["#E1F16B", "green"])

fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(15, 10))

for cls, ax in zip(classifiers, axes.flatten()):
    y_pred = cls.predict(X_test)
    y_test_arr = np.array(y_test, dtype=int)
    y_pred_arr = np.array(y_pred, dtype=int)

    cm = confusion_matrix(y_test_arr, y_pred_arr, labels=np.unique(y_test_arr))

    sns.heatmap(cm, annot=True, fmt="d", cmap=cmap, ax=ax)
    ax.set_title(type(cls).__name__)
    ax.set_xlabel('Predicted')
    ax.set_ylabel('True')

plt.tight_layout()
plt.show()

 文末推荐与福利

《AI爆款文案 巧用AI大模型让文案变现插上翅膀》免费包邮送出3本!

内容简介:      

       掌握人工智能辅助文案写作的方式,就可以轻松写出高质量文案,进而快速实现文案变现。本书通过对10款人工智能应用的介绍及调试,帮助读者快速掌握人工智能辅助文案变现的方式。本书共10章,分别讲解AI智能创作,AI爆款文案写作工具,人工智能辅助泛流量文案、泛商业文案、私域文案创作,利用人工智能实现文案变现的底层逻辑,以及在今日头条、百家号、小红书、知乎等平台及不同展示形式下进行文案创作的实战案例等。

        本书适合希望通过文案写作实现变现的写作新人、写作爱好者以及相关培训机构使用。

编辑推荐:           

1. 爆款文案一键式创作:通过人工智能写爆款文案,提高效率的同时,也降低了试错成本的代价。本书通过大量的实际案例,展示了AI工具在文案创作中的应用和效果,使读者能够更直观地掌握AI工具的巨大优势。

2. 解构文案变现逻辑:文案变现的市场需求度极高,无论应用在新媒体文、短视频文案脚本还是知乎小红书种草文都能带来极高收益,而当文案变现与人工智能结合在一起时,一切就变得更有意思了。本书不仅关注文案创作本身,更着眼于如何利用AI工具实现文案的变现,帮助创作者实现商业价值的最大化。

3. 握未来之笔,引领文案革命新浪潮:本书不仅涉及泛流量文案、泛商业文案和私域文案的创作技巧,还针对主流平台和社交平台详细介绍了AI在文案创作实战中的高级技巧,引领文案变革新浪潮。

  • 抽奖方式:评论区随机抽取3位小伙伴免费送出!
  • 参与方式:关注博主、点赞、收藏、评论区评论“人生苦短,拒绝内卷!”(切记要点赞+收藏,否则抽奖无效,每个人最多评论三次!
  • 活动截止时间:2024-4-13 20:00:00
  • 京东:https://item.jd.com/14521488.html

    当当:http://product.dangdang.com/29706300.html

 名单公布时间:2024-4-13 21:00:00 

 

资料获取,更多粉丝福利,关注下方公众号获取

在这里插入图片描述

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

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

相关文章

30.WEB渗透测试-数据传输与加解密(4)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;29.WEB渗透测试-数据传输与加解密&#xff08;3&#xff09;-CSDN博客 加解密需要用到的源…

【linux】sudo 与 su/su -之间的区别

一、区别 二、其他 大概是因为使用 su 命令或直接以 root 用户身份登录有风险&#xff0c;所以&#xff0c;一些 Linux 发行版&#xff08;如 Ubuntu&#xff09;默认禁用 root 用户帐户。鼓励用户在需要 root 权限时使用 sudo 命令。 然而&#xff0c;您还是可以成功执行 su…

4.10作业

//.h文件#ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimerEvent> //定时器事件类 #include <QTime> //时间类 #include <QString> #include <QPushButton> //按钮类 #include <QLabel> //标签类 #include <QT…

<-泛型->

1.泛型的概念 所谓泛型&#xff0c;就是允许在定义类, 接口 时通过一个"标识"表示类中某个属性的类型或者某个方法的返回值或形参类型.这个类型参数将在使用时确定. 2.举例 (1). 集合类在设计阶段/声明阶段不能确定这个容器到底存的是什么对象&#xff0c;所以在JDK…

蓝桥杯PythonB组练习——矩形面积交

一、题目 问题描述   平面上有两个矩形&#xff0c;它们的边平行于直角坐标系的X轴或Y轴。对于每个矩形&#xff0c;我们给出它的一对相对顶点的坐标&#xff0c;请你编程算出两个矩形的交的面积。 输入格式   输入仅包含两行&#xff0c;每行描述一个矩形。   在每行中…

Python 新手最容易踩的坑

Python新手最容易踩的坑 缩进错误忘记引入模块使用未定义的变量不理解变量作用域字符串格式化错误乱用关键字多余的符号本期图书推荐&#xff1a;Python算法小讲堂---39个算法案例带你玩转Python内容简介获取方式 在学习 Python 的过程中&#xff0c;新手往往会遇到一些常见的陷…

HarmonyOS开发实例:【分布式数据管理】

介绍 本示例展示了在eTS中分布式数据管理的使用&#xff0c;包括KVManager对象实例的创建和KVStore数据流转的使用。 通过设备管理接口[ohos.distributedDeviceManager]&#xff0c;实现设备之间的kvStore对象的数据传输交互&#xff0c;该对象拥有以下能力 ; 1、注册和解除注…

SpringBoot菜品分页查询模块开发(多表连接查询)

需要注意的地方 为什么创建VO类怎么进行多表连接查询分页查询的统一返回结果类PageResult分页查询Mapper的返回结果是Page<目标实体类> 需求分析与设计 一&#xff1a;产品原型 系统中的菜品数据很多的时候&#xff0c;如果在一个页面中全部展示出来会显得比较乱&…

力扣HOT100 - 238. 除自身以外数组的乘积

解题思路&#xff1a; 当前位置的结果就是它左部分的乘积再乘以它右部分的乘积。因此需要进行两次遍历&#xff0c;第一次遍历用于求左部分的乘积&#xff0c;第二次遍历在求右部分的乘积的同时&#xff0c;再将最后的计算结果一起求出来。 class Solution {public int[] prod…

Transformer详解和知识点总结

目录 1. 注意力机制1.1 注意力评分函数1.2 多头注意力&#xff08;Multi-head self-attention&#xff09; 2. Layer norm3. 模型结构4. Attention在Transformer中三种形式的应用 论文&#xff1a;https://arxiv.org/abs/1706.03762 李沐B站视频&#xff1a;https://www.bilibi…

(学习日记)2024.04.05:UCOSIII第三十三节:互斥量

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

SpringBoot第一个hello world项目

文章目录 前言一、Spring Boot是什么&#xff1f;二、使用步骤1. 创建项目2.书写测试 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 例如&#xff1a;随着人工智能的不断发展&#xff0c;机器学习这门技术也越来越重要&#xff0c;很多人都开启了…

DRL-VWAP算法

摘要 在量化策略的交易端&#xff0c;为了更好的扩大策略的资金容量必须要考虑策略冲击陈本的降低。本文梳理了传统 VWAP 存在的诸多弊端&#xff0c;主要在于对于日内交易信息的缺失与忽略市场行情的影响。本文梳理了传统VWAP 算法存在的主要弊端&#xff0c;并改写了传统 VW…

20240409在全志H3平台的Nano Pi NEO CORE开发板运行的Ubuntu Core更新boot.img(eMMC启动)

20240409在全志H3平台的Nano Pi NEO CORE开发板运行的Ubuntu Core更新zImage内核 2024/4/9 9:21 一、生成zImage: 参考资料&#xff1a; http://wiki.friendlyelec.com/wiki/index.php/NanoPi_NEO_Core/zh#.E7.83.A7.E5.86.99.E5.88.B0eMMC NanoPi NEO Core/zh 6 FriendlyCore…

【leetcode面试经典150题】37. 矩阵置零(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主&#xff0c;题解使用C语言。&#xff08;若有使用其他语言的同学也可了解题解思路&#xff0c;本质上语法内容一致&…

大数据相关组件安装及使用

自学大数据相关组件 持续更新中。。。 一、linux安装docker 1、更新yum sudo yum update2、卸载docker旧版本 sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine3、…

菜鸟IPO折戟背后:估值大幅下降,阿里巴巴为“分拆之痛”买单

撰稿|行星 来源|贝多财经 近日&#xff0c;阿里巴巴集团&#xff08;下称“阿里巴巴”或“阿里”&#xff09;发布公告&#xff0c;称其物流子公司菜鸟&#xff08;同菜鸟物流、菜鸟网络&#xff09;撤回在港交所的首次公开发行及上市申请&#xff0c;并计划收购菜鸟少数股东…

LeetCode31. 下一个排列(Java)

题目&#xff1a; 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。 例如&#xff0c;arr [1,2,3] &#xff0c;以下这些都可以视作 arr 的排列&#xff1a;[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。 整数数组的 下一个排列 是指其整数的下一个字典序更大的排列…

鸿蒙实战开发-如何实现查看系统相册、最近删除、收藏夹操作功能

介绍 本示例主要展示了相册相关的功能&#xff0c;使用ohos.file.photoAccessHelper 接口&#xff0c;实现了查看系统相册、创建用户相册、查看相册照片、用户相册文件添加和删除、以及预览图片、最近删除、收藏夹操作等功能; 效果预览 使用说明 主界面&#xff1a;查询显示…

一本想教会你滤波算法书

一本想教会你滤波算法书 从今天开始&#xff0c;这个博客系列会翻译一本 500 页左右的滤波算法的书&#xff0c;该书的原文连接我会放到后面的文中。翻译这本书不仅能继续我的英语学习&#xff08;水平有限&#xff0c;有问题我留言我马上改&#xff01;&#xff09;而且可以跟…