Руководство по созданию собственного спам-фильтра на Python

В этом посте мы собираемся использовать один простой алгоритм обработки естественного языка (НЛП), известный как мешок слов, чтобы классифицировать сообщения как спам или спам. Используя набор слов и функций, связанных с НЛП, мы получим практический опыт работы с небольшим набором данных для классификации SMS.

Итак, чего мы ждем?

Проблема: спам-сообщения

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

Спам также может использоваться в атаках типа «отказ в обслуживании» (DOS) или распределенного отказа в обслуживании (DDOS). Для фильтрации нежелательных сообщений используются различные методы, обычно основанные на фильтрации по содержанию. Это связано с тем, что определенные ключевые слова, ссылки или веб-сайты неоднократно массово рассылаются пользователям, что характеризует их как спам.

Решение: классификация текста

Для сравнения, языки сложнее интерпретировать и анализировать алгоритмами, чем числовые данные. Это верно по нескольким причинам:

  1. Предложения не имеют фиксированной длины, но для большинства алгоритмов требуется стандартный размер входного вектора. Таким образом, требуется заполнение, соответствующее самому большому предложению в корпусе.
  2. Алгоритмы машинного обучения не могут воспринимать слова как входные данные: следовательно, каждое слово должно быть представлено некоторым числовым значением.

Модель мешка слов

Модель набора слов позволяет нам извлекать функции из текстовых данных. Как мы знаем, алгоритм не понимает языка. Таким образом, нам нужно использовать числовое представление слов в корпусе. Это числовое представление впоследствии может быть использовано в любом алгоритме для дальнейшего анализа.

Это называется «мешком слов», потому что в этой модели теряется порядок слов или структура предложения. Имеет значение только появление или присутствие слова.

Мы можем думать о модели таким образом - у нас есть большая сумка, пустая вначале, и словарь или корпус. Мы берем слова одно за другим и кладем их в сумку, увеличивая частоту их появления, а затем выбираем наиболее распространенные слова в качестве признаков для прохождения через наш алгоритм выбора.

Таким образом, это способствует представлению о том, что похожие документы состоят из похожих слов.

Набор данных

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

Вы можете найти набор данных здесь. Полный исходный код можно найти в репозитории this.

Импорт набора данных

Чтобы импортировать набор данных в фреймворк Pandas, мы используем пару строк, написанных ниже:

import pandas as pd
dataset = pd.read_csv('spam.csv', encoding='ISO-8859-1');

Вот краткий обзор набора данных, над которым мы работаем. Позже мы конвертируем метки в фиктивные переменные.

Предварительные условия

  1. НЛТК для задач, связанных с НЛП
  2. NumPy и Pandas для математических операций
  3. Scikit-learn для токенизации и модели tf-idf
  4. Матплотлиб и Сиборн для задач визуализации

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

Удаление игнорируемых слов

Стоп-слова относятся к словам в заявлении, которые не придают ему особого значения. Они часто включают предлоги, вспомогательные глаголы и артикли (например, in, the, an, is). Поскольку они не добавляют ценности нашей модели, нам необходимо их искоренить.

nltk.download('stopwords')
from nltk.corpus import stopwords
stopwords.words('english')

Удаление неалфавитных символов

Поскольку для классификации текста мы используем только слова, нам нужно избавиться от знаков препинания и цифр. Для этого мы используем сопоставление строк или регулярное выражение в Python. В приведенном ниже регулярном выражении сохраняются только буквенные слова, остальные отбрасываются.

text = re.sub('[^A-Za-z]', ' ', text)

Меняем все на нижний регистр

Модель не может различать строчные и прописные буквы, рассматривая «текст» и «текст» как разные слова. Мы определенно этого не хотим; поэтому для простоты мы меняем регистр всех слов на строчные.

text = text.lower()

Орфографические исправления

Иногда люди по ошибке пишут сокращения или неправильно пишут слова. Чтобы исправить эти случаи, мы используем пакет автозамены и его корректор орфографии.

from autocorrect import spell
text.append(spell(word))

Стеминг и лемматизация

Такие слова, как «действие», «действующее лицо» и «действие», имеют одно и то же корневое слово (действие). Одинаковые основы и лемматизация - это методы, используемые для усечения слов с целью получения основы или основного слова.

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

Например, «исследования» могут быть обозначены как «studi» (а не слово), но будут преобразованы в «исследование» (существующее слово).

Вот сравнение набора данных до и после стемминга.

Вы можете заметить, что выделенные слова входят в число немногих, которые нужно исключить. Кроме того, в большинстве случаев слова с корнями не являются настоящими словами.

Визуализация ключевых слов спама

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

from wordcloud import WordCloud
import matplotlib.pyplot as plt
spam_wc = WordCloud(width = 600,height = 512).generate(spam_words)
plt.figure(figsize = (12, 8), facecolor = 'k')
plt.imshow(spam_wc)
plt.show()

Функциональная инженерия

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

Токенизация

Для реализации пакета слов мы используем CountVectorizer из scikit-learn, который подсчитывает частоту каждого слова, присутствующего в нашем предварительно обработанном наборе данных, и принимает n наиболее распространенных слов в качестве функций.

CountVectorizer возвращает матрицу, в которой строки содержат количество сообщений, содержащих слово, а столбцы - это лучшие выбранные функции.

from sklearn.feature_extraction.text import CountVectorizer
data = CountVectorizer(max_features=2000)
X = data.fit_transform(dataset).toarray()

Поскольку счетчик-вектор содержит 2000 объектов, их сложно здесь изобразить. Таким образом, для примера ниже мы берем первые 25 слов нашего набора данных, токенизируем их и выбираем 10 из наиболее часто используемых.

Матрица, которая представляет частоту каждой из этих функций в наших сообщениях (наборе данных), приведена ниже:

Разработка модели

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

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y)
from sklearn.naive_bayes import GaussianNB
classifier = GaussianNB()
classifier.fit(X_train, y_train)
y_pred = classifier.predict(X_test)

Полученные результаты

Давайте посмотрим, как наша простая модель работает на тестовой выборке:

Похоже, наша модель пересекла финишную черту с приличной точностью ~ 80%. Не чем похвастаться, но все же довольно прилично, учитывая простоту нашей модели и ее недостатки, которые обсуждаются в следующем разделе. Таким образом, мы можем сказать, что наша модель с хорошей степенью уверенности различает спам и любительскую рассылку.

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

Недостатки модели мешка слов

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

Кроме того, структура предложения не имеет значения в глазах нашей модели. Два предложения, такие как «Эти моллюски хороши» и «Эти моллюски хороши?» означают то же самое для модели мешка слов, хотя один - это претензии, а другой - вопрос. Кроме того, для большого словарного запаса набор слов приводит к очень многомерному вектору.

Улучшения указанной выше модели

Вот несколько способов повысить точность вышеуказанной модели:

  1. Используя специально созданные игнорируемые слова, в соответствии с требованиями набора данных (какой язык или жаргон использует ваш набор данных), вы можете добавлять другие слова в соответствии с языком корпуса. Некоторые тексты или ссылки относятся к спам-сообщениям, или добавлен жаргон для прохождения общих спам-фильтров. Этого можно избежать, хорошо проанализировав набор данных и зная, в частности, структуру и содержание спам-сообщений, адаптируя ключевые слова к нашим потребностям.
  2. Вместо использования юниграмм (отдельных слов) использование биграмм и триграмм может быть полезным для лучшего понимания смысла сообщения. Например, возьмем сообщение - «подарочная карта на миллионы». Здесь вместо использования юниграмм, которые дадут нам «подарок», «карту», ​​«ценность», «миллионы», мы можем использовать биграммы, которые вместе дают нам «подарочную карту» или «стоимость на миллионы». характерная черта. Как видите, это может явно указывать на спам-сообщение, тогда как «подарок», «карта», «ценность» и «миллионы» по отдельности могут быть частью любого повседневного разговора.
  3. Примените модель векторного пространства, такую ​​как подобие косинуса между сообщениями, и используйте векторизацию tf-idf, чтобы лучше понять относительный вес слова по отношению к важности этого документа. Подробнее об этом вы можете прочитать здесь, в этой статье.

Репозиторий

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



Источники для начала работы с НЛП





Заключение

В этом посте мы реализовали классификатор текста спама, используя модель набора слов. Мы узнали, как эффективно работать с текстовыми данными и разработать надежную модель, используя несколько концепций НЛП.

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

До следующего раза! 😁

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

Независимая редакция, Heartbeat спонсируется и публикуется Comet, платформой MLOps, которая позволяет специалистам по обработке данных и группам машинного обучения отслеживать, сравнивать, объяснять и оптимизировать свои эксперименты. Мы платим участникам и не продаем рекламу.

Если вы хотите внести свой вклад, отправляйтесь на наш призыв к участникам. Вы также можете подписаться на наши еженедельные информационные бюллетени (Deep Learning Weekly и Comet Newsletter), присоединиться к нам в » «Slack и подписаться на Comet в Twitter и LinkedIn для получения ресурсов, событий и гораздо больше, что поможет вам быстрее и лучше строить модели машинного обучения.