код русского языка для бота
Научи бота! — разметка эмоций и семантики русского языка
Со всех сторон на нас сыпятся перспективы светлого роботического будущего. Или не очень светлого, в духе Матрицы и Терминатора. В самом деле — машины уже уверено справляются с переводами, не хуже и намного быстрее людей распознают лица и предметы окружающего мира, учатся понимать и синтезировать речь. Круто? Не то слово!
Но дело серьёзно осложняется тем, что компьютеры так и научились ориентироваться в нашем мире. Всё, что они так хорошо делают, они делают по аналогии, не вдаваясь в суть и не нагружая себя смыслом происходящего. Может оно и к лучшему — дольше проживём, не будучи порабощены бездушным племенем машин.
Но любопытство подталкивает к рискованным шагам, а именно к попыткам познакомить компьютер с нашим миром, в том числе и с внутренним — чувствами, эмоциями и переживаниями.
Как мы планируем прокачать сознание машин, научить их эмоциям, чувствам и оценочным суждениям, а также где вы можете свободно скачать размеченные
данные — читайте в статье.
Не хочу читать, покажите результат!
Можно сразу попробовать обучить бота по ссылке: Научи бота!
Если понравится отвечать — создайте свою Карту и результат будет запоминаться.
Ограничения дистрибутивной семантики
В чём, собственно, проблема понимания компьютером текстов, ведь машина может изучить всё текстовое культурное наследие и научиться всему оттуда? Лучше слов расскажет результат работы word2vec.
женщина 0.650
замужний 0.594
немолодой 0.542
антимужчина 0.538
…
беременный 0.519
нерожавший 0.516
девушка 0.498
.
восхищение 0.715
…
негодование 0.609
ярость 0.597
ужас 0.586
отчаяние 0.584
…
трепет 0.531
смятение 0.523
недоумение 0.522
…
бешенство 0.472
.
…
технология 0.569
искусство 0.451
мастерство 0.410
…
самолётостроение 0.393
индустрия 0.392
медицина 0.379
ремесло 0.375
…
промышленность 0.370
…
знание 0.360
наука 0.358
.
Собственно эти примеры ярко показывают, сколько информации даёт контекст. Достаточно много, но явно недостаточно, чтобы разводить антонимы, часть-целое, общее-частное, делать различие между вертикальными и горизонтальными связями.
Поэтому, вполне разумно, что многие исследователи наряду с подходами дистрибутивной семантики (читай: word2vec) используют тезаурусы. Для английского языка таким ресурсом является WordNet, для русского — РуТез, Викисловарь.
Очевидное не так очевидно
Каждый исследователь, решившийся на дерзкую попытку объяснить машине смыслы, рано или поздно столкнётся с тем, что самые казалось бы тривиальные вещи компьютеру совершенно неочевидны. Более того, даже в детских книжках о них не написано ни слова. Мир, в целом ряде аспектов, познаётся нами через наши органы восприятия — посредством зрения, слуха, обоняния, осязания, вкуса и других.
Затем мы уже коммуницируем друг другу предельно сжатый и краткий контекст ситуации, который разворачивается в отдельно взятой голове в детальную картину. Причём у каждого человека ситуация раскрывается по-разному, в зависимости от личного опыта, культурного фона, особенностей характера и мировосприятия.
Эмоции, чувства, переживания
Слова и словосочетания несут в себе гораздо больше смысла, чем зафиксировано в толковых словарях. В первую очередь это связано с такими зыбкими и слабоосязаемыми свойствами, как оценка и сопутствующая эмоциональная окраска. Например, словосочетание тяжкие муки несёт в себе сильную отрицательную эмоцию. А словосочетание бурная радость — сильную положительную. Не подарок — это что-то отрицательное, но не слишком. А, к примеру, виртуоз имеет довольно сильную положительную оценку.
Сложность с фиксацией таких тонких характеристик слов в том, что они предельно субъективны и плохо формализуемы. Скажем, слово стратегия — оно положительное или нейтральное? Согласиться можно лишь с тем, что не отрицательное.
Тем не менее эмоциональные и оценочные атрибуты являются неотъемлемой частью языковых единиц и играют довольно важную роль в человеческой коммуникации. Следовательно, если мы хотим сделать машину более человечной и приятной в общении, она тоже должна проникнуться этими тонкими материями.
Что делать?
Вручную создать такого рода словарь было бы крайне трудоёмко, ведь размечать хочется не только слова, но и словосочетания. К тому же все оценки будут сильно привязаны к субъективному мнению исследователя.
Хорошие новости! мы живём в 2017-ом году и нам доступны такие замечательные технологии, как Интернет и краудсорсинг. Последний позволяет одновременно справляться как с проблемой трудоёмкости, так и c субъективностью оценок. Конечно это рождает эффект «среднего по больнице», но для первого приближения мы позволим себе закрыть глаза на неровности такого рода.
Научи бота! — разметка эмоций и семантики русского языка
Идея реализована на языковой платформе Карта слов. Работа будет вестись по нескольким направлениям:
Как принять участие?
Важная цель нашей инициативы — восполнение недостающих лингвистических ресурсов для русского языка, открытых для использования исследователями, учёными-лингвистами и инженерами-практиками. Мы рассчитываем, что основываясь на данных разметки будут проведены интересные исследования, написаны научные статьи, статьи на Хабре, появятся инженерные продукты и открытые технологии.
Вы можете помочь проекту следующими способами:
Открытые данные
Агрегированные результаты разметки будут открыты для скачивания и доступны по лицензии CC BY-NC 4.0.
Получить и опубликовать первые результаты мы рассчитываем к середине/концу июля — всё будет зависеть от активности отвечающих. Чтобы ничего не пропустить, ставьте звёздочки и подписывайтесь на наш гитхаб:
Где деньги, Зин?
Здорово попробовать совместить в одном проекте краудсорсинг и краудфандинг, что мы и сделали, запустив кампанию по сбору средств на Планете.ру:
Важно. Проект мы уже делаем и доведём до результата своими силами и имеющимися ресурсами. Собранные данные, как и обещали, будут открытыми и доступными всем желающим. Вопрос лишь в сроках и объёме разметки. Сейчас мы рассчитываем получить базовый результат (10.000 самых частотных слов) за три месяца, разметка полного объёма займёт около двух лет.
Дополнительные ресурсы помогут существенно ускорить получение результата. Нам нужно помогать разработчикам, задействованным в создании и совершенствовании системы разметки, добавлять новые семантические категории и проводить исследовательскую работу. Также средства необходимы для продвижения проекта и проведения конкурсов.
Пожертвовать на кампанию можно любое количество денег — при этом вы будете знать, что в общем успехе есть и ваш вклад, а каждый вложенный рубль будет потрачен на крутое и полезное дело.
Не забывайте, что вы можете помочь инициативе и без денег. Ставьте лайки и рассказывайте о проекте в социальных сетях — это очень простой, совершенно бесплатный, но очень действенный способ продвижения.
Выбор всегда за вами.
Корпорейт спонсоршип
Вы представляете устоявшийся бизнес и вам интересно развитие открытых лингвистических данных в России? Становитесь корпоративным спонсором проекта! Вы получаете вечную графическую ссылку со страницы проекта, дополнительную рекламу на многотысячную аудиторию и неземной респект от сообщества.
Каждый вложенный рубль мы потратим с невероятной эффективностью, а за несколько месячных окладов одного программиста в крупной компании сделаем весь проект, результатами которого будут пользоваться тысячи исследователей, учёных и инженеров.
Коммерческое использование
По вопросам коммерческого использования или бизнес-специфичной разметки пишите на kartaslov@mail.ru или в ЛС автору статьи.
Благодарности
Большую благодарность хочется выразить организаторам и участникам Диалога-2017 — 23-ей международной конференции по компьютерной лингвистике и интеллектуальным технологиям.
Именно в кулуарных обсуждениях мероприятия стала понятна необходимость такого рода разметки, а также собрана группа единомышленников для обсуждения экспериментальной разметки отношений по теории „Смысл ⇔ Текст“. Хочется надеяться, что в следующем году, основываясь на собранных данных, можно будет запустить новое интересное соревнование в рамках Dialogue Evaluation.
Инструкция: Как создавать ботов в Telegram
24 июня разработчики Telegram открыли платформу для создания ботов. Новость кого-то обошла стороной Хабр, однако многие уже начали разрабатывать викторины. При этом мало где указаны хоть какие-то примеры работающих ботов.
Прежде всего, бот для Telegram — это по-прежнему приложение, запущенное на вашей стороне и осуществляющее запросы к Telegram Bot API. Причем API довольное простое — бот обращается на определенный URL с параметрами, а Telegram отвечает JSON объектом.
Рассмотрим API на примере создания тривиального бота:
1. Регистрация
Прежде чем начинать разработку, бота необходимо зарегистрировать и получить его уникальный id, являющийся одновременно и токеном. Для этого в Telegram существует специальный бот — @BotFather.
Пишем ему /start и получаем список всех его команд.
Первая и главная — /newbot — отправляем ему и бот просит придумать имя нашему новому боту. Единственное ограничение на имя — оно должно оканчиваться на «bot». В случае успеха BotFather возвращает токен бота и ссылку для быстрого добавления бота в контакты, иначе придется поломать голову над именем.
Для начала работы этого уже достаточно. Особо педантичные могут уже здесь присвоить боту аватар, описание и приветственное сообщение.
Не забудьте проверить полученный токен с помощью ссылки /getMe»>api.telegram.org/bot /getMe, говорят, не всегда работает с первого раза.
2. Программирование
Создавать бота буду на Python3, однако благодаря адекватности этого языка алгоритмы легко переносятся на любой другой.
Telegram позволяет не делать выгрузку сообщений вручную, а поставить webHook, и тогда они сами будут присылать каждое сообщение. Для Python, чтобы не заморачиваться с cgi и потоками, удобно использовать какой-нибудь реактор, поэтому я для реализации выбрал tornado.web. (для GAE удобно использовать связку Python2+Flask)
Здесь мы при запуске бота устанавливаем вебхук на наш адрес и отлавливаем сигнал выхода, чтобы вернуть поведение с ручной выгрузкой событий.
Приложение торнадо для обработки запросов принимает класс tornado.web.RequestHandler, в котором и будет логика бота.
Здесь CMD — словарь доступных команд, а send_reply — функция отправки ответа, которая на вход принимает уже сформированный объект Message.
Собственно, её код довольно прост:
Теперь, когда вся логика бота описана можно начать придумывать ему команды.
3. Команды
Перво-наперво, необходимо соблюсти соглашение Telegram и научить бота двум командам: /start и /help:
Структура message[‘from’] — это объект типа User, она предоставляет боту информацию как id пользователя, так и его имя. Для ответов же полезнее использовать message[‘chat’][‘id’] — в случае личного общения там будет User, а в случае чата — id чата. В противном случае можно получить ситуацию, когда пользователь пишет в чат, а бот отвечает в личку.
Команда /start без параметров предназначена для вывода информации о боте, а с параметрами — для идентификации. Полезно её использовать для действий, требующих авторизации.
После этого можно добавить какую-нибудь свою команду, например, /base64:
Для пользователей мобильного Telegram, будет полезно сказать @BotFather, какие команды принимает наш бот:
I: /setcommands
BotFather : Choose a bot to change the list of commands.
I: @******_bot
BotFather: OK. Send me a list of commands for your bot. Please use this format:
C таким описанием, если пользователь наберет /, Telegram услужливо покажет список всех доступных команд.
4. Свобода
Как можно было заметить, Telegram присылает сообщение целиком, а не разбитое, и ограничение на то, что команды начинаются со слеша — только для удобства мобильных пользователей. Благодаря этому можно научить бота немного говорить по-человечески.
UPD: Как верно подсказали, такое пройдет только при личном общении. В чатах боту доставляются только сообщения, начинающиеся с команды (/ ) (https://core.telegram.org/bots#privacy-mode)
Чтобы бот получал все сообщения в группах пишем @BotFather команду /setprivacy и выключаем приватность.
Для начала в Handler добавляем обработчик:
А потом в список команд добавляем псевдо-речь:
Здесь эмпирическая константа 75 относительно неплохо отражает вероятность того, что пользователь всё-таки хотел сказать. А format_map — удобна для одинакового описания строк как требующих подстановки, так и без нее. Теперь бот будет отвечать на приветствия и иногда даже обращаться по имени.
5. Не текст.
Боты, как и любой нормальный пользователь Telegram, могут не только писать сообщения, но и делиться картинками, музыкой, стикерами.
Для примера расширим словарь RESPONSES:
И будем отлавливать текст :
Видно, что теперь структура Message уже не содержит текст, поэтому необходимо модифицировать send_reply:
И все, теперь бот будет время от времени присылать стикер вместо времени:
6. Возможности
Благодаря удобству API и быстрому старту боты Telegram могут стать хорошей платформой для автоматизации своих действий, настройки уведомлений, создания викторин и task-based соревнований (CTF, DozoR и прочие).
Вспоминая статью про умный дом, могу сказать, что теперь извращений меньше, а работа прозрачнее.
7. Ограничения
К сожалению, на данный момент существует ограничение на использование webHook — он работает только по https и только с валидным сертификатом, что, например для меня пока критично за счет отсутствия поддержки сертифицирующими центрами динамических днс.
К счастью, Telegram также умеет работать и по ручному обновлению, поэтому не меняя кода можно создать еще одну службу Puller, которая будет выкачивать их и слать на локальный адрес:
P.S. По пункту 7 нашел удобное решение — размещение бота не у себя, а на heroku, благо все имена вида *.herokuapp.com защищены их собственным сертификатом.
UPD: Telegram улучшили Бот Апи, из-за чего, теперь не обязательно иметь отдельную функцию для отправки сообщений при установленном вебхуке, а в ответ на POST запрос можно отвечать тем же сформированным JSON с ответным сообщением, где одно из полей устанавливается как ч ‘method’: ‘sendMessage’ (или любой другой метод, используемый ботом).
Создание Discord-бота, используя библиотеку discord.js | Часть №1
Введение
В этой статье я подробно расскажу о том, как работать с библиотекой discord.js, создать своего Discord-бота, а также покажу несколько интересных и полезных команд.
Сразу хочу отметить, что я планирую сделать ряд подобных статей, начиная с простых команд, заканчивая музыкой, системой экономики и распознаванием голоса ботом.
Начало работы
Если вы уже знакомы с приведёнными ниже материалами, — смело можете пролистать этот раздел.
Для начала работы с кодом нам нужно установить среду разработки, это может быть:
Среда разработки выбирается по удобству использования и практичности, она у вас может быть любая, но мы рассмотрим её на примере Visual Studio Code, так как она является одной из самых приемлемых для новичков, а также для опытных программистов.
Для установки переходим по этой ссылке.
Выбираем свою операционную систему и запускаем скачивание.
Для создания бота мы используем среду выполнения node.js. Для её установки нам необходимо перейти на этот сайт.
На данный момент нас интересует версия долгосрочной поддержки (LTS), скачиваем её.
В Visual Studio Code присутствует возможность устанавливать расширения.
Для этого, кликните по отмеченной ниже иконке.
В открывшемся окне вписываем название название/идентификатор нужного нам расширения, после чего устанавливаем его.
Из полезных расширений могу отметить:
Создание бота
Теперь, когда вы установили все нужные компоненты, мы можем приступить к созданию самого бота.
Здесь всё просто. Переходим на портал разработчиков и нажимаем на кнопку с надписью «New Application» — она находится в правом верхнем углу.
В открывшемся окне вписываем имя бота, после чего, нажимаем на кнопку с надписью «Create».
На этой странице мы можем изменить имя бота, загрузить для него иконку, заполнить описание.
Теперь наша задача — воплотить бота в жизнь. Для этого переходим во вкладку «Bot».
Нажимаем на кнопку с надписью «Add Bot» и воплощаем бота в жизнь.
Поздравляю! Вы создали аккаунт для вашего бота. Теперь у него есть тег, токен, ник и иконка.
Подготовка к написанию кода
После создания аккаунта для бота, мы должны установить нужные пакеты и модули, чтобы в дальнейшем он корректно работал.
Первым делом создаём папку, после чего открываем её в VS Code (Файл > Открыть папку) / (Ctrl + K Ctrl + O)
Далее нам нужно открыть терминал (Терминал > Создать терминал) / (Ctrl + Shift + `)
Теперь мы должны создать файл с неким «описанием» нашего бота, сделаем это через терминал.
Вписываем данную строку в терминал и нажимаем Enter:
После каждой появившейся строки нажимаем Enter или вписываем свои значения.
Значения в этом файле можно будет изменить в любой момент.
Далее, мы должны поочерёдно вводить в терминал эти строки:
«Install» также можно сокращать в «I», но необязательно.
Итого, если вы следовали инструкциям и всё сделали правильно, в вашей папке должны были появиться 3 объекта:
Написание кода
Для того, чтобы наш бот появился в сети и мог реагировать на команды, нам нужно написать для него код.
Существует множество вариантов для его написания: используя один файл, два, несколько, и т.д
Мы рассмотрим вариант с двумя файлами, так как его использовать очень легко и удобно, но у каждого варианта есть свои недостатки — например, у этого недостатком является сложность в написании начального кода.
Но не волнуйтесь, весь код вам писать не придётся.
Для начала, нам нужно где-то хранить основные параметры и информацию о боте.
Мы можем сделать это двумя способами:
Разберём хранение параметров в отдельном файле.
Итак, создаем файл config.json
Вставляем в него следующий код:
* Для получения токена зайдите на портал разработчиков, перейдите во вкладку «Bot» и скопируйте его.
* Самым распространённым среди разработчиков префиксом является !
Далее нам нужно создать файл bot.js и вставить в него данный код:
Теперь создаём файл comms.js, в нём будут сами команды.
В нём должен быть следующий код:
Чтобы добавить больше команд — просто объявляйте больше функций и добавляйте их в список, например:
И вот, мы вышли на финишную прямую!
Осталось всего ничего — запустить бота.
Для этого открываем терминал и вставляем в него следующую строку:
Готово! Бот запущен и вы можете им пользоваться, ура!
Чтобы пригласить бота на свой сервер, воспользуемся нам уже известным порталом разработчиков.
Перейдём во вкладку OAuth2, пролистаем чуть ниже, выберем «Bot» и отметим нужные боту привилегии.
Теперь осталось скопировать ссылку-приглашение и добавить бота на свой сервер.
Существует два способа:
Для этого, сначала мы должны скопировать ссылку-приглашение.
После чего перейти в файл bot.js и вставить данную строчку кода сюда:
Итоговый код должен быть таким:
Чтобы указать несколько привилегий, мы должны перечислить их в квадратных скобках, через запятую:
* Все привилегии указываются заглавными буквами
Список доступных привилегий:
ADMINISTRATOR
CREATE_INSTANT_INVITE
KICK_MEMBERS
BAN_MEMBERS
MANAGE_CHANNELS
MANAGE_GUILD
ADD_REACTIONS
VIEW_AUDIT_LOG
PRIORITY_SPEAKER
STREAM
VIEW_CHANNEL
SEND_MESSAGES
SEND_TTS_MESSAGES
MANAGE_MESSAGES
EMBED_LINKS
ATTACH_FILES
READ_MESSAGE_HISTORY
MENTION_EVERYONE
USE_EXTERNAL_EMOJIS
VIEW_GUILD_INSIGHTS
CONNECT
SPEAK
MUTE_MEMBERS
DEAFEN_MEMBERS
MOVE_MEMBERS
USE_VAD
CHANGE_NICKNAME
MANAGE_NICKNAMES
MANAGE_ROLES
MANAGE_WEBHOOKS
MANAGE_EMOJIS
Я не советую вам из привилегий выбирать только ADMINISTRATOR, поэтому лучше указать только те привилегии, которые бот действительно использует для корректной работы
Полезные и интересные команды
В предыдущем разделе я показал вам, как запустить бота и как писать для него команды.
Теперь я хочу поделиться с вами несколькими своими командами.
Не стоит пугаться большого кода, здесь всё предельно просто.
Заключение
Вот и подошла к концу первая часть обучения, как вы могли заметить, создать бота, используя библиотеку discord.js очень просто.
Итого, из этой статьи мы выяснили:
Надеюсь, что вам понравилась моя статья и вы узнали из неё что-то новое.
Создание простого разговорного чатбота в python
Как вы думаете, сложно ли написать на Python собственного чатбота, способного поддержать беседу? Оказалось, очень легко, если найти хороший набор данных. Причём это можно сделать даже без нейросетей, хотя немного математической магии всё-таки понадобится.
Идти будем маленькими шагами: сначала вспомним, как загружать данные в Python, затем научимся считать слова, постепенно подключим линейную алгебру и теорвер, и под конец сделаем из получившегося болтательного алгоритма бота для Телеграм.
Этот туториал подойдёт тем, кто уже немножко трогал пальцем Python, но не особо знаком с машинным обучением. Я намеренно не пользовался никакими nlp-шными библиотеками, чтобы показать, что нечто работающее можно собрать и на голом sklearn.
Поиск ответа в диалоговом датасете
Год назад меня попросили показать ребятам, которые прежде не занимались анализом данных, какое-нибудь вдохновляющее приложение машинного обучения, которое можно собрать самостоятельно. Я попробовал собрать вместе с ними бота-болталку, и у нас это действительно получилось за один вечер. Процесс и результат нам понравились, и написал об этом в своем блоге. А теперь подумал, что и Хабру будет интересно.
Итак, начинаем. Наша задача — сделать алгоритм, который на любую фразу будет давать уместный ответ. Например, на «как дела?» отвечать «отлично, а у тебя?». Самый простой способ добиться этого — найти готовую базу вопросов и ответов. Например, взять субтитры из большого количества кинофильмов.
Я, впрочем, поступлю ещё более по-читерски, и возьму данные из соревнования Яндекс.Алгоритм 2018 — это те же диалоги из фильмов, для которых работники Толоки разметили хорошие и неплохие продолжения. Яндекс собирал эти данные, чтобы обучать Алису (статьи о её кишках 1, 2, 3). Собственно, Алисой я и был вдохновлен, когда придумывал этого бота. В таблице от Яндекса даны три последних фразы и ответ на них (reply), но мы будем пользоваться только самой последней из них (context_0).
Векторизация текстов
Теперь говорим о том, как превратить тексты в числовые векторы, чтобы осуществлять по ним приближённый поиск.
Мы уже познакомились с библиотекой pandas в Python — она позволяет загружать таблицы, осуществлять поиск в них, и т.п. Теперь затронем библиотеку scikit-learn (sklearn), которая позволяет более хитрые манипуляции с данными — то, что называется машинным обучением. Это значит, что любому алгоритму сперва нужно показать данные (fit), чтобы он узнал о них что-то важное. В результате алгоритм «научится» делать с этими данными что-то полезное — преобразовывать их (transform), или даже предсказывать неизвестные величины (predict).
В данном случае мы хотим преобразовать тексты («вопросы») в числовые векторы. Это нужно, чтобы можно было находить «близкие» друг к другу тексты, пользуясь математическим понятием расстояние. Расстояние между двумя точками можно рассчитать по теореме Пифагора — как корень из суммы квадратов разностей их координат. В математике это называется Евклидовой метрикой. Если мы сможем превращать тексты в объекты, у которых есть координаты, то мы сможем вычислять Евклидову метрику и, например, находить в базе вопрос, наиболее всего похожий на «о чём ты думаешь?».
Самый простой способ задать координаты текста — это пронумеровать все слова в языке, и сказать, что i-тая координата текста равна числу вхождений в него i-того слова. Например, для текста «я не могу не плакать» координата слова «не» равна 2, координаты слов «я», «могу» и «плакать» равны 1, а координаты всех остальных слов (коих десятки тысяч) равны 0. Такое представление теряет информацию о порядке слов, но всё равно работает неплохо.
Проблема в том, что у слов, которые встречаются часто (например, частиц «и» и «а») координаты будут несоразмерно большие, хотя информации они несут мало. Чтобы смягчить эту проблему, координату каждого слова можно поделить на логарифм числа текстов, где такое слово встречается — это называется tf-idf и тоже работает неплохо.
Проблема только одна: в нашей базе 60 тысяч текстовых «вопросов», в которых содержится 14 тысяч различных слов. Если превратить все вопросы в векторы, получится матрица 60к*14к. Работать с такой не очень классно, поэтому дальше мы поговорим о сокращении размерности.
Сокращение размерности
Мы уже поставили задачу создания болталочного чатбота, скачали и векторизовали данные для его обучения. Теперь у нас есть числовая матрица, представляющая реплики пользователей. Она состоит из 60 тысяч строк (столько было реплик в базе диалогов) и 14 тысяч столбцов (столько в них было различных слов). Сейчас наша задача — сделать её поменьше. Например, представить каждый текст не 14123-мерным, а всего лишь 300-мерным вектором.
Достичь этого можно, умножив нашу матрицу размера 60049х14123 на специально подобранную матрицу проекции размера 14123х300, в итоге получим результат 60049х300. Алгоритм PCA (метод главных компонент) подбирает матрицу проекции так, чтобы исходную матрицу можно было потом восстановить с наименьшей среднеквадратической ошибкой. В нашем случае получилось сохранить около 44% об исходной матрице, хотя размерность сократилась почти в 50 раз.
За счёт чего возможно такое эффективное сжатие? Напомним, что исходная матрица содержит счётчики упоминания отдельных слов в текстах. Но слова, как правило, употреблятся не независимо друг от друга, а в контексте. Например, чем больше раз в тексте новости встречается слово «блокировка», тем больше раз, скорее всего в этом тексте встретится также слово «телеграм». А вот корреляция слова «блокировка», например, со словом «кафтан» отрицательная — они встречаются в разных контекстах.
Так вот, получается, что метод главных компонент запоминает не все 14 тысяч слов, а 300 типовых контекстов, по которым эти слова потом можно пытаться восстановить. Столбцы матрицы проекции, соответствующие синонимичным словам, обычно похожи друг на друга, потому что эти слова часто встречаются в одном контексте. А значит, можно сократить избыточные измерения, не потеряв при этом в информативности.
Во многих современных приложениях матрицу проекции слов вычисляют нейросети (например, word2vec). Но на самом деле простой линейной алгебры для практически полезного результата уже достаточно. Метод главных компонент вычислительно сводится к SVD, а оно — к расчёту собственных векторов и собственных чисел матрицы. Впрочем, программировать это можно, даже не зная деталей.
Поиск ближайших соседей
В предыдущих разделах мы закачали в python корпус диалогов, векторизовали его, и сократили размерность, а теперь хотим наконец научиться искать в нашем 300-мерном пространстве ближайших соседей и наконец-то осмысленно отвечать на вопросы.
Поскольку научились отображать вопросы в Евклидово пространство не очень высокой размерности, поиск соседей в нём можно осуществлять довольно быстро. Мы воспользуемся уже готовым алгоритмом поиска соседей BallTree. Но мы напишем свою модель-обёртку, которая выбирала бы одного из k ближайших соседей, причём чем ближе сосед, тем выше вероятность его выбора. Ибо брать всегда одного самого близкого соседа — скучно, но не завязываться на сходство совсем — опасно.
Поэтому мы хотим превратить найденные расстояния от запроса до текстов-эталонов в вероятности выбора этих текстов. Для этого можно использовать функцию softmax, которая ещё часто стоит на выходе из нейросетей. Она превращает свои аргументы в набор неотрицательных чисел, сумма которых равна 1 — как раз то, что нам нужно. Дальше полученные «вероятности» мы можем использовать для случайного выбора ответа.
Фразы, которые будет вводить пользователь, надо пропускать через все три алгоритма — векторизатор, метод главных компонент, и алгоритм выбора ответа. Чтобы писать меньше кода, можно связать их в единую цепочку (pipeline), применяющую алгоритмы последовательно.
В результате мы получили алгоритм, который по вопросу пользователя способен найти похожий на него вопрос и выдать ответ на него. И иногда это ответы даже звучат почти осмысленно.
Публикация бота в Telegram
Мы уже разобрались, как сделать чатбота-болталку, который бы выдавал примерно уместные ответы на запросы пользователя. Теперь показываю, как выпустить такого чатбота в Телеграм.
Проще всего использовать для этого готовую обёртку Telegram API для питона — например, pytelegrambotapi. Итак, пошаговая инструкция:
Полный код к статье я намеренно не выкладываю — вы получите гораздо больше удовольствия и полезного опыта, когда напечатаете его сами, и получите работающего бота в результате собственных усилий. Ну или если вам очень лень это делать, можете поболтать с моей версией ботика.