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


В этой статье Вас ждет курс по подключению и работе с базой данных SQL, хранение и получение данных, все это мы будем использовать при создании бота Вконтакте

Если Вы читаете эту статью, значит Вы уже более менее разбираетесь в работе сервера. Для начала давайте рассмотрим то, что требуется для работы с базой данных.
Сервер с PHP не ниже 5.6
MySQL 5.5.х и выше
А теперь я отвечу на несколько вопросов
Что такое MySQL — Это система управления базами данных (СУБД), простым языком, с помощью MySQL мы можем сохранять, получать и удалять данные из таблиц.
Почему лучше выбирать SQL? Хранение данных в файлах при большом объеме информации будет с каждым разом нагружать работу вашего скрипта, дело может дойти до того, что данные просто не будут сохранятся. При использовании MySQL это проблема пропадает из за высокой скорости работы и структурированного хранения данных, что идеально подходит для работы с большим объемом данных.

операторы определения данных:
CREATE создаёт объект БД (саму базу, таблицу, представление, пользователя и т. д.),
ALTER изменяет объект,
DROP удаляет объект;
операторы манипуляции данными:
SELECT выбирает данные, удовлетворяющие заданным условиям,
INSERT добавляет новые данные,
UPDATE изменяет существующие данные,
DELETE удаляет данные;

Для нашего проекта мы будем использовать операторы манипуляции данными, давайте уже начнем. В связи с тем что мы используем PHP для создания бота, то сами разработчики PHP рекомендуют использовать MySQLi, а начиная с версии PHP 7.x работает только MySQLi

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

Теперь создаем файл нашего будущего проекта, давайте сделаем бота для Вконтакте, который будет сохранять информацию о пользователе в БД, для примера можем написать админку для нашего прошлого кода, о котором я писал здесь

Берем готовый код с прошлой статьи

Админ права нужно было прописывать постоянно в скрипте, в строке
Это не совсем удобно, давайте создадим команду !админ, которая будет принимать 1 аргумент, это ID пользователя, его мы уже научились принимать в той же статье про исключение пользователя.

Такой командой мы получаем ID пользователя

Этот ID мы будем сохранять в базу данных, потом получать его и сверять, есть ли этот ID в БД, если да, то даем доступ к команде.

Теперь создаем базу данных. Сделать это можно используя панель управления ISPManager, она предоставляется практически всегда, заходим и выбираем Базы данных и создаем новую БД, название bot, пользователь и пароль придумайте свои, сохраняем.

Теперь ниже переходим в phpMyAdmin

Или просто перейти с раздела Базы данных, если такая кнопка есть

После того как зашли в phpMyAdmin, нам нужно создать таблицу в БД, выбираем сверху в меню SQL и вставляем туда запрос, не забудьте выбрать название БД, где мы будем создавать саму таблицу


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

и делаем подключение в самом скрипте

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

Давайте напишем команду и посмотрим что произойдет
Данные сохранились в таблицу, но если мы повторно отправим команду с этим же ID, будет создана еще 1 запись, а это нам не нужно, давайте сделаем проверку, если запись уже есть, то ничего предупредим об этом, иначе создадим запись в БД

Что бы проверить наличие записи, нужен оператор SELECT, им будем проверять наличие записей в БД. Давайте сделаем проверку на наличие записи в БД. Пишем следующий код:

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

Таким образом делается проверка на наличие записи.

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

Таким образом мы получили данные с БД и вывели их с помощью бота. Такой способ выводит только 1 запись, для вывода нескольких записей нужно использовать цикл WHILE

Создаем еще 1 запись в БД и проверим получения данных из БД:

С получением данных разобрались, теперь рассмотрим последний пример на сегодня, это UPDATE, для обновления записей в БД.

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

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

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

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

На мой взгляд, в этом что-то есть…

Тем не менее, о чат-ботах много говорят на Хабре. Они могут быть самые разные. Популярностью пользуются боты на базе нейронных сетей прогнозирования, которые генерируют ответ пословно. Это очень интересно, но затратно с точки зрения реализации, особенно для русского языка из-за большого количества словоформ. Мной был выбран другой подход для реализации чат-бота Boltoon.

Boltoon работает по принципу выбора наиболее семантически близкого ответа из предложенной базы данных с последующей обработкой. Этот подход имеет ряд преимуществ:

  • Быстрота работы;
  • Чат-бот можно использовать для разных задач, для этого нужно загрузить новую базу;
  • Боту не требуется дообучение после обновления базы.

Есть база данных с вопросами и ответами на них.

Необходимо, чтобы бот хорошо распознавал смысл введенных фраз и находил похожие в базе. Например, «как дела?», «как ты?», «как дела у тебя?» значат одно и то же. Т.к. компьютер хорошо работает с числами, а не с буквами, поиск соответствий между введенной фразой и имеющимися нужно свести к сравнению чисел. Требуется перевести всю колонку с вопросами из базы данных в числа, вернее, в векторы из N действительных чисел. Так все документы получат координаты в N-мерном пространстве. Представить его затруднительно, но можно снизить размерность пространства до 2 для наглядности.

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

Теперь обо всем по порядку и более формальным языком. Введем понятие «векторное представление текста» (word embeddings) – отображение слова из естественного языка в вектор фиксированной длины (обычно от 100 до 500 измерений, чем выше это значение, тем представление точнее, но сложнее его вычислить).

Например, слова «наука», «книга» могут иметь следующее представление:

На Хабре уже писали об этом (подробно можно почитать здесь). Для данной задачи более всего подходит распределенная модель представления текста. Представим, что есть некое «пространство смыслов» — N-мерная сфера, в которой каждое слово, предложение или абзац будут точкой. Вопрос в том, как его построить?

В 2013 году появилась статья «Efficient Estimation of Word Representations in Vector Space», автор Томас Миколов, в которой он говорит о word2vec. Это набор алгоритмов для нахождения распределенного представления слов. Так каждое слово переводится в точку в некотором семантическом пространстве, причем алгебраические операции в этом пространстве соответствуют операциям над смыслом слов (поэтому используют слово семантическое).

На картинке отображено это очень важное свойство пространства на примере вектора «женственности». Если от вектора слова «король» вычесть вектор слова «мужчина» и прибавить вектор слова «женщина», то получим «королеву». Больше примеров Вы можете найти в лекциях Яндекса, также там представлено объяснение работы word2vec «для людей», без особой математики.

На Python это выглядит примерно так (потребуется установить пакет gensim).

Здесь используется уже построенная модель word2vec проектом Russian Distributional Thesaurus

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

Модель, которую предложил Миколов очень проста – предполагается, что слова, находящиеся в схожих контекстах, могут значить одно и то же. Рассмотрим архитектуру нейронной сети.

Word2vec использует один скрытый слой. Во входном слое установлено столько нейронов, сколько слов в словаре. Размер скрытого слоя – размерность пространства. Размер выходного слоя такой же, как входного. Таким образом, считая, что словарь для обучения состоит из V слов и N размерность векторов слов, веса между входным и скрытым слоем образуют матрицу SYN0 размера V×N. Она представляет собой следующее.

Каждая из V строк является векторным N-мерным представлением слова.

Аналогично, веса между скрытым и выходным слоем образуют матрицу SYN1 размера N×V. Тогда на входе выходного слоя будет:

где – j-ый столбец матрицы SYN1.

Скалярное произведение – косинус угла между двумя точками в n-мерном пространстве. И эта формула показывает, как близко находятся векторы слов. Если слова противоположные, то это значение -1. Затем используем softmax – «функцию мягкого максимума», чтобы получить распределение слов.

С помощью softmax word2vec максимизирует косинусную меру между векторами слов, которые встречаются рядом и минимизирует, если не встречаются. Это и есть выход нейронной сети.

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

«Кот увидел собаку»,
«Кот преследовал собаку»,
«Белый кот взобрался на дерево».

Словарь корпуса содержит восемь слов: [«белый», «взобрался», «дерево», «кот», «на», «преследовал», «собаку», «увидел»]

После сортировки в алфавитном порядке на каждое слово можно ссылаться по его индексу в словаре. В этом примере нейронная сеть будет иметь восемь входных и выходных нейронов. Пусть будет три нейрона в скрытом слое. Это означает, что SYN0 и SYN1 будут соответственно 8×3 и 3×8 матрицами. Перед началом обучения эти матрицы инициализируются небольшими случайными значениями, как это обычно бывает при обучении. Пусть SYN0 и SYN1 инициализированы так:

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

В этом случае входной вектор X будет (потому что «взобрался» находится вторым в словаре). Вектор слова «кот» — .

При подаче на вход сети вектора, представляющего «взобрался», вывод на нейронах скрытого слоя можно вычислить так:

Обратите внимание, что вектор H скрытого слоя равен второй строке матрицы SYN0. Таким образом, функция активации для скрытого слоя – это копирование вектора входного слова в скрытый слой.

Аналогично для выходного слоя:

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

Таким образом вероятности для восьми слов в корпусе равны: [0,143073 0,094925 0,114441 0,111166 0,14492 0,122874 0,119431 0,1448800], вероятность «кота» равна 0,111166 (по индексу в словаре).

Так мы сопоставили каждому слову вектор. Но нам нужно работать не со словами, а со словосочетаниями или с целыми предложениями, т.к. люди общаются именно так. Для это существует Doc2vec (изначально Paragraph Vector) – алгоритм, который получает распределенное представление для частей текстов, основанный на word2vec. Тексты могут быть любой длины: от словосочетания до абзацев. И очень важно, что на выходе получаем вектор фиксированной длины.

На этой технологии основан Boltoon. Сначала мы строим 300-мерное семантическое пространство (как упоминалось выше, выбирают размерность от 100 до 500) на основе русскоязычной Википедии (ссылка на дамп).

Еще немного Python.

Создаем экземпляр класса для последующего обучения с параметрами:

  • min_count: минимальная частота появления слова, если частота ниже заданной – игнорировать
  • window: «окно», в котором рассматривается контекст
  • size: размерность вектора (пространства)
  • sample: максимальная частота появления слова, если частота выше заданной – игнорировать
  • workers: количество потоков

Строим таблицу словарей. Documents – дамп Википедии.

Обучение. total_examples – количество документов на вход. Обучение проходит один раз. Это ресурсоемкий процесс, строим модель из 50 МБ дампа Википедии (мой ноутбук с 8 ГБ RAM больше не потянул). Далее сохраняем обученную модель, получая эти файлы.

Как упоминалось выше, SYN0 и SYN1 – матрицы весов, образованные во время обучения. Эти объекты сохранены в отдельные файлы с помощью pickle. Их размер пропорционален N×V×W, где N – размерность вектора, V – количество слов в словаре, W – вес одного символа. Из этого получился такой большой размер файлов.

Возвращаемся к базе данные с вопросами и ответами. Находим координаты всех фраз в только что построенном пространстве. Получается, что с расширением базы данных не придется переучивать систему, достаточно учитывать добавленные фразы и находить их координаты в том же пространстве. Это и есть основное достоинство Boltoon’а – быстрая адаптация к обновлению данных.

Теперь поговорим об обратной связи с пользователем. Найдем координату вопроса в пространстве и ближайшую к нему фразу, имеющуюся в базе данных. Но здесь возникает проблема поиска ближайшей точки к заданной в N-мерном пространстве. Предлагаю использовать KD-Tree (подробнее о нем можно почитать здесь).

KD-Tree (K-мерное дерево) – структура данных, которая позволяет разбить K-мерное пространство на пространства меньшей размерности посредством отсечения гиперплоскостями.

Но оно имеет существенный недостаток: при добавлении элемента перестройка дерева осуществляется за O(NlogN) в среднем, что долго. Поэтому Boltoon использует «ленивое» обновление — перестраивает дерево каждые M добавлений фраз в базу данных. Поиск происходит за O(logN).

Для дообучения Boltoon’a был введен следующий функционал: после получения вопроса отправляется ответ с двумя кнопками для оценки качества.

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

Пример диалога с Boltoon’ом с использованием фраз, которых нет в базе данных.