Pull to refresh

Бот-философ для vk.com

Reading time4 min
Views6.1K
По мотивам многих статей, которые были посвящены ботоводам…

Недавно разрабатывал «под ключ» один интересный проект, посвященный соц.сети vk.com. Задача проста — создать бота, которого можно будет добавить в беседу и который будет выдавать случайные цитаты. Но это показалось слишком просто, поэтому пришлось возродить великого философа Фридриха Ницше, который сделает из бота — сверхбота…

image

Ничего сложного в этом я не увидел, поэтому был быстро написан скрипт такого рода:
Авторизация -> чтение сообщений -> анализ и формирование ответа -> ответ
Все это было сделано с помощью Callback API VK v.5.80 (ничего нового)
Самым сложным пунктом был — «анализ и формирование ответа». Еще бы, ведь это самое главное.
Но дело в том, что я хотел создать «более менее умного бота», чем который будет просто выдавать рандомную фразу из словаря.

«Как у меня это получилось и получилось ли?» — прошу к прочтению…

И так, начнем!

В принципе, у бота довольно простой функционал, но он прост лишь поверхностно. Если углубиться, то все куда сложнее, ведь писать мы будем на PHP (оО)

Повторюсь, что мне не нужен просто генератор цитат, поэтому я решил задать боту кое-какую логику. Однако, мне также не нужна нейронная сеть, ведь обучение — пугающая задача.

Я решил проблему с креативом, когда попытался возродить великого философа XIX века — Фридриха Ницше.

Да, именно Ницше будет в роли бота, а потому даже случайные цитаты будут казаться умнее.
Но я хотел как-то объединить собеседника и бота, создать связь между ними…

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

Таким образом, формировался как-будто ответ на вопрос спрашивающего.

Новое сообщения от пользователя я получал так:

//новое сообщение
case 'message_new':
//...получаем id его автора
$user_id = $data->object->peer_id;
//получаем текст сообщения
$body = $data->object->text;

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

Во-первых, я избавлялся полностью от окончаний "а, и, ы, ами, ями, ах, ых..." и тд… Убирал знаки препинания и прочие символы.

Во-вторых, я не брал в расчет предлоги. Сначала я ограничил слова по их длине — до 3 букв. Но это было неправильно, ведь философии Ницше присущи такие слова, как: "бог, мир, рок, век и тд.". К тому же, после фильтрации слов из четырех букв, были слова из трех букв, ведь отбрасывались окончания. Тогда я просто ограничил поиск по таким словам, как: "над, что, про, как, где и тд.".

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

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

Далее — необходимо было сделать базу, некий словарь фраз/цитат/высказываний из отрывков книг Ницше.

Я загрузил с литрес книги Ницше в формате txt. Собрал их вместе, а затем профильтровал:

1 цитата = 1 предложение ( использовал разделитель в качестве ".", "!', "?" )

получилась база примерно такого вида:

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


Что ж, есть база и отфильтрованное сообщение от пользователя.

до фильтрации: "Ницше, что ты можешь сказать о женщинах?"
после фильтрации: "могу сказать женщин"


Осталось прикрутить систему поиска. С этим было сложно, ведь разные настройки давали разные результаты. И если один код выдавал правильный ответ, то на другой запрос выдавал не то, что нужно.

Было принято решение не использовать регулярные выражения, а вернее использовать их совместно со встроенными функциями типа:

substr
stripos
substr_count


и другие текстовые функции…

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

Логика поиска примерно такова: пройтись по каждому предложению и найти слова из входящего сообщения, которые присутствуют в этом предложении.

Если слово найдено, то прибавляется +1 в качестве «веса переменной».

Следовательно, чем больше слов найдено в предложении, тем больше «вес переменной».

Это говорит о том, что если слова «мораль и жизнь» были найдены в каком-то предложении из базы, то это 100% ответ, который будет выдан.

Но если слова были по теме и выдавало много 100% результатов, то методом rand() выдавалось случайное предложение.

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

 preg_match('/(?:^|\.\s+)([^\.]*?'.$wordpattern.'[^\.]*?\.+)\s+/i', $text , $matches);

Затем все по-автомату:
отправка сообщения

$request_params = array(
'message' =>  $matches[1],
#'message' =>  $find[0],
'peer_id' => $user_id,
'access_token' => $token,
'v' => '5.80'
);
$get_params = http_build_query($request_params);
file_get_contents('https://api.vk.com/method/messages.send?'. $get_params);
header("HTTP/1.1 200 OK");
echo('ok');

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

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

Это тестовая версия, а потому неполная, поэтому маты, молодежный сленг, ошибки в словах и тд — бот не учитывает и база лишь на 10000 фраз.

В качестве примеров могу привести диалоги:

image

image

image

image

image

image

Вывод: Да, бот не имеет двустороннего общения с пользователем — он не искусственный интеллект. Но в беседе из большого количества участников бот станет хорошим «собеседником».
Tags:
Hubs:
-7
Comments6

Articles

Change theme settings