[Мессенджеры, ООП, Функциональное программирование, Kotlin, Natural Language Processing] Распознавание команд
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
При разработке ботов для Telegram и других месенджеров, периодически возникает задача распознавания и выполнения запросов, высказанных человеческим языком. Именно эта "фишка", по некоторому мнению, и является главным отличием ботов от приложений командной строки. Под катом описан собственный фреймворк для исполнения произвольных речевых команд. Описания ключевых концепций сопровождены примерами на языке Kotlin.За основу для распознания речи возьмем нормализованные семантические представления. Их выбор обусловлен прежде всего простотой и легкостью реализации. Начнем с базиса, пример из исходников фреймворка:
/** Правило проверяет лексему на соответствие */
typealias Rule = (String) -> Boolean
/** Нормализованное семантическое представление */
open class Semnorm(vararg val rules: Rule)
/** Правило задает стемы для семантических представлений */
fun stem(vararg stems: String): Rule = { stems.any(it::startsWith) }
/** Правило задает точные соответствия для семантических представлений */
fun word(vararg words: String): Rule = { words.any(it::equals) }
/** Проверяем слово на соответствие семантике */
fun String.matches(norm: Semnorm) = norm.rules.any { it(this) }
Теперь у нас появилась возможность задавать предопределенные нормализованные семантические представления в виде объектов:
object Day : Semnorm(stem("day", "суток", "сутк", "дня", "ден", "дне"))
Фреймворк ставит их в соответствие лексемам входящих фраз, и предложение начинает выглядеть, например так:
assertThat(
"забань васю на 5 минут".tokenize(),
equalTo(
listOf(
Token("забань", Ban),
Token("васю", null),
Token("на", null),
Token("5", Number),
Token("минут", Minute)
)
)
)
С распознаванием речи мы разобрались. Код токенизатора приложен в репозитории, доступном в конце статьи. Перейдем к исполнению команд из речи. А вот здесь и начинается самое интересное: фреймворк позволяет для каждого семантического представления навесить заданное поведение. Снова простейший пример, как распознать запрос справки на двух языках:
object Help : ExecutableSemnorm(stem(
"помощ", "справк", "правил", "help",
"rule", "faq", "start", "старт",
)) {
override fun execute(bot: Botm: Message) {
val faq = message.from.relatedFaq()
bot.sendMessage(m.chat.id, faq)
}
}
Что насчет более сложного поведения, зависящего от различных слов в предложении? Оно тоже поддерживается, вот как, например, исполняется, уже известное из тестов предложение забанить Васю:
object Ban : DurableSemonrm(stem(
"ban", "block", "mute", "бан", "блок",
"забан", "завали", "замьют",
)) {
override fun execute(
bot: Bot, attackerMessage: Message, duration: Duration) {
val victimMessage = attackerMessage.replyToMessage
val victimId = victimMessage.from.id
val untilSecond = now().epochSecond + duration.inWholeSeconds
bot.restrictChatMember(
attackerMessage.chat.id, victimId, untilSecond)
}
}
Откуда это семантическое представление знает о своей продолжительности? Дело в том, что ему вовсе не обязательно парсить всю цепочку токенов целиком. Достаточно задать только минимально необходимое поведение для каждого представления, например для времени:
object Week : Semnorm(stem("week", "недел")) {
override fun toDuration(number: Long) =
days(number) * 7
}
Или для любых команд, зависящих от времени:
class DurableSemnorm(vararg rules: Rule) : ExecutableSemnorm(*rules) {
final override fun execute(
token: Iterator<Token>, bot: Bot, m: Message) =
execute(bot, message, token.parseDuration())
abstract fun execute(bot: Bot, m: Message, duration: Duration)
}
Благодаря такой архитектуре, нам больше не приходится думать о запутанной логике работы интерпретатора. Достаточно просто определить желаемые атрибуты для семантических представлений и наслаждаться результатом. Пример бота, использующего эту концепцию, можно посмотреть на Github: https://github.com/demidko/timecobot
===========
Источник:
habr.com
===========
Похожие новости:
- [Разработка веб-сайтов, CSS, JavaScript, HTML, Node.JS] Как я сделал свою сборку Gulp для быстрой, лёгкой и приятной вёрстки
- [Разработка веб-сайтов, JavaScript, Программирование, Совершенный код] Погружение во внедрение зависимостей (DI), или как взломать Матрицу
- [Веб-дизайн, Разработка веб-сайтов, Платежные системы, JavaScript, Дизайн мобильных приложений] Создаём королевскую форму для приёма банковских карт
- [Мессенджеры, Oracle, API, Голосовые интерфейсы] Как можно запустить MVP личного кабинета в WhatsApp и получить новый инструмент для проверки гипотез
- [Разработка веб-сайтов, JavaScript, Клиентская оптимизация, HTML, VueJS] Проблемы рендера 7-и тысяч элементов на Vuetify
- [JavaScript, Программирование] Доступные текстовые метки для всех (перевод)
- [Разработка веб-сайтов, JavaScript, Программирование, TypeScript] Как мы потерпели неудачу, а затем преуспели в переходе на TypeScript (перевод)
- [Java, Тестирование веб-сервисов] Как найти все битые ссылки на странице с помощью Selenium (перевод)
- [Программирование, Java, .NET] Как я выбирал между .NET и Java
- [Java, SQL] Как выбрать 1 млн. записей из бд, записать в Excel и не упасть с OutOfMemoryError
Теги для поиска: #_messendzhery (Мессенджеры), #_oop (ООП), #_funktsionalnoe_programmirovanie (Функциональное программирование), #_kotlin, #_natural_language_processing, #_kotlin, #_java, #_telegram, #_bot, #_raspoznavanie_rechi (распознавание речи), #_messendzhery (
Мессенджеры
), #_oop (
ООП
), #_funktsionalnoe_programmirovanie (
Функциональное программирование
), #_kotlin, #_natural_language_processing
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 07:56
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
При разработке ботов для Telegram и других месенджеров, периодически возникает задача распознавания и выполнения запросов, высказанных человеческим языком. Именно эта "фишка", по некоторому мнению, и является главным отличием ботов от приложений командной строки. Под катом описан собственный фреймворк для исполнения произвольных речевых команд. Описания ключевых концепций сопровождены примерами на языке Kotlin.За основу для распознания речи возьмем нормализованные семантические представления. Их выбор обусловлен прежде всего простотой и легкостью реализации. Начнем с базиса, пример из исходников фреймворка: /** Правило проверяет лексему на соответствие */
typealias Rule = (String) -> Boolean /** Нормализованное семантическое представление */ open class Semnorm(vararg val rules: Rule) /** Правило задает стемы для семантических представлений */ fun stem(vararg stems: String): Rule = { stems.any(it::startsWith) } /** Правило задает точные соответствия для семантических представлений */ fun word(vararg words: String): Rule = { words.any(it::equals) } /** Проверяем слово на соответствие семантике */ fun String.matches(norm: Semnorm) = norm.rules.any { it(this) } object Day : Semnorm(stem("day", "суток", "сутк", "дня", "ден", "дне"))
assertThat(
"забань васю на 5 минут".tokenize(), equalTo( listOf( Token("забань", Ban), Token("васю", null), Token("на", null), Token("5", Number), Token("минут", Minute) ) ) ) object Help : ExecutableSemnorm(stem(
"помощ", "справк", "правил", "help", "rule", "faq", "start", "старт", )) { override fun execute(bot: Botm: Message) { val faq = message.from.relatedFaq() bot.sendMessage(m.chat.id, faq) } } object Ban : DurableSemonrm(stem(
"ban", "block", "mute", "бан", "блок", "забан", "завали", "замьют", )) { override fun execute( bot: Bot, attackerMessage: Message, duration: Duration) { val victimMessage = attackerMessage.replyToMessage val victimId = victimMessage.from.id val untilSecond = now().epochSecond + duration.inWholeSeconds bot.restrictChatMember( attackerMessage.chat.id, victimId, untilSecond) } } object Week : Semnorm(stem("week", "недел")) {
override fun toDuration(number: Long) = days(number) * 7 } class DurableSemnorm(vararg rules: Rule) : ExecutableSemnorm(*rules) {
final override fun execute( token: Iterator<Token>, bot: Bot, m: Message) = execute(bot, message, token.parseDuration()) abstract fun execute(bot: Bot, m: Message, duration: Duration) } =========== Источник: habr.com =========== Похожие новости:
Мессенджеры ), #_oop ( ООП ), #_funktsionalnoe_programmirovanie ( Функциональное программирование ), #_kotlin, #_natural_language_processing |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 07:56
Часовой пояс: UTC + 5