Видео проигрыватель загружается.Воспроизвести видеоВоспроизвестиБез звукаТекущее время 0:00/Продолжительность 4:43Загрузка: 0.00%0:00Тип потока ОНЛАЙНSeek to live, currently behind liveОНЛАЙНОставшееся время -4:43 1xСкорость воспроизведения2x1.75x1.5x1.25x1x, выбрано0.75x0.5xГлавыГлавыОписанияОтключить описания, выбраноСубтитрынастройки субтитров, откроется диалог настройки субтитровСубтитры выкл., выбраноЗвуковая дорожкаPicture-in-PictureПолноэкранный режимThis is a modal window.Начало диалоговго окна. Кнопка Escape закроет или отменит окноТекстColorБелыйЧерныйКрасныйЗеленыйСинийЖелтыйПурпурныйГолубойTransparencyПрозрачностьПолупрозрачныйФонColorЧерныйБелыйКрасныйЗеленыйСинийЖелтыйПурпурныйГолубойTransparencyПрозрачностьПолупрозрачныйПрозрачныйОкноColorЧерныйБелыйКрасныйЗеленыйСинийЖелтыйПурпурныйГолубойTransparencyПрозрачныйПолупрозрачныйПрозрачностьРазмер шрифта50%75%100%125%150%175%200%300%400%Стиль края текстаНичегоПоднятыйПониженныйОдинаковыйТеньШрифтПропорциональный без засечекМоноширинный без засечекПропорциональный с засечкамиМоноширинный с засечкамиСлучайныйПисьменныйМалые прописныеСбросить сбросить все найстройки по умолчаниюГотовоЗакрыть модальное окноКонец диалогового окна.
Отлично! Теперь давайте закодируем этот алгоритм с помощью библиотек pytorch и "torchtext". Обучать сеть мы будем не для стандартной (и немного надоевшей) задачи машинного перевода, а для чуть более сложной задачи ответов на вопросы со StackOverflow. Итак, сначала импортируем все библиотеки, которые нам могут понадобиться (это "torch", "torchtext" и некоторые другие библиотеки). После этого задаём "random.seed" для воспроизводимости результатов (вот здесь). И дальше нам нужно посмотреть на формат данных и понять, каким образом мы будем их считывать. Давайте с помощью "pandas" откроем наши данные и посмотрим, что у нас в них есть. Прочитаем CSV с помощью библиотеки pandas. Он лежит в папке data. Давайте откроем файл с тестовой выборкой и посмотрим на первые три строки из неё. Мы видим, что в нашем датасете есть два поля: intent и snippet. Intent — это, собственно, вопрос со StackOverflow, а snippet — это кусочек кода, который отвечает на этот вопрос. Теперь нам нужно написать токенизаторы, которые помогут нам поделить на токены вопросы со StackOverflow и кусочек кода. Функция "tokenize_question" токенизирует наш вопрос — делаем это с помощью простой регулярки. Кроме того, мы отрезаем слишком длинные слова, которые, скорее всего, являются названиями веб-сайтов, либо слишком длинными названиями каких-то текстовых полей, или что-то подобное... Кроме того, мы будем подавать наш вопрос в обратном порядке в нашу сеть. То есть, будем начинать с последнего слова и заканчивать первым. Функция "tokenize_snippet" токенизирует кусочек кода. Работает она примерно так же, с помощью чуть другой регулярки, где мы перечисляем знаки пунктуации, которые нас могут интересовать. Отлично, что дальше? Теперь напишем обработчик входных данных с помощью библиотеки "torchtext". Torchtext позволяет сделать это достаточно быстро и с минимальным числом строк кода. Field позволяет нам определить, как должны обрабатываться данные. Напишем два разных обработчика для вопросов на естественном языке и для кода. Intent, то есть текстовый вопрос — это исходная последовательность, назовём её "src" (source), а код назовём "trg" (target). Field позволяет задать параметр tokenize, куда мы можем передать наши функции-токенизаторы отдельно для вопроса или для кода. В нашем примере, Field также добавит два дополнительных токена — это "end of sequence" и "start of sequence". Все токены будут приведены к нижнему регистру, а также, для вопроса, мы будем учитывать длину этого вопроса. Таким образом, "field" будет возвращать нам пары, а именно — вопрос и его длина. В дальнейшем это нам понадобится для обучения seq2seq модели. Далее разделим наши данные на обучающую, валидационную и тестовую выборки. Это уже сделано за нас, наша выборка поделена на 3 CSV-файла, и всё, что нам нужно — это, всего лишь, скачать эти данные с помощью, например, "data.TabularDataset". Данные мы собрали из следующего источника — он называется CoNaLa-corpus, это объединённый проект лаборатории из Carnegie Mellon и лаборатории со смешным названием STRUDEL. Этот датасет достаточно маленький, включает в себя всего 2.5 тысячи примеров. Мы поделили их следующим образом: 2000 на обучение, примерно 350 на валидацию и 500 на тест. Кроме того, данные с похожей тематикой можно найти, загуглив следующее сочетание слов: "StackOverflow question code dataset". Это датасет, намайненный автоматически со StackOverflow, с помощью "Bi-View Hierarchical Neural Network". Cтатья про "bi view hierarchical neural network" была представлена в 2018 году[1], её авторы — сотрудники университетов Огайо, Вашингтона и компании Fujitsu, и их датасет включает в себя гораздо больше данных (там есть около 150 тысяч пар вопрос и сниппет на python и около 120 тысяч пар вопросов и ответов на SQL). Для обучения мы оставили только пары из первого датасета, так как он был собран вручную, гораздо менее шумный и позволяет обучить seq2seq модели с большим качеством. Второй датасет необходимо предварительно чистить, чтобы получить гораздо более хорошее качество. Вы можете попробовать выкачать этот датасет и обучить модель с использованием большего количества данных и посмотреть на результат — посмотреть на метрики, которые вас получатся.
[1] Yao Z. et al. Staqc: A systematically mined question-code dataset from stack overflow //Proceedings of the 2018 World Wide Web Conference. – 2018. – С. 1693-1703.
К сожалению, у нас пока нет статистики ответов на данный вопрос,
но мы работаем над этим.