垃圾信息过滤:朴素贝叶斯与支持向量机

在当今数字化时代,垃圾信息成为了一个普遍存在的问题,它不仅给人们带来困扰,还可能造成经济损失。发送垃圾信息会消耗存储空间、计算能力和速度,并且需要花费时间去清理。为了解决这个问题,已经开发出了许多过滤垃圾信息的方法,其中一些取得了不同程度的成功。本文将探讨朴素贝叶斯分类器和支持向量机这两种机器学习模型,并实现它们来过滤垃圾文本信息,最后比较结果。

1.朴素贝叶斯分类器

朴素贝叶斯是一种用于分类问题的监督式机器学习算法,它基于贝叶斯定理。之所以被称为“朴素”,是因为它对预测变量之间的条件独立性做出了朴素的假设。这种算法假设一个类别中的所有特征都是相互无关的。为了解释朴素贝叶斯算法,首先需要了解贝叶斯定理。

贝叶斯定理:假设有两个事件A和B,可以使用以下公式来计算后验概率P(B|A),其中P(B)是先验概率,P(A)是事件A的概率,P(A|B)是在B发生的条件下A发生的概率。

当只有一个特征时,计算后验概率相对简单。但是,当有两个或更多特征时,计算后验概率就变得复杂了,有时甚至会出现零概率问题。因此,采用朴素的假设来计算后验概率。

假设有预测变量[X1, X2]和目标Y,计算后验概率的公式如下:

P(X1, X2|Y=1)

这是使用朴素贝叶斯分类器计算后验概率的公式。

2.支持向量机(SVM)

支持向量机是一种监督式机器学习算法,可以用于回归和分类。在SVM中,数据点被绘制在n维空间中,其中n是特征的数量。然后通过选择一个合适的超平面来分类两个类别。在n维空间中,超平面的维度是(n-1)。假设类别是线性可分的。

方程的符号有助于分类类别,而方程的大小有助于理解观察值离超平面的距离。当大小较高时,对类别分配的确定性更高。数据点到超平面的最小距离称为边际。需要有最大的边际,以便它具有高的大小。因此,这个超平面被称为最大边际分类器。

位于边际上或违反边际的观察值被称为支持向量。支持向量支持超平面。在支持向量分类器中,有一个最大边际分类器,它有一个软边际(这个边际可以被一些观察值违反)。

本文使用的数据集是UCI机器学习库中的SMS Spam Collection数据集。这是一个公共的SMS标记消息集合,收集于2012年,用于移动电话垃圾信息研究。该数据集包含5572条消息,其中4825条是正常消息,747条是垃圾信息。在这个数据集中,每一行都以消息的标签开始,后面跟着文本。

数据集链接:

数据集包含两列:数据的标签类别(正常或垃圾)和文本消息。移除了其他不需要的列。

# 导入包 import pandas as pd import numpy as np # 读取数据集 sms_data = pd.read_csv("spam", encoding='latin-1', sep='\t') print(sms_data.head()) # 移除不需要的列 sms_data.drop(labels=['Unnamed: 2','Unnamed: 3','Unnamed: 4','length'], axis=1, inplace=True) sms_data.head()

接下来,将创建一个语料库并附加消息,在附加消息到语料库之前,需要执行某些预处理步骤。导入‘re’包并移除标点符号、特殊字符,并将所有字符转换为小写。然后,需要将消息分割成单词以移除停用词,并执行词干提取。

# 导入包 import re import nltk from nltk.corpus import stopwords from nltk.stem.porter import PorterStemmer # 创建一个精炼消息的语料库 stemming = PorterStemmer() corpus = [] for i in range(0, len(sms_data)): s1 = re.sub('[^a-zA-Z]', repl=' ', string=sms_data['v2'][i]) s1.lower() s1 = s1.split() s1 = [stemming.stem(word) for word in s1 if word not in set(stopwords.words('english'))] s1 = ' '.join(s1) corpus.append(s1) corpus[50]

将导入Scikit-learn库中的Count-Vectorizer来标记化和向量化文本。

# 导入包 from sklearn.feature_extraction.text import CountVectorizer countvectorizer = CountVectorizer()

使用这个Count-Vectorizer,将标记化一系列文本文档并构建词汇表,这个词汇表也用于编码新文档。要使用这个Count-Vectorizer,首先,将创建一个Count-Vectorizer类的实例。然后,fit()函数用于从文档中学习词汇,transform()函数用于编码为向量。

x = countvectorizer.fit_transform(corpus).toarray() print(x) y = sms_data['v1'].values print(y)

这个向量表示整个词汇表的长度和每个词在文档中出现的次数。现在有一个从文本字符串转换来的数值向量。

# 分割训练和测试数据 from sklearn.model_selection import train_test_split x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, stratify=y, random_state=100) # 1. 多项式朴素贝叶斯 from sklearn.naive_bayes import MultinomialNB multinomialnb = MultinomialNB() multinomialnb.fit(x_train, y_train) # 在测试数据上预测 y_pred = multinomialnb.predict(x_test) # 2. SVM from sklearn.svm import LinearSVC linearsvc = LinearSVC() linearsvc.fit(x_train, y_train) # 在测试数据上预测 y_pred = linearsvc.predict(x_test) # 导入包 from sklearn.metrics import classification_report, confusion_matrix from sklearn.metrics import accuracy_score print(classification_report(y_test, y_pred)) accuracy_score(y_test, y_pred)
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485