Давайте начнем…

Написано много романов, но некоторые из них с годами приобретают статус культовых и вспоминаются на века. Романы нескольких жанров и кросс-жанров (смешение нескольких жанров). Ужасы - это особый жанр романов. Есть много известных романов ужасов, которые являются абсолютными фаворитами читателей даже спустя десятилетия после их выхода. Например, Сериал «Мурашки по коже» (1998–2016) Р.Л. Стайна стал нарицательным и одним из самых знаменитых романов ужасов современности. Но до 21 века появилось много классических романов ужасов. Например, роман ужасов Поиски во сне неизвестного Кадата (1943) Х.П. Лавкрафт был одним из романов ужасов ХХ века, которые необходимо прочитать. Отсюда, если мы вернемся в XIX век, как можно забыть Франкенштейн (1818 и 1823) Мэри Шелли и Падение дома Ашеров (1839) Эдгара Аллана По ? Но совершенно очевидно одно:

У каждого автора, будь то Лавкрафт, Мэри Шелли или По, был свой стиль письма, включающий в себя фирменную манеру использования определенных слов, делающую их литературу уникальной и узнаваемой

Итак, давайте воспользуемся этим фактом, чтобы идентифицировать автора (Лавкрафт / Мэри Шелли / По) по фрагментам текста или цитатам из их романов ужасов. Машинное обучение на основе обработки естественного языка (NLP) - отличное решение вышеуказанной проблемы. Итак, давайте четко сформулируем проблему и приступим к работе !!!

Постановка проблемы: «Приведенные фрагменты текста / цитаты из известных романов Эдгара Аллана По, Мэри Шелли и Х.П. Лавкрафта позволяют определить, кто является автором фрагмента текста или цитаты»

Для этой цели рассматривается Spooky Author Identification Dataset, подготовленный Kaggle.

Итак, приступим к разработке модели машинного обучения на Python с использованием NLTK (Natural Language Took Kit) и Scikit-Learn !!!

I. Загрузка (чтение) набора данных с помощью Pandas:

import pandas as pd
df = pd.read_csv('train.csv')
df.head(5) # for showing a snapshot of the dataset

II. Этапы обработки текста:

  1. Удаление знаков препинания → Все знаки пунктуации удаляются из всех текстовых фрагментов (экземпляров или документов) из набора данных (корпуса).
  2. Лемматизация → Склоняемые формы слова известны как лемма. Например, (учеба, учеба) - это флективные формы или лемма слова учеба, которое является корневым словом. Итак, леммы слова сгруппированы под одним корневым словом. Это сделано для того, чтобы словарь слов в корпусе содержал только отдельные слова.
  3. Удаление стоп-слов → Стоп-слова обычно представляют собой артикли (a, an, the), предлоги (in, on, under,…) и другие часто встречающиеся слова, не содержащие ключевой или необходимой информации. Они удаляются из всех текстовых фрагментов, присутствующих в наборе данных (корпусе).
# Importing necessary libraries
import string
from nltk.corpus import stopwords
from nltk.stem import WordNetLemmatizer
lemmatiser = WordNetLemmatizer()
# Defining a module for Text Processing
def text_process(tex):
    # 1. Removal of Punctuation Marks 
    nopunct=[char for char in tex if char not in string.punctuation]
    nopunct=''.join(nopunct)
    # 2. Lemmatisation 
    a=''
    i=0
    for i in range(len(nopunct.split())):
        b=lemmatiser.lemmatize(nopunct.split()[i], pos="v")
        a=a+b+' '
    # 3. Removal of Stopwords
    return [word for word in a.split() if word.lower() not 
            in stopwords.words('english')]

III. Кодирование ярлыков классов:

Поскольку это проблема классификации, здесь классы - это 3 автора, как упоминалось. Но в наборе данных видно, что метки не являются числовыми (MWS, EAP и HPL). Эти метки закодированы, чтобы сделать их числовыми, начиная с 0, отображая каждую метку в алфавитном порядке, то есть (0 → EAP, 1 → HPL и 2 → MWS)

# Importing necessary libraries
from sklearn.preprocessing import LabelEncoder
y = df['author']
labelencoder = LabelEncoder()
y = labelencoder.fit_transform(y)

IV. Визуализация облака слов:

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

# Importing necessary libraries
from PIL import Image
from wordcloud import WordCloud
import matplotlib.pyplot as plt
X = df['text']
wordcloud1 = WordCloud().generate(X[0]) # for EAP
wordcloud2 = WordCloud().generate(X[1]) # for HPL
wordcloud3 = WordCloud().generate(X[3]) # for MWS 
print(X[0])
print(df['author'][0])
plt.imshow(wordcloud1, interpolation='bilinear')
plt.show()
print(X[1])
print(df['author'][1])
plt.imshow(wordcloud2, interpolation='bilinear')
plt.show()
print(X[3])
print(df['author'][3])
plt.imshow(wordcloud3, interpolation='bilinear')
plt.show()

V. Разработка функций с помощью пакета слов:

Алгоритмы машинного обучения работают только с числовыми данными. Но здесь данные представлены только в виде текста. Для этого нужно каким-то образом преобразовать текстовые данные в числовую форму. Один из таких подходов - Feature Engineering. В этом подходе числовые функции извлекаются или создаются из текстовых данных. Существует множество методов проектирования функций. В этой задаче была использована техника «мешка слов» при проектировании признаков.

= ›Мешок слов:

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

# Importing necessary libraries
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.model_selection import train_test_split
# 80-20 splitting the dataset (80%->Training and 20%->Validation)
X_train, X_test, y_train, y_test = train_test_split(X, y
                                  ,test_size=0.2, random_state=1234)
# defining the bag-of-words transformer on the text-processed corpus # i.e., text_process() declared in II is executed...
bow_transformer=CountVectorizer(analyzer=text_process).fit(X_train)
# transforming into Bag-of-Words and hence textual data to numeric..
text_bow_train=bow_transformer.transform(X_train)#ONLY TRAINING DATA
# transforming into Bag-of-Words and hence textual data to numeric..
text_bow_test=bow_transformer.transform(X_test)#TEST DATA

VI. Обучение модели:

Полиномиальный наивный байесовский алгоритм (классификатор) использовался в качестве алгоритма машинного обучения классификации [1].

# Importing necessary libraries
from sklearn.naive_bayes import MultinomialNB
# instantiating the model with Multinomial Naive Bayes..
model = MultinomialNB()
# training the model...
model = model.fit(text_bow_train, y_train)

VII. Анализ эффективности модели:

= ›Точность тренировки

model.score(text_bow_train, y_train)

= ›Точность проверки

model.score(text_bow_test, y_test)

= ›Точность, отзывчивость и F1 – оценка

# Importing necessary libraries
from sklearn.metrics import classification_report
 
# getting the predictions of the Validation Set...
predictions = model.predict(text_bow_test)
# getting the Precision, Recall, F1-Score
print(classification_report(y_test,predictions))

= ›Матрица путаницы

# Importing necessary libraries
from sklearn.metrics import confusion_matrix
import numpy as np
import itertools
import matplotlib.pyplot as plt
# Defining a module for Confusion Matrix...
def plot_confusion_matrix(cm, classes,
                          normalize=False,
                          title='Confusion matrix',
                          cmap=plt.cm.Blues):
    """
    This function prints and plots the confusion matrix.
    Normalization can be applied by setting `normalize=True`.
    """
    if normalize:
        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
        print("Normalized confusion matrix")
    else:
        print('Confusion matrix, without normalization')
print(cm)
plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45)
    plt.yticks(tick_marks, classes)
fmt = '.2f' if normalize else 'd'
    thresh = cm.max() / 2.
    for i, j in itertools.product(range(cm.shape[0])
                                  , range(cm.shape[1])):
        plt.text(j, i, format(cm[i, j], fmt),
                 horizontalalignment="center",
                 color="white" if cm[i, j] > thresh else "black")
plt.tight_layout()
    plt.ylabel('True label')
    plt.xlabel('Predicted label')
cm = confusion_matrix(y_test,predictions)
plt.figure()
plot_confusion_matrix(cm, classes=[0,1,2], normalize=True,
                      title='Confusion Matrix')

Согласно анализу производительности, можно сделать вывод, что модель машинного обучения на основе NLP успешно классифицирует 84,14% неизвестных (проверочный набор) примеров. Другими словами, 84,14% текстовых сниппетов идентифицируются правильно, какому автору принадлежит из трех.

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

Ответ ДА ​​!!! Давайте посмотрим на нормализованную матрицу неточностей. Здесь метка 2 классифицируется наиболее правильно. Поскольку метка 2 относится к Мэри Уоллстонкрафт Шелли, можно сделать вывод, что

Мэри Уоллстонкрафт Шелли обладает самым уникальным стилем написания романов ужасов с Эдгаром Алланом По и Г.П. Лавкрафтом.

Кроме того, с другой стороны, можем ли мы сказать, кто из авторов Мэри Шелли, Эдгара Аллана По и Г.П. Лавкрафта самый разносторонний?

И снова ответ ДА ​​!!! Снова посмотрев на матрицу путаницы, метка 0 классифицируется наименее правильно. Метка 0 относится к Эдгару Аллану По, поэтому можно сделать вывод, что

Эдгар Аллан По более универсален, чем Лавкрафт и Мэри Шелли.

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

Соответствующее веб-приложение, использующее обученный Bernoulli Naive Bayes (вместо Multinomial Naive Bayes), также было разработано и развернуто в Heroku с использованием Flask API. Ссылка на веб-приложение приведена ниже:

Https://authoridentifier.herokuapp.com/

ССЫЛКИ

[1] https://towardsdatascience.com/multinomial-naive-bayes-classifier-for-text-analysis-python-8dd6825ece67

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