Электронные письма со спамом — это незапрошенные нежелательные сообщения, рассылаемые в большом количестве на большое количество адресов электронной почты. Эти сообщения обычно носят рекламный, мошеннический характер или содержат вредоносное ПО и могут представлять угрозу безопасности устройства и личной информации получателя. В этом руководстве мы узнаем, как создать модель обнаружения спама в электронной почте с помощью Scikit-Learn, популярной библиотеки машинного обучения на Python.

Предпосылки

Чтобы следовать этому руководству, вам понадобится следующее:

  • Базовые знания программирования на Python
  • Установлена ​​библиотека Scikit-Learn (версия 0.24 или выше)
  • Набор данных Enron-Spam, который можно скачать по следующей ссылке: https://www2.aueb.gr/users/ion/data/enron-spam/. В частности, здесь мы будем использовать набор данных Eron1.


Теперь давайте начнем!

Шаг 1: Предварительная обработка данных

Первым шагом в построении модели обнаружения спама в электронной почте является предварительная обработка данных. Мы начнем с загрузки набора данных Enron-Spam, который содержит коллекцию спама и ветчины (не спама).

import os
from sklearn.model_selection import train_test_split

spam_path = "dataset/enron1/spam/"
ham_path = "dataset/enron1/ham/"

spam_emails = [os.path.join(spam_path, email) for email in os.listdir(spam_path)]
ham_emails = [os.path.join(ham_path, email) for email in os.listdir(ham_path)]

emails = spam_emails + ham_emails
labels = [1] * len(spam_emails) + [0] * len(ham_emails)

train_emails, test_emails, train_labels, test_labels = train_test_split(emails, labels, test_size=0.2)

Здесь мы импортируем необходимые библиотеки и определяем пути к папкам спама и ветчины в наборе данных. Затем мы используем модуль os, чтобы получить список всех имен файлов электронной почты в каждой папке и объединить их в два отдельных списка нежелательных и нежелательных электронных писем. Мы также создаем список меток, где 1 представляет спам, а 0 — нежелательное письмо.

Затем мы разделяем набор данных на наборы для обучения и тестирования, используя функцию train_test_split() из Scikit-Learn, где 80% данных используются для обучения и 20% для тестирования.



Шаг 2: Извлечение признаков

Следующим шагом является извлечение функций из электронных писем, которые можно использовать для обучения модели. Мы будем использовать подход Bag of Words, чтобы преобразовать электронные письма в числовое представление, понятное модели.

from sklearn.feature_extraction.text import CountVectorizer

vectorizer = CountVectorizer()
train_features = vectorizer.fit_transform(train_emails).toarray()
test_features = vectorizer.transform(test_emails).toarray() 

Здесь мы импортируем класс CountVectorizer из Scikit-Learn, который будет использоваться для преобразования электронных писем в набор слов. Затем мы создаем экземпляр класса CountVectorizer и используем метод fit_transform() для изучения словарного запаса обучающих данных и преобразования его в матрицу количества слов. Мы также используем метод transform() для преобразования данных тестирования с использованием того же словаря. Наконец, мы конвертируем матрицы в массивы NumPy для дальнейшей обработки.



Шаг 3: Обучение модели и оценка

После завершения этапа извлечения признаков мы можем обучить и оценить модель обнаружения спама в электронной почте. Мы будем использовать алгоритм мультиномиального наивного Байеса, который обычно используется для задач классификации текста.

from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score

nb = MultinomialNB()
nb.fit(train_features, train_labels)

train_predictions = nb.predict(train_features)
test_predictions = nb.predict(test_features) 

Теперь, когда мы обучили модель, мы можем оценить ее производительность, используя различные метрики оценки, такие как точность, достоверность, полнота и показатель F1.

train_accuracy = accuracy_score(train_labels, train_predictions)
test_accuracy = accuracy_score(test_labels, test_predictions)

train_precision = precision_score(train_labels, train_predictions)
test_precision = precision_score(test_labels, test_predictions)

train_recall = recall_score(train_labels, train_predictions)
test_recall = recall_score(test_labels, test_predictions)

train_f1_score = f1_score(train_labels, train_predictions)
test_f1_score = f1_score(test_labels, test_predictions)

print("Training Accuracy: ", train_accuracy)
print("Testing Accuracy: ", test_accuracy)
print("Training Precision: ", train_precision)
print("Testing Precision: ", test_precision)
print("Training Recall: ", train_recall)
print("Testing Recall: ", test_recall)
print("Training F1 Score: ", train_f1_score)
print("Testing F1 Score: ", test_f1_score)

Здесь мы импортируем необходимые метрики оценки из Scikit-Learn и используем их для расчета точности, достоверности, полноты и оценки F1 модели как на обучающем, так и на тестовом наборах.

Выводы приведенных выше операторов печати показаны ниже:

Training Accuracy:  1.0
Testing Accuracy:  1.0
Training Precision:  1.0
Testing Precision:  1.0
Training Recall:  1.0
Testing Recall:  1.0
Training F1 Score:  1.0
Testing F1 Score:  1.0

Обратите внимание, что в этом конкретном случае мы нашли оптимальные результаты с точки зрения метрик оценки, но может случиться так, что производительность модели не будет хорошей с точки зрения метрик оценки. Затем мы выполняем настройку гиперпараметров (которая обсуждается ниже), чтобы улучшить производительность модели.



Шаг 4: Настройка гиперпараметров

Производительность модели можно дополнительно улучшить, настроив ее гиперпараметры. Мы будем использовать перекрестную проверку поиска по сетке, чтобы найти оптимальные значения гиперпараметров alpha и fit_prior.

from sklearn.model_selection import GridSearchCV

param_grid = {
    'alpha': [0.01, 0.1, 1.0, 10.0],
    'fit_prior': [True, False]
}

grid = GridSearchCV(estimator=nb, param_grid=param_grid, cv=5)
grid.fit(train_features, train_labels)

print("Best Parameters: ", grid.best_params_)

Здесь мы импортируем класс GridSearchCV из Scikit-Learn, который будет использоваться для перекрестной проверки поиска по сетке. Мы определяем словарь гиперпараметров, которые необходимо настроить, и их соответствующие значения. Затем мы создаем экземпляр класса GridSearchCV и передаем наивную байесовскую модель, сетку параметров и количество сгибов для перекрестной проверки. Наконец, мы подгоняем объект поиска по сетке к обучающим данным и печатаем лучшие параметры, найденные алгоритмом.

Вывод приведенного выше оператора печати показан ниже:

Best Parameters:  {'alpha': 0.01, 'fit_prior': True}


Шаг 5: Уточнение модели

Используя оптимальные гиперпараметры, найденные с помощью поиска по сетке, мы теперь можем уточнить модель и снова оценить ее производительность.

nb = MultinomialNB(alpha=0.01, fit_prior=True)
nb.fit(train_features, train_labels)

train_predictions = nb.predict(train_features)
test_predictions = nb.predict(test_features)

train_accuracy = accuracy_score(train_labels, train_predictions)
test_accuracy = accuracy_score(test_labels, test_predictions)

train_precision = precision_score(train_labels, train_predictions)
test_precision = precision_score(test_labels, test_predictions)

train_recall = recall_score(train_labels, train_predictions)
test_recall = recall_score(test_labels, test_predictions)

train_f1_score = f1_score(train_labels, train_predictions)
test_f1_score = f1_score(test_labels, test_predictions)

print("Training Accuracy: ", train_accuracy)
print("Testing Accuracy: ", test_accuracy)
print("Training Precision: ", train_precision)
print("Testing Precision: ", test_precision)
print("Training Recall: ", train_recall)
print("Testing Recall: ", test_recall)
print("Training F1 Score: ", train_f1_score)
print("Testing F1 Score: ", test_f1_score)

Здесь мы создаем новый экземпляр наивной байесовской модели с оптимальными гиперпараметрами, найденными с помощью поиска по сетке. Затем мы обучаем модель и делаем прогнозы для обучающих и тестовых наборов. Наконец, мы оцениваем производительность модели, используя те же метрики оценки, что и раньше.

Выводы приведенных выше операторов печати показаны ниже:

Training Accuracy:  1.0
Testing Accuracy:  1.0
Training Precision:  1.0
Testing Precision:  1.0
Training Recall:  1.0
Testing Recall:  1.0
Training F1 Score:  1.0
Testing F1 Score:  1.0


Заключение

В этом руководстве мы узнали, как создать классификатор электронной почты для спама с использованием алгоритма Naive Bayes в Python. Мы начали с предварительной обработки данных и преобразования их в формат, подходящий для наивного байесовского алгоритма. Затем мы разделили данные на обучающие и проверочные наборы и обучили наивную байесовскую модель на обучающих данных. Мы оценили производительность модели как на тренировочном, так и на тестовом наборах, используя различные оценочные показатели, такие как точность, воспроизводимость и оценка F1. Затем мы выполнили настройку гиперпараметров с помощью перекрестной проверки поиска по сетке, чтобы найти оптимальные значения гиперпараметров alpha и fit_prior. Наконец, мы уточнили модель, используя оптимальные гиперпараметры, и снова оценили ее производительность.

Наивный байесовский алгоритм — это популярный алгоритм для задач классификации текста, таких как обнаружение спама в электронной почте. Это просто, быстро и эффективно для многих приложений. Однако это не лучший алгоритм для каждой задачи классификации текста. Всегда полезно попробовать разные алгоритмы и сравнить их производительность, чтобы найти лучший для конкретной задачи.