如何在Python中使用Keras构建垃圾邮件分类器

自1990年代初以来,电子邮件垃圾邮件一直在增长,到2014年,据估计,垃圾邮件约占发送的电子邮件的90%。

由于我们所有人都有垃圾邮件填充收件箱的问题,因此在本教程中,我们将在Keras中建立一个模型来区分垃圾邮件和合法电子邮件。

如何在<a href='/tag/python.html'>Python</a>中使用<a href='/tag/keras.html'>Keras</a>构建垃圾邮件分类器

一、安装和导入依赖项

我们首先需要安装一些依赖项:
pip3 install keras sklearn tqdm numpy keras_metrics tensorflow==1.14.0
现在打开一个交互式shell或bfwstudio并导入:
import tqdm
import numpy as np
import keras_metrics # for recall and precision metrics
from keras.preprocessing.sequence import pad_sequences
from keras.preprocessing.text import Tokenizer
from keras.layers import Embedding, LSTM, Dropout, Dense
from keras.models import Sequential
from keras.utils import to_categorical
from keras.callbacks import ModelCheckpoint, TensorBoard
from sklearn.model_selection import train_test_split
import time
import numpy as np
import pickle


让我们定义一些超参数:

SEQUENCE_LENGTH = 100 #序列的长度 (每个样本的单词数量)

EMBEDDING_SIZE = 100 # 使用100维GloVe嵌入向量

TEST_SIZE = 0.25 #测试比率

BATCH_SIZE = 64 #批量大小

EPOCHS = 20 # 迭代次数#

# 将垃圾邮寄和正常邮件转成成0和1

label2int = {"ham": 0, "spam": 1}

int2label = {0: "ham", 1: "spam"}

如果您不确定这些参数的含义,请不要担心,我们稍后将在构建模型时讨论它们。

二、加载数据集


我们将使用的数据集是SMS Spam Collection Dataset,下载地址https://archive.ics.uci.edu/ml/machine-learning-databases/00228/smsspamcollection.zip,下载后解压并将其放入名为“ data”的文件夹中,让我们定义加载它的函数:

def load_data():
"""
Loads SMS Spam Collection dataset
"""
texts, labels = [], []
with open("data/SMSSpamCollection") as f:
for line in f:
split = line.split()
labels.append(split[0].strip())
texts.append(' '.join(split[1:]).strip())
return texts, labels


数据集在一个文件中,每一行对应一个数据样本,第一个单词是标签,其余是实际的电子邮件内容,这就是为什么我们将标签作为split [0]抓取,并将内容作为split [1: ]。

调用函数:
# load the data
X, y = load_data()

三、准备数据集

现在,我们需要一种通过将每个文本转换为整数序列来矢量化文本语料库的方法,您现在可能想知道为什么我们需要将文本转换为整数序列,所以,记住我们要输入文本进入神经网络,神经网络只能理解数字。更精确地说,是固定长度的整数序列。

但是在执行所有这些操作之前,我们需要通过删除标点符号,小写所有字符等来清理该语料库。幸运的是,Keras具有内置类keras.preprocessing.text.Tokenizer(),该类可以在几行中完成所有这些工作。代码如下:

# Text tokenization
# vectorizing text, turning each text into sequence of integers
tokenizer = Tokenizer()
tokenizer.fit_on_texts(X)
# convert to sequence of integers
X = tokenizer.texts_to_sequences(X)


让我们尝试打印第一个样本:

In [4]: print(X[0])
[49, 472, 4436, 843, 756, 659, 64, 8, 1328, 87, 123, 352, 1329, 148, 2996, 1330, 67, 58, 4437, 144]


一堆数字,每个整数对应于词汇表中的一个单词,这正是神经网络所需要的。但是,样本的长度不同,我们需要一种固定长度的序列。

结果,我们使用了keras.preprocessing.sequence.pad_sequences()函数,该函数在每个序列的开头填充零。
# convert to numpy arrays
X = np.array(X)
y = np.array(y)
# pad sequences at the beginning of each sequence with 0's
# for example if SEQUENCE_LENGTH=4:
# [[5, 3, 2], [5, 1, 2, 3], [3, 4]]
# will be transformed to:
# [[0, 5, 3, 2], [5, 1, 2, 3], [0, 0, 3, 4]]
X = pad_sequences(X, maxlen=SEQUENCE_LENGTH)

您可能还记得,我们将SEQUENCE_LENGTH设置为100,这样所有序列的长度都为100。

现在我们的标签也是文本,但是我们将在这里采取另一种方法,因为标签只是“ spam”和“ ham”,我们需要对它们进行一次热编码:

# One Hot encoding labels
# [spam, ham, spam, ham, ham] will be converted to:
# [1, 0, 1, 0, 1] and then to:
# [[0, 1], [1, 0], [0, 1], [1, 0], [0, 1]]

y = [ label2int[label] for label in y ]
y = to_categorical(y)


我们在这里使用了keras.utils.to_categorial(),它的名字如其名,让我们尝试打印标签的第一个样本:

In [7]: print(y[0])
...

点击查看剩余70%

{{collectdata}}

网友评论0