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

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

Этот блог посвящен Маркировке вопросов и ответов Google QUEST, который размещен на Kaggle.

В этом задании участникам предлагается построить алгоритмы прогнозирования для различных субъективных аспектов ответов на вопросы. Пары вопрос-ответ были собраны почти с 70 различных веб-сайтов в духе «здравого смысла».

Данные предоставлены kaggle для этой задачи

Для этой задачи ниже были предоставлены данные.

· train.csv — данные обучения (целевые метки — последние 30 столбцов)

Этот файл содержит данные для обучения модели.

Форма обучающих данных (6079,41).

Ниже приведены столбцы в этом файле:

Функции: 'qa_id', 'question_title', 'question_body', 'question_user_name', 'question_user_page', 'answer', 'answer_user_name', 'answer_user_page', 'url', 'category ', 'хост'

Ярлыки классов:'question_asker_intent_understanding', 'question_body_critical', 'question_conversational', 'question_expect_short_answer', 'question_fact_seeking', 'question_has_commonly_accepted_answer', 'question_interestingness_others', 'question_interestingness_self', 'question',multi_intention 'question_opinion_seeking', 'question_type_choice', 'question_type_compare', 'question_type_consequence', 'question_type_definition', 'question_type_entity', 'question_type_instructions', 'question_type_procedure', 'question_type_reason_explanation', 'question_type_spelling', 'question_well_written', 'answer_helpful', «answer_level_of_information ', 'answer_plausible', 'answer_relevance', 'answer_satisfaction', 'answer_type_instructions', 'answer_type_procedure', 'answer_type_reason_explanation', 'answer_well_writing'

Для каждой из приведенных выше меток класса необходимо предсказать непрерывное значение в диапазоне [0,1] для каждого из столбцов.

· test.csv — тестовый набор (вы должны предсказать 30 меток для каждой строки тестового набора)

Это тестовый файл, содержащий данные о том, какие прогнозы необходимо отправить в kaggle для оценки.

Какие данные я использую?

Я бы использовал следующие столбцы — question_title, question_body, answer, category, host для обучения модели.

Решение победителя

Победитель этого испытания использовал 4 предварительно обученные модели — 2 BERT, одну RoBERTa и одну BART и набрал метрику (коэффициент корреляции Спирмена) 0,4310.

Мое решение

Я создал модель CNN, имеющую 2 параллельные операции свертки, одну для текстовых данных, а другую для комбинированных категориальных и числовых данных. Вывод этих двух сверток передается на 2 разных плотных слоя. Затем выходные данные этих двух плотных слоев объединяются для прохождения через финальный плотный слой с 30 сигмовидными единицами активации, чтобы получить окончательный результат.

Ниже приведены этапы процесса, которым следовали в этом тематическом исследовании.

· Исследовательский анализ данных

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

· Разработка функций

· Создание модели

· Анализ ошибок

· Улучшение модели

АНАЛИЗ ИССЛЕДОВАТЕЛЬСКИХ ДАННЫХ

Давайте пройдемся по части анализа данных.

Следующий фрагмент показывает используемые библиотеки.

Первая проверка на пропущенные значения

Таким образом, нет пропущенного значения

Теперь приступим к анализу данных.

В приведенном выше Wordcloud мы видим, что наиболее часто встречающимися словами в заголовке вопроса являются using, file, use, value, user, one, time, change, window, function, data.

Наиболее часто встречающиеся слова в теле вопроса: gt, lt, one, will, using, use, example,know, question, new, work, value, problem

Некоторые из наиболее часто встречающихся слов в теле вопроса и заголовке вместе взятые: gt, lt, one, will, use, file, want, example, know, question, using, new, work, problem

Из вышеприведенного Wordcloud можно сказать, что в заголовке вопроса чаще всего встречаются слова use, one, will, need, gt, lt, using, file, time, gt, lt, way, make, example, see.

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

Из 77 578 слов в заголовке вопроса 25 859 слов, т. е. почти 33 %, совпадают с ответом.

Названия ответов и вопросов также хорошо перекрываются. 90 % слов в заголовке вопроса присутствуют в ответах.

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

Максимальное количество вопросов относится к категории TECHNOLOGY, что составляет 40,2% от общего числа вопросов. 20,6% от общего числа вопросов составляют STACKOVERFLOW.15,6% вопросов относятся к категории CULTURE.SCIENCE, а LIFE_ARTS составляют минимум 11,7% каждый.

Теперь, чтобы выполнить анализ HOST на , мне нужно предварительно обработать его и извлечь только уникальное имя хоста. напр. «photo.stackexchange.com» становится «stackexchange»

На приведенном выше графике показано, что stackexchange разместил максимальное количество вопросов с 68,6% от общего числа вопросов. Хост со вторым по величине количеством вопросов — это stackoverflow. Другие хосты: superuser с 3,7%, serverfault с 3,5%, askubuntu с 2,1% и mathoverflow 1,3%.

Большинство вопросов категории life_arts дают хорошее представление о намерениях спрашивающего с оценкой от 0,8 до 1.

Вопросы категории culture также имеют те же баллы, что и life_arts.

Категории science, stackoverflow, technology имеют 75% вопросов с оценкой намерения задающего от 0,78 до 1, но все еще есть 25% вопросов с оценкой от 0,3 до 0,75.

Судя по приведенному выше графику, можно сказать, что в основном вопросы в категориях culture, stackoverflow, technology предполагают короткие ответы.

Кажется, вопросы из категории 'life_arts более интересны другим, чем вопросы из других категорий.

Категории life_arts и culture имеют более высокий балл по показателю question_interestingness_self, чем другие категории.

stackoverflow имеют самые низкие баллы.

life_arts и culture содержат более хорошо написанные вопросы, чем другие категории. science также имеет хорошо написанные вопросы по сравнению с stackoverflow и technology

Ответы всех категорий написаны хорошо, за исключением нескольких отклонений со значением менее 0,5. stackoverflow некоторые ответы имеют более низкий балл по сравнению с другими

Таким образом, все категории имеют более или менее одинаковые оценки удовлетворенности ответами.

Я создал приведенную ниже функцию для графика распределения меток классов.

Из всех сюжетов категорий у cultural и life_arts больше вопросов для разговора, чем у других категорий.

Ярлык класса question_interestingness_self имеет более высокий балл по категориям life_arts и cultural по большинству вопросов.

Категории stackoverflow и technology имеют меньше ответов с объяснением причин, тогда как science содержат больше вопросов по сравнению с другими категориями с ответами с объяснением причин.

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

ПРЕДВАРИТЕЛЬНАЯ ОБРАБОТКА ДАННЫХ

Давайте сначала поговорим о предварительной обработке текстовых данных —question_title, question_body, answer

Я пытался удалить стоп-слова, заменить такие слова, как "не будет", на"не будет","может" t”to“cannot”,удаление ссылок http из текста, нообнаружил, что результат был не так хорош, как без предварительной обработки текста, поэтому я оставил все вопросы и ответы как есть, чтобы сохранить все значения и чувства сохраненными.

Я уже предварительно обработал host выше для выполнения EDA, поэтому теперь я просто преобразую его в нижний регистр.

Приведенный выше код преобразует "category" и "host" в нижний регистр и удаляет все начальные и/или конечные пробелы.

РАЗРАБОТКА ОСОБЕННОСТЕЙ

Я создал 15 новых функций для обучения модели.

Ниже код показывает создание 3 функций —

1. q_title_length (length of question title, 2. q_body_length (length of question body, 3. answer_length (length of answer)

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

Следующий код генерирует четыре функции тональности из заголовка вопроса.

Следующий код генерирует четыре функции тональности из тела вопроса.

Следующий код генерирует четыре функции тональности из ответов.

Итак, наконец, я создал 15 новых функций — длину заголовка вопроса, длину тела вопроса, длину ответов и 4 сентиментальных функции для каждого из заголовка вопроса, тела и ответа.

Чтобы узнать о новых функциях EDA, обратитесь к моей учетной записи github.

КОДИРОВАНИЕ ДАННЫХ

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

Категориальное кодирование данных:

Существует две категориальные функции — "хост" и "категория".

Я использовал CountVectorizer библиотеки sklearn для кодирования категориальных данных в представление с горячим кодированием. Ниже функция кодирует входные данные в горячее кодирование и возвращает закодированный вывод.

Эта функция используется при обучении модели. Он берет кадр данных Train and Validation вместе со столбцом, который необходимо закодировать, и возвращает закодированный вывод по CountVectorizer, который соответствует тем же входным данным, чтобы его можно было использовать для кодирования будущих невидимых данных.

Кодировка текстовых данных:

Существует поворот в кодировании текстовых данных. Вместо широко используемых методов, таких как Bag of Words, TF-IDF, Word2Vec, я использовал предварительно обученную модель BERT для получения векторного представления каждого вопроса и ответа.

BERT — Bidirectional Encoder Representations from Transformers,созданный и опубликованный в 2018 году,является методикой предварительного обучения НЛП (обработка естественного языка), разработанной Google . BERT использует Transformer, механизм внимания, который изучает контекстуальные отношения между словами (или подсловами) в тексте.

BERT обеспечивает плотные векторные представления для естественного языка с помощью глубокой предварительно обученной нейронной сети с архитектурой Transformer. Модель BERT, которую я использовал в этом примере, была предварительно обучена для английского языка в Википедии и BooksCorpus с использованием кода, опубликованного на GitHub. Входные данные были без регистра, что означает, что текст был переведен в нижний регистр до токенизации в части слов, а все маркеры акцента были удалены.

Чтобы получить закодированное текстовое представление из BERT, нам сначала нужно закодировать необработанные текстовые данные в способ, понятный BERT. Входное представление, используемое BERT, может представлять одно текстовое предложение, а также пару предложений (например, вопрос, ответ) в одной последовательности токенов.

Поскольку этот блог ориентирован на Google-Quest-Challenge, я бы не стал углубляться в BERT, но вы можете узнать больше об этом в Google.

Для BERT каждое вложение ввода представляет собой комбинацию трех вложений:

  • Встраивание позиций: BERT изучает и использует встраивания позиций для выражения положения слов в предложении. Они добавлены, чтобы преодолеть ограничение Transformer, которое, в отличие от RNN, не может собирать информацию о «последовательности» или «порядке».
  • Встраивание сегментов: BERT также может использовать пары предложений в качестве входных данных для задач (вопрос-ответ). Вот почему он изучает уникальное вложение для первого и второго предложений, чтобы помочь модели различать их. В приведенном выше примере все токены, помеченные как EA, принадлежат предложению A (и аналогично для EB).
  • Внедрения токенов: это вложения, полученные для конкретного токена из словаря токенов WordPiece.

Я создал функции ниже, чтобы получить текстовые данные, закодированные во входное представление BERT.

Функция get_encoded_bert_inputs принимает фрейм данных и максимальную длину, которую необходимо сохранить для вопроса/ответа. Сначала он объединяет question_title и question_body каждой точки данных, а затем кодирует их с помощью функции encode_text, которая имеет предварительно обученный токенизатор BERT для кодирования текстовых данных. Эта функция выводит внедрение позиции, внедрение сегмента и встраивание токена, как упоминалось выше.

Мы вводим эти закодированные данные в предварительно обученную модель BERT, чтобы получить закодированное текстовое представление для ввода в нашу окончательную модель CNN. Функция ниже выполняет эту операцию кодирования.

Мы получаем два разных вывода от энкодеров BERT. Один выходной сигнал ('pool' в приведенной выше функции) представляет все предложение в виде N”-мерного числового вектора (в нашем случае N=768, так как это базовая модель), а другой вывод (как'seq'в приведенной выше функции) представляет каждое слово входного предложения как N-мерный числовой вектор.

Я использовал вывод представления каждого слова и суммировал их, чтобы сделать окончательный вектор размером 768 для каждого вопроса (question_title + question_body), а также для ответа.

Затем я объединил эти 768-мерные вектора для вопросов и ответов каждой точки данных, чтобы сделать окончательное текстовое векторное представление 1536-мерного (786 для вопроса + 768 для ответа).

Примечание. Я мог бы сразу ввести все закодированные текстовые данные (встраивание позиции, встраивание сегмента, встраивание токена) в BERT, но поскольку у меня 8 ГБ ОЗУ, этого недостаточно для выполнения этой операции за один раз, поэтому Я написал приведенную выше функцию get_text_vector для одновременной обработки каждой точки данных.

Окончательные закодированные данные для ввода в модель:

  • Текстовые данные — вектор размерности 768 для (question_title + question_body), вектор размерности 768 для ответа.
  • Категорические данные — одна категория и хост с горячим кодированием.
  • Числовые данные — длина question_title, длина question_body, длина ответа, настроения (отрицательные, нейтральные, положительные, составные) для question_title, question_body и ответа.

МОДЕЛЬ

Я пробовал несколько моделей — CNN, LSTM, ALBERT+CNN, BERT+CNN, но наиболее эффективной была BERT+CNN. BERT просто использовался для получения векторного представления текстовых данных.

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

Давайте пройдемся по коду модели CNN.

Вышеуказанная функция определяет архитектуру модели CNN и возвращает скомпилированную модель.

Модель принимает два входа — один вход для закодированных текстовых данных, а другой — для закодированных категориальных + числовых данных. Над каждыми входными данными выполняются отдельные операции свертки, затем выходные данные каждого из них передаются на разные плотные слои, а выходные данные этих двух разных плотных слоев объединяются для перехода к другому плотному слою с 30 сигмовидными единицами активации (поскольку у нас есть 30 классов). метки), чтобы получить окончательный результат.

Приведенный выше код создает экземпляр модели CNN (как определено в функции cnn_model выше) и печатает сводку модели (выходная форма, параметры).

Всего у модели 4 700 446 обучаемых параметров.

Ниже код для обучения модели.

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

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

Показатель корреляции Спирмена для обучающих данных – 0,407, а для невидимых проверочных данных – 0,361

Коды всех опробованных мной моделей можно найти в моем репозитории github, куда я загрузил все коды.

АНАЛИЗ ОШИБОК

Я выполнил некоторый анализ ошибок на модели CNN, которая использовала среднее значение Word2Vec для кодирования текстовых данных. Подробности анализа ошибок в этой модели см. в моем репозитории Github. Я не добавляю здесь много подробностей, потому что я не освещал детали этой модели в этом блоге, чтобы сосредоточить внимание на лучшей модели (BERT + CNN) и не слишком долго читать.

Здесь я бы просто добавил значения ошибок (средняя абсолютная ошибка), которые я получил для этой модели.

Вышеприведенный код дает значения средней абсолютной ошибки для каждой метки класса.

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

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

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

Из приведенных выше оценок видно, что BERT+CNN работал лучше всего.

Теперь, когда мы обучили модель, давайте перейдем к коду окончательной сквозной функции, чтобы предсказать будущие невидимые данные.

КОНЕЧНАЯ ФУНКЦИЯ ДЛЯ ПРОГНОЗИРОВАНИЯ БУДУЩИХ НЕВИДИМЫХ ДАННЫХ

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

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

Я попробовал выше функцию predict для данных поезда.

И вы можете увидеть оценку = 0,4021, что почти равно 0,4076, оценку, которую я получил на наборе данных поезда во время обучения.

Ниже приведен скриншот моей оценки Kaggle по тестовым данным, предоставленным kaggle.

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

КРЕДИТЫ и ССЫЛКИ:

  1. https://www.appliedaicourse.com/
  2. https://www.kaggle.com/abhinand05/bert-for-humans-tutorial-baseline-version-2
  3. https://www.kaggle.com/vinaydoshi/tfbert-ensemble-preprocess-with-2-hidden-layers
  4. https://tfhub.dev/tensorflow/bert_en_uncased_L-12_H-768_A-12/2

Весь код можно найти в моем репозитории GITHUB.

Свяжитесь со мной по LINKEDIn