Автор статьи: Рустем Галиев
IBM Senior DevOps Engineer & Integration Architect
Привет Хабр!
Отправка URL-адресов через сообщения SMS (служба коротких сообщений) является наиболее используемой функцией SMS. Хакеры часто отправляют вредоносные URL-адреса через эти текстовые сообщения и призывают получателей щелкнуть ссылку, что может поставить под угрозу личность пользователя и раскрыть личную информацию. Хакеры также используют метод, при котором они отправляют номер мобильного телефона через SMS и убеждают получателей позвонить по этому номеру, а затем используют сложное программное обеспечение для извлечения и использования информации о вызывающем абоненте.
Из-за такого потенциального неправомерного использования SMS хакерами важно иметь возможность идентифицировать спам-сообщения. Традиционные методы выявления SMS-спама включают в себя выявление контрольных признаков, таких как сообщение о срочности или отправка сообщений «судного дня», таких как закрытие или отключение важных учетных записей или служб получателя. Используя эти контрольные шаблоны, предоставленные экспертами, можно обучить машину с помощью обучения с учителем обнаруживать спам-SMS.
Полноценная модель машинного обучения для обнаружения спама для SMS будет обучена содержанию SMS, номеру мобильного телефона отправителя, URL-адресам, включенным в содержимое SMS, номеру мобильного телефона, включенному в содержимое SMS, и т. д. Однако достаточно мощную модель машинного обучения для обнаружения спама можно разработать, просто проанализировав содержимое SMS-сообщения. Мы разработаем модель машинного обучения для обнаружения спама путем лексического анализа содержимого SMS.
Шаги по разработке модели машинного обучения для обнаружения спама в SMS следующие:
Сборка помеченного набора данных SMS, содержащего как безопасные SMS, так и SMS-спам.
Извлечение признаков из набора данных. Эти функции будут включать наличие или отсутствие URL-адреса, а также наличие или отсутствие номера мобильного телефона.
Очищение содержимого SMS, сохранив только необходимый текст, который может способствовать построению модели обнаружения спама в SMS.
Разделение данных на обучающий набор и тестовый набор.
Создание матрицы TF-IDF (частота термина – обратная частота документа) из обучающего набора.
Используя функции, извлеченные из содержимого SMS, создание модели машинного обучения случайного леса для классификации.
Наконец, тестирование разработанной модели с помощью тестового набора.
Сегодня мы завершим шаг 5, упомянутый выше, то есть векторизируем данные для создания матрицы TF-IDF из содержимого SMS, доступного в наборе данных. Содержание sms: текстовое. Мы знаем, что модели машинного обучения — это, по сути, математические модели, поэтому нам нужно преобразовать текст в числа, прежде чем мы сможем смоделировать данные. Этот процесс преобразования текста в числа также называется векторизацией. Для каждой точки данных мы создадим векторы TF-IDF. И эти векторы вместе образуют матрицу TF-IDF. Поскольку матрицу TF-IDF трудно визуализировать для большого набора данных, мы поймем и визуализируем матрицу TF-IDF, используя очень маленький набор тестовых данных.
Сегодня мы:
Создадим и визуализируем матрицу TF-IDF на тестовом наборе данных.
Создадим матрицу TF-IDF для обучающего набора данных.
Объединим все функции для набора обучающих данных.
Содержание SMS представляет собой набор текста. Мы знаем, что модели машинного обучения — это математические модели, поэтому мы можем создать модель машинного обучения только с использованием чисел. Сначала найдем способ преобразовать текст содержимого SMS в числа. Этот процесс преобразования текста в числа также называется векторизацией. Существует множество методов векторизации. Одним из сложных методов векторизации является использование векторизатора TF-IDF (частота термина — обратная частота документа).
TF-IDF — это статистическая мера, используемая для оценки важности различных слов в корпусе (наборе документов). В нашем случае коллекция SMS образует корпус, где каждое SMS является документом. Важность, или вес TF-IDF, прямо пропорциональна количеству раз, которое слово встречается в документе (TF) и обратно пропорционально частоте этого слова во всех документах в корпусе.
TF: Частота термина слова — это общее количество раз, когда слово появляется в документе, деленное на общее количество слов в этом документе.
IDF: обратная частота слова в документе рассчитывается как логарифм количества документов в корпусе, деленный на общее количество документов, содержащих это слово в них.
Вес TF-IDF является произведением этих двух величин.
Нам не придется выполнять столько вычислений, потому что мы будем использовать реализацию TF-IDF, доступную в библиотеке Scikit-Learn. Cтратегия преобразования текста в числа состоит в том, чтобы присвоить значение важности каждого слова в каждом SMS, поэтому мы хотим, чтобы машина запоминала важность каждого слова, которое может быть связано с безопасными SMS и спамом. На этом этапе мы создадим матрицу TF-IDF для тестового набора данных, чтобы иметь возможность понять и визуализировать матрицу TF-IDF. Также создадим кадр данных из тестового набора данных и применим к нему векторизацию TF-IDF, чтобы сформировать матрицу TF-IDF.
Прежде чем мы сможем начать кодирование, необходимо создать файл, в котором будем писать наш код
spamSMSDetection.py
Начнем писать код:
import os
os.system('clear')
import pandas as pd
import cleanData
text1 = "This is a test of Stop Word remover"
text2 = "'This'; is a #test $tring, sent: to @someone."
text3 = "This text contains 66 numbers and 1654 characters."
text4 = "This is a test of removing extra white spaces"
df = pd.DataFrame([text1, text2, text3, text4], columns = ['text'])
df['text'] = df.text.apply(cleanData.cleanData)
print('The dataframe is as shown below\n', df)
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf = TfidfVectorizer(min_df = 0, use_idf = True, ngram_range = (1, 1))
tfidfText = tfidf.fit_transform(df.text)
dfTFIDF = pd.DataFrame(tfidfText.todense(), columns = tfidf.get_feature_names_out())
print('\nThe TF-IDF matrix formed is as shown below\n', dfTFIDF)
Протестируем python3 spamSMSDetection.py
В показанном выводе каждая строка относится к одной из точек данных, а столбцы относятся ко всем словам извлеченным из тестового набора данных. Число, указанное на пересечении каждой строки и столбца, представляет собой важность слов в их документах.
Обратите внимание, что в выводе много нулей. Нули указывают, что эти слова отсутствуют в связанных документах. Это будет иметь место с большей частью сформированной матрицы TF-IDF, поскольку общее количество различных слов во всех документах будет большим. Образовавшаяся матрица называется разреженной матрицей. Когда мы формируем матрицу TF-IDF из набора данных, доступного для моделирования обнаружения спама в SMS, увидим в основном нули, когда попытаемся отобразить матрицу TF-IDF.
Сформируем матрицу TF-IDF из содержимого SMS, доступного в нашем наборе данных.
На предыдущем шаге мы увидели визуализацию матрицы TF-IDF, где нашли важность каждого уникального слова в документах. См. параметр ngram_range. Этот параметр управляет ngrams, которые будут использоваться для создания уникальных функций в TF-IDF. Nграммы — это комбинации последовательных слов в данных, поэтому 1-граммы — это все отдельные слова, а 2-граммы — это пары последовательных слов в тексте, такие как «это», «дайте отзыв» и т. д. Установка ngram_range
в (1 , 1) означает, что мы будем рассматривать только отдельные слова. В приведенном ниже коде я указал ngram_range
как (1, 4). Это означает, что мы будем рассматривать все отдельные слова и все комбинации из двух, трех и четырех слов.
import createDataSets
_, X_train, X_test, y_train, y_test = createDataSets.createDataSets()
os.system('clear')
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf = TfidfVectorizer(min_df = 0, use_idf = True, ngram_range = (1, 4))
tfidfText = tfidf.fit_transform(X_train.cText)
dfTFIDF = pd.DataFrame(tfidfText.todense(), columns = tfidf.get_feature_names_out())
print('The number of unique features extracted is %d' % (dfTFIDF.shape[1]))
print('\nThe first few rows of the TF-IDF matrix formed is as shwon below\n', dfTFIDF.head())
Запустимpython3 spamSMSDetection.py
Мы видим, что теперь у нас есть 87 653 функции(features) для обучения нашей модели. Обратите внимание, что существуют функции с 1 граммом, такие как «zs», функции с 2 граммами, такие как «подписка zs», функции с 3 граммами, такие как «подписка zs pw» и т. д.
Вывод, который вы видите, в основном содержит все нули. Однако в этой матрице будут числа для важности слов, встречающихся в документах.
Мы сгенерировали матрицу TF-IDF. Теперь у нас есть 87 653 функции. Однако есть еще две функции для количества URL-адресов в SMS и количества мобильных номеров в SMS. На этом этапе добавим эти две функции к функциям, сгенерированным из TF-IDF.
X_train_temp = dfTFIDF
X_train_temp['noURLs'] = X_train['noURLs']
X_train_temp['noMobiles'] = X_train['noMobiles']
X_train_temp['noURLs'] = X_train_temp['noURLs'].fillna(0)
X_train_temp['noMobiles'] = X_train_temp['noMobiles'].fillna(0)
X_train = X_train_temp
print('\n\nThe shape of the Training Data = ', X_train.shape)
Запустимpython3 spamSMSDetection.py
Обратите внимание, что в обучающих данных у нас 87 655 столбцов. Другими словами, в обучающих данных содержится 87 655 признаков (или независимых переменных).
В обучающих данных содержится 5014 точек данных (или строк). Мы знаем, что для каждой точки обучающих данных в X_train
у нас есть связанная метка в y_train
.
Полный код:
import os
os.system('clear')
import pandas as pd
import cleanData
text1 = "This is a test of Stop Word remover"
text2 = "'This'; is a #test $tring, sent: to @someone."
text3 = "This text contains 66 numbers and 1654 characters."
text4 = "This is a test of removing extra white spaces"
df = pd.DataFrame([text1, text2, text3, text4], columns = ['text'])
df['text'] = df.text.apply(cleanData.cleanData)
print('The dataframe is as shown below\n', df)
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf = TfidfVectorizer(min_df = 0, use_idf = True, ngram_range = (1, 1))
tfidfText = tfidf.fit_transform(df.text)
dfTFIDF = pd.DataFrame(tfidfText.todense(), columns = tfidf.get_feature_names_out())
print('\nThe TF-IDF matrix formed is as shown below\n', dfTFIDF)
import createDataSets
_, X_train, X_test, y_train, y_test = createDataSets.createDataSets()
os.system('clear')
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf = TfidfVectorizer(min_df = 0, use_idf = True, ngram_range = (1, 4))
tfidfText = tfidf.fit_transform(X_train.cText)
dfTFIDF = pd.DataFrame(tfidfText.todense(), columns = tfidf.get_feature_names_out())
print('The number of unique features extracted is %d' % (dfTFIDF.shape[1]))
print('\nThe first few rows of the TF-IDF matrix formed is as shwon below\n', dfTFIDF.head())
X_train_temp = dfTFIDF
X_train_temp['noURLs'] = X_train['noURLs']
X_train_temp['noMobiles'] = X_train['noMobiles']
X_train_temp['noURLs'] = X_train_temp['noURLs'].fillna(0)
X_train_temp['noMobiles'] = X_train_temp['noMobiles'].fillna(0)
X_train = X_train_temp
print('\n\nThe shape of the Training Data = ', X_train.shape)
Итак, мы научились извлекать функции из содержимого SMS, чтобы подготовиться к построению модели машинного обучения. А именно научились делать следующее:
Создание матрицы TF-IDF для обучающего набора данных.
Объединение всех функций для набора обучающих данных
Вот конец первой части, далее займемся построением модели обнаружения спама в sms с использованием алгоритма модели случайного леса и будем её тестировать.
Статья подготовлена в преддверии старта курса Machine Learning. Professional. Узнать о курсе подробнее и бесплатно посетить урок: "Мы похожи на свое окружение: алгоритм k Nearest Neighbours для задачи классификации" можно по ссылке ниже.