Создайте программу классификации текста: учебник по НЛП
Опубликовано: 2022-03-11Глубокое обучение — это технология, которая стала неотъемлемой частью рабочих процессов машинного обучения. Благодаря усовершенствованию параллельной вычислительной мощности и вспомогательных инструментов сложные и глубокие нейронные сети, которые когда-то были непрактичными, теперь становятся жизнеспособными.
Появление мощных и доступных библиотек, таких как Tensorflow, Torch и Deeplearning4j, также открыло возможности разработки для пользователей за пределами научных кругов и исследовательских отделов крупных технологических компаний. В подтверждение его растущей повсеместности такие компании, как Huawei и Apple, теперь включают в свои новейшие устройства специализированные процессоры, оптимизированные для глубокого обучения, для поддержки приложений глубокого обучения.
Глубокое обучение доказало свою эффективность во многих областях. В частности, AlphaGo от Google смогла победить игроков-людей в игре Го, чья умопомрачительная сложность когда-то считалась почти непреодолимым барьером для компьютеров в их соревновании с игроками-людьми. Проект Flow Machines от Sony разработал нейросеть, способную сочинять музыку в стиле известных музыкантов прошлого. FaceID, функция безопасности, разработанная Apple, использует глубокое обучение для распознавания лица пользователя и отслеживания изменений лица пользователя с течением времени.
В этой статье мы применим глубокое обучение к двум моим любимым темам: обработке естественного языка и вину. Мы построим модель, чтобы понимать обзоры вин, сделанные экспертами на естественном языке, и делать выводы о разнообразии вин, которые они рассматривают.
Глубокое обучение для НЛП
Глубокое обучение широко используется в обработке естественного языка (НЛП), потому что оно хорошо подходит для изучения сложной базовой структуры предложения и семантической близости различных слов. Например, современное состояние анализа настроений использует глубокое обучение, чтобы зафиксировать трудно моделируемые лингвистические понятия, такие как отрицание и смешанные чувства.
Глубокое обучение имеет ряд преимуществ перед другими алгоритмами НЛП:
- Гибкие модели. Модели глубокого обучения гораздо более гибкие, чем другие модели машинного обучения. Мы можем легко экспериментировать с различными структурами, добавляя и удаляя слои по мере необходимости. Модели глубокого обучения также позволяют создавать модели с гибкими выходными данными. Гибкость является ключом к разработке моделей, которые хорошо подходят для понимания сложных лингвистических структур. Это также важно для разработки приложений NLP, таких как переводы, чат-боты и приложения для преобразования текста в речь.
- Требуется меньше знаний в предметной области: хотя для разработки хорошей модели глубокого обучения, безусловно, нужны некоторые знания в предметной области и интуиция, способность алгоритмов глубокого обучения самостоятельно изучать иерархии функций означает, что разработчику не нужно столь глубокое знание предметной области. проблемное пространство для разработки алгоритмов глубокого обучения НЛП. Для такого сложного проблемного пространства, как естественный язык, это очень долгожданное преимущество.
- Более простое непрерывное обучение: алгоритмы глубокого обучения легко обучать по мере поступления новых данных. Некоторые алгоритмы машинного обучения требуют, чтобы весь набор данных был отправлен через модель для обновления, что может создать проблему для живых больших наборов данных.
Проблема сегодня
Сегодня мы построим алгоритм глубокого обучения, чтобы определить сорт рассматриваемого вина на основе текста обзора. Мы будем использовать набор данных винного журнала по адресу https://www.kaggle.com/zynicide/wine-reviews, предоставленный пользователем Kaggle zackthoutt .
Концептуально вопрос в том, можем ли мы рассматривать винный обзор как…
Ароматы включают тропические фрукты, метлу, серу и сушеные травы. Вкус не слишком выразительный, предлагая нотки незрелого яблока, цитрусовых и сушеного шалфея, а также острую кислотность.
…и признать, что речь идет о белой смеси? Некоторые винные энтузиасты могут распознавать явные признаки белых вин, такие как яблоко, цитрусовые и ярко выраженная кислотность, но можем ли мы научить нашу нейронную сеть распознавать эти сигналы? Кроме того, можем ли мы научить нашу нейронную сеть распознавать тонкие различия между обзором белого бленда и обзором пино гриджо?
Похожие алгоритмы
Проблема, с которой мы сегодня работаем, по сути является проблемой классификации НЛП. Существует несколько алгоритмов классификации НЛП, которые применялись к различным задачам НЛП. Например, наивный байесовский метод использовался в различных алгоритмах обнаружения спама, а машины опорных векторов (SVM) использовались для классификации текстов, таких как заметки о ходе работы в медицинских учреждениях. Было бы интересно реализовать простую версию этих алгоритмов, которая послужила бы основой для нашей модели глубокого обучения.
Наивный Байес
Популярная реализация наивного байесовского метода для НЛП включает предварительную обработку текста с использованием TF-IDF, а затем запуск полиномиального наивного байесовского метода на предварительно обработанных выходных данных. Это позволяет запускать алгоритм на наиболее заметных словах в документе. Мы можем реализовать наивный Байес следующим образом:
import numpy as np from sklearn.naive_bayes import MultinomialNB from sklearn.feature_extraction.text import CountVectorizer import pandas as pd from collections import Counter from sklearn.model_selection import train_test_split from sklearn.feature_extraction.text import TfidfTransformer df = pd.read_csv('data/wine_data.csv') counter = Counter(df['variety'].tolist()) top_10_varieties = {i[0]: idx for idx, i in enumerate(counter.most_common(10))} df = df[df['variety'].map(lambda x: x in top_10_varieties)] description_list = df['description'].tolist() varietal_list = [top_10_varieties[i] for i in df['variety'].tolist()] varietal_list = np.array(varietal_list) count_vect = CountVectorizer() x_train_counts = count_vect.fit_transform(description_list) tfidf_transformer = TfidfTransformer() x_train_tfidf = tfidf_transformer.fit_transform(x_train_counts) train_x, test_x, train_y, test_y = train_test_split(x_train_tfidf, varietal_list, test_size=0.3) clf = MultinomialNB().fit(train_x, train_y) y_score = clf.predict(test_x) n_right = 0 for i in range(len(y_score)): if y_score[i] == test_y[i]: n_right += 1 print("Accuracy: %.2f%%" % ((n_right/float(len(test_y)) * 100)))
Запустите приведенный выше код, и вы должны увидеть что-то вроде следующего: 73,56%

Учитывая, что мы рассматриваем 10 классов, это довольно хороший результат.
Мы также можем использовать машину опорных векторов и посмотреть, как это будет работать. Чтобы увидеть, как это работает, просто замените определение классификатора на
clf = SVC(kernel='linear').fit(train_x, train_y)
Запустите это, и вы должны увидеть следующий вывод:
Точность: 80,66%
Тоже не слишком хлипкий.
Давайте посмотрим, сможем ли мы построить модель глубокого обучения, которая сможет превзойти или хотя бы соответствовать этим результатам. Если нам это удастся, это будет отличным признаком того, что наша модель глубокого обучения эффективна, по крайней мере, в воспроизведении результатов популярных моделей машинного обучения, основанных на опыте в предметной области.
Построение модели
Сегодня мы будем использовать Keras с Tensorflow для построения нашей модели. Keras — это библиотека Python, которая упрощает создание моделей глубокого обучения по сравнению с относительно низкоуровневым интерфейсом API Tensorflow. В дополнение к плотным слоям мы также будем использовать слои встраивания и свертки, чтобы изучить основную семантическую информацию слов и потенциальных структурных паттернов в данных.
Очистка данных
Во-первых, нам придется реструктурировать данные таким образом, чтобы наша нейронная сеть могла легко их обрабатывать и понимать. Мы можем сделать это, заменив слова уникальными числами. В сочетании с вектором встраивания мы можем представлять слова одновременно гибким и семантически чувствительным образом.
На практике мы хотим быть немного умнее в этой предварительной обработке. Имеет смысл сосредоточиться на часто используемых словах, а также отфильтровать наиболее часто используемые слова (например, the, this, a).
Мы можем реализовать эту функциональность, используя Defaultdict и NLTK. Напишите следующий код в отдельный модуль Python. Я поместил его в lib/get_top_x_words.py
.
from nltk import word_tokenize from collections import defaultdict def count_top_x_words(corpus, top_x, skip_top_n): count = defaultdict(lambda: 0) for c in corpus: for w in word_tokenize(c): count[w] += 1 count_tuples = sorted([(w, c) for w, c in count.items()], key=lambda x: x[1], reverse=True) return [i[0] for i in count_tuples[skip_top_n: skip_top_n + top_x]] def replace_top_x_words_with_vectors(corpus, top_x): topx_dict = {top_x[i]: i for i in range(len(top_x))} return [ [topx_dict[w] for w in word_tokenize(s) if w in topx_dict] for s in corpus ], topx_dict def filter_to_top_x(corpus, n_top, skip_n_top=0): top_x = count_top_x_words(corpus, n_top, skip_n_top) return replace_top_x_words_with_vectors(corpus, top_x)
Теперь мы готовы построить модель. Мы хотим, чтобы слой внедрения, сверточный слой и плотный слой использовали все функции глубокого обучения, которые могут быть полезны для нашего приложения. С Keras мы можем построить модель очень просто:
from keras.models import Sequential from keras.layers import Dense, Conv1D, Flatten from keras.layers.embeddings import Embedding from keras.preprocessing import sequence from keras.utils import to_categorical import pandas as pd from collections import Counter from sklearn.model_selection import train_test_split from lib.get_top_xwords import filter_to_top_x df = pd.read_csv('data/wine_data.csv') counter = Counter(df['variety'].tolist()) top_10_varieties = {i[0]: idx for idx, i in enumerate(counter.most_common(10))} df = df[df['variety'].map(lambda x: x in top_10_varieties)] description_list = df['description'].tolist() mapped_list, word_list = filter_to_top_x(description_list, 2500, 10) varietal_list_o = [top_10_varieties[i] for i in df['variety'].tolist()] varietal_list = to_categorical(varietal_list_o) max_review_length = 150 mapped_list = sequence.pad_sequences(mapped_list, maxlen=max_review_length) train_x, test_x, train_y, test_y = train_test_split(mapped_list, varietal_list, test_size=0.3) max_review_length = 150 embedding_vector_length = 64 model = Sequential() model.add(Embedding(2500, embedding_vector_length, input_length=max_review_length)) model.add(Conv1D(50, 5)) model.add(Flatten()) model.add(Dense(100, activation='relu')) model.add(Dense(max(varietal_list_o) + 1, activation='softmax')) model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) model.fit(train_x, train_y, epochs=3, batch_size=64) y_score = model.predict(test_x) y_score = [[1 if i == max(sc) else 0 for i in sc] for sc in y_score] n_right = 0 for i in range(len(y_score)): if all(y_score[i][j] == test_y[i][j] for j in range(len(y_score[i]))): n_right += 1 print("Accuracy: %.2f%%" % ((n_right/float(len(test_y)) * 100)))
Запустите код, и вы должны увидеть следующий вывод.
Точность: 77,20%
Напомним, что точность для наивного Байеса и SVC составила 73,56% и 80,66% соответственно. Таким образом, наша нейронная сеть очень хорошо справляется с некоторыми из наиболее распространенных методов классификации текста.
Заключение
Сегодня мы рассмотрели создание модели глубокого обучения классификации для анализа обзоров вин.
Мы обнаружили, что смогли построить модель, способную конкурировать и превосходить некоторые другие алгоритмы машинного обучения. Мы надеемся, что вы вдохновитесь использовать эту информацию для создания приложений, которые анализируют более сложные наборы данных и генерируют более сложные результаты!
Примечание. Вы можете найти код, который я использовал для этой статьи, на GitHub.
Дальнейшее чтение в блоге Toptal Engineering:
- Более глубокий смысл: тематическое моделирование в Python
- Как создать бота для анализа настроений в электронной почте: учебник по НЛП