Внедрение алгоритмов машинного обучения для классификации электронных писем

Классификация электронной почты - это проблема машинного обучения, которая относится к категории контролируемого обучения.

Этот мини-проект Email Classification вдохновлен J.K. Роулинг издает книгу под псевдонимом. Введение в машинное обучение от Udacity содержит всестороннее исследование алгоритмов и проекта.



Пару лет назад Роулинг написала книгу «Зов кукушки» под именем Роберт Гэлбрейт. Книга получила несколько хороших отзывов, но никто не обратил на нее особого внимания - пока анонимный аналитик в Твиттере не сказал, что это Дж.К. Роулинг. The London Sunday Times привлекла двух экспертов для сравнения лингвистических паттернов «Кукушки» с «Случайной вакансией» Роулинг, а также с книгами нескольких других авторов. После того, как результаты их анализа явно указали на Роулинг как на автора, Times прямо спросила издателя, были ли они одним и тем же человеком, и издатель подтвердил. Книга стала популярной в мгновение ока.

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

Набор данных

Набор данных можно взять из следующего репозитория GitHub:



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

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

В репозитории есть 2 файла рассола: word_data и email_authors.

Файл python email_preprocess служит для обработки данных из файлов солений. Он разбивает данные на поезд / тест с 0,1 тестовыми данными.

Наивный Байес:

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

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

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

Ниже приведен код Python, который вы можете реализовать в любой среде разработки Python с необходимыми библиотеками, установленными в вашей системе.

import sys
from time import time
sys.path.append("C:\\Users\\HP\\Desktop\\ML Code\\")
from email_preprocess import preprocess
import numpy as np
# using the Gaussian Bayes algorithm for classification of emails.
# the algorithm is imported from the sklearn library
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import accuracy_score
# initializaing the test and train features and labels
# the function preprocess is imported from email_preprocess.py 
features_train, features_test, labels_train, labels_test = preprocess()
# defining the classifier
clf = GaussianNB()
#predicting the time of train and testing
t0 = time()
clf.fit(features_train, labels_train)
print("\nTraining time:", round(time()-t0, 3), "s\n")
t1 = time()
pred = clf.predict(features_test)
print("Predicting time:", round(time()-t1, 3), "s\n")
#calculating and printing the accuracy of the algorithm
print("Accuracy of Naive Bayes: ", accuracy_score(pred,labels_test))

Выполнение кода дает нам следующие результаты:

Точность Наивного Байеса для этой конкретной задачи в 0.9203. Довольно хорошо, правда? Даже время обучения и прогнозирования алгоритма вполне разумно.

Машины опорных векторов

Машины опорных векторов - это также тип контролируемого обучения, используемый для классификации, регрессии, а также обнаружения выбросов. Мы можем использовать алгоритм SVM для классификации точек данных на 2 класса через плоскость, которая их разделяет. У SVM есть прямая граница принятия решений. Алгоритм SVM достаточно универсален, для функции принятия решения могут быть указаны разные функции ядра.

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

Наш классификатор - это классификация опорных векторов C с линейным ядром и значением C = 1.

clf = SVC (ядро = "линейное", C = 1)

import sys
from time import time
sys.path.append("C:\\Users\\HP\\Desktop\\ML Code\\")
from email_preprocess import preprocess
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score
### features_train and features_test are the features for the training
### and testing datasets, respectively
### labels_train and labels_test are the corresponding item labels
features_train, features_test, labels_train, labels_test = preprocess()
#defining the classifier
clf = SVC(kernel = 'linear', C=1)
#predicting the time of train and testing
t0 = time()
clf.fit(features_train, labels_train)
print("\nTraining time:", round(time()-t0, 3), "s\n")
t1 = time()
pred = clf.predict(features_test)
print("Predicting time:", round(time()-t1, 3), "s\n")
#calculating and printing the accuracy of the algorithm
print("Accuracy of SVM Algorithm: ", clf.score(features_test, labels_test))

Точность алгоритма SVM составляет 0,9596. Мы видим видимый компромисс между точностью и временем обучения. Повышение точности алгоритма является результатом более длительного времени обучения (22,7 с по сравнению с 0,13 с в случае Наивного Байеса). Мы можем поэкспериментировать с данными обучения, а также с ядрами, чтобы прийти к оптимальному выбору, который даст хороший показатель точности при меньшем времени обучения. !

Сначала мы разрежем набор обучающих данных до 1% от его исходного размера, выбрасывая 99% обучающих данных. Если остальная часть кода не изменилась, мы можем наблюдать значительное сокращение времени обучения и, как следствие, снижение точности. Компромисс заключается в том, что точность почти всегда снижается, когда мы разрезаем обучающие данные.

Используйте следующий код, чтобы сократить обучающие данные до 1%:

features_train = features_train[:len(features_train)//100]
labels_train = labels_train[:len(labels_train)//100]

Как видно, с 1% обучающих данных время обучения алгоритма было сокращено до 0,01 с с уменьшенной точностью до 0,9055.

При 10% данных обучения точность составляет 0,9550 при времени обучения 0,47 с.

Мы также можем изменить ядра и значение C в классификации C-опорных векторов scikit-learn.

При 100% обучающих данных, ядре RBF и значении C, установленном на 10000, мы получаем точность 0,9891 при времени обучения 14,718.

Деревья решений

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

Давайте посмотрим, как этот алгоритм работает с нашим набором данных.

import sys
from time import time
sys.path.append("C:\\Users\\HP\\Desktop\\ML Code\\")
from email_preprocess import preprocess
from sklearn import tree
from sklearn.metrics import accuracy_score
### features_train and features_test are the features for the training
### and testing datasets, respectively
### labels_train and labels_test are the corresponding item labels
features_train, features_test, labels_train, labels_test = preprocess()
# defining the classifier
clf = tree.DecisionTreeClassifier()
print("\nLength of Features Train", len(features_train[0]))
#predicting the time of train and testing
t0 = time()
clf.fit(features_train, labels_train)
print("\nTraining time:", round(time()-t0, 3), "s\n")
t1 = time()
pred = clf.predict(features_test)
print("Predicting time:", round(time()-t1, 3), "s\n")
#calculating and printing the accuracy of the algorithm
print("Accuracy of Decision Trees Algorithm: ", accuracy_score(pred,labels_test))

Выполнение приведенного выше кода дает нам точность 0,9880 и время обучения 6,116 с. Это очень хороший показатель точности, не так ли? У нас есть 100% обучающих данных, взятых для обучения модели.

Случайные леса

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

Мы можем использовать алгоритм случайных лесов из библиотеки sklearn в нашем наборе данных: RandomForestClassifier ().

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

import sys
from time import time
sys.path.append("C:\\Users\\HP\\Desktop\\ML Code\\")
from email_preprocess import preprocess
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
### features_train and features_test are the features for the training
### and testing datasets, respectively
### labels_train and labels_test are the corresponding item labels
features_train, features_test, labels_train, labels_test = preprocess()
# defining the classifier
clf = RandomForestClassifier(max_depth=2, random_state=0)
#predicting the time of train and testing
t0 = time()
clf.fit(features_train, labels_train)
print("\nTraining time:", round(time()-t0, 3), "s\n")
t1 = time()
pred = clf.predict(features_test)
print("Predicting time:", round(time()-t1, 3), "s\n")
#calculating and printing the accuracy of the algorithm
print("Accuracy of Random Forest Algorithm: ", accuracy_score(pred,labels_test))

Точность алгоритма довольно низкая, т.е. 0,7707. Время обучения составляет 1,2 секунды, что является разумным, но в целом не является хорошим инструментом для нашей задачи. Причина низкой точности - случайность выбора признаков, которая является свойством случайных лесов. Случайный лес - это модель, состоящая из множества деревьев решений. Вместо простого усреднения прогнозов деревьев (которые мы могли бы назвать «лесом») в этой модели используются две ключевые концепции, дающие ей название «случайный»: Случайная выборка точек обучающих данных при построении деревьев.

KNN - K Ближайшие соседи

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

Давайте посмотрим на результаты классификации писем с использованием алгоритма KNN из библиотеки sklearn KNeighborsClassifier () с 5 ближайшими соседями и евклидовой метрикой.

import sys
from time import time
sys.path.append("C:\\Users\\HP\\Desktop\\ML Code\\")
from email_preprocess import preprocess
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
### features_train and features_test are the features for the training
### and testing datasets, respectively
### labels_train and labels_test are the corresponding item labels
features_train, features_test, labels_train, labels_test = preprocess()
# defining the classifier
clf = KNeighborsClassifier(n_neighbors=5, metric='euclidean')
#predicting the time of train and testing
t0 = time()
clf.fit(features_train, labels_train)
print("\nTraining time:", round(time()-t0, 3), "s\n")
t1 = time()
pred = clf.predict(features_test)
print("Predicting time:", round(time()-t1, 3), "s\n")
#calculating and printing the accuracy of the algorithm
print("Accuracy of KNN Algorithm: ", accuracy_score(pred,labels_test))

Точность алгоритма составляет 0,9379 при времени обучения 2,883 с. Однако можно заметить, что инструмент модели значительно дольше предсказывает классы.

Классификатор AdaBoost

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

Мы будем использовать классификатор из библиотеки scikit. Ниже приведен код:

import sys
from time import time
sys.path.append("C:\\Users\\HP\\Desktop\\ML Code\\")
from email_preprocess import preprocess
from sklearn.ensemble import AdaBoostClassifier
from sklearn.metrics import accuracy_score
### features_train and features_test are the features for the training
### and testing datasets, respectively
### labels_train and labels_test are the corresponding item labels
features_train, features_test, labels_train, labels_test = preprocess()
# defining the classifier
clf = AdaBoostClassifier(n_estimators=100, random_state=0)
#predicting the time of train and testing
t0 = time()
clf.fit(features_train, labels_train)
print("\nTraining time:", round(time()-t0, 3), "s\n")
t1 = time()
pred = clf.predict(features_test)
print("Predicting time:", round(time()-t1, 3), "s\n")
#calculating and printing the accuracy of the algorithm
print("Accuracy of Ada Boost Classifier: ", accuracy_score(pred,labels_test))

Точность классификатора оказалась 0,9653 при времени обучения 17,946 с. Точность неплохая, однако время обучения немного больше, чем требуется.

Заключение

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

  • алгоритм случайных лесов имел самый низкий показатель точности
  • У алгоритма SVM было самое долгое время обучения
  • алгоритм SVM с оптимизированными параметрами C = 10000 и ядром RBF имел наивысший показатель точности
  • Наивный алгоритм Байеса имел самое быстрое время прогнозирования

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

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

Поделитесь своим опытом и подпишитесь на меня, чтобы увидеть больше статей!