Пишем голосового ассистента на Python

А что дальше?

Я хочу продемонстрировать, насколько простыми будут голосовые функции в 2021 году. Вы можете усовершенствовать некоторые системы, добавив распознавание фраз и ключевых слов с помощью машинного обучения и эвристики.

Весь код проекта находится в данном разделе.

Что такое pyttsx3?

Эта библиотека Python позволяет преобразовывать текст в речь. Она доступна для PyThone 2 и Python 3 и функционирует в автономном режиме.

Установка:

pip install pyttsx3

Вы должны импортировать модуль в нашу программу после успешной установки pyttsx3.

.

import pyttsx3

engine = pyttsx3.init('sapi5')
voices = engine.getProperty('voices') #даёт подробности о текущем установленном голосе
engine.setProperty('voice', voice[1].id)  # 0-мужской , 1-женский

Что такое sapi5? Компания предлагает технологию синтеза и распознавания речи под названием Microsoft Speech API (SAP5).

VoiceId позволяет нам выбирать различные голоса.

  • voice[0].id = мужской голос
  • voice[1].id = женский голос

Введение

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

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

1 способ

Для хранения намерений и сценариев развития (которые часто используются для чатов) можно использовать объект, похожий на JSON. В общем случае он выглядит следующим образом:

config = {
    "intents": {
        "greeting": {
            "examples": ["привет", "здравствуй", "добрый день",
                         "hello", "good morning"],
            "responses": play_greetings
        },
        "farewell": {
            "examples": ["пока", "до свидания", "увидимся", "до встречи",
                         "goodbye", "bye", "see you soon"],
            "responses": play_farewell_and_quit
        },
        "google_search": {
            "examples": ["найди в гугл",
                         "search on google", "google", "find on google"],
            "responses": search_for_term_on_google
        },
    },
    "failure_phrases": play_failure_phrase
}

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

Мы рассмотрим этот подход более подробно в шаге 5 этой статьи. А пока рассмотрим менее сложный вариант.

2 способ


Можно взять упрощенный словарь, у которого в качестве ключей будет hashable-тип tuple, а в виде значений будут названия методов, которые будут выполняться. Для коротких команд подойдёт вот такой вариант:

Docker

Для функционирования внутри контейнера базы данных необходим этот элемент. Приложение с интерфейсом бота в будущем также будет установлено внутри другого контейнера.

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

Оборудование для проверки:

Ffmpeg

Коллекция бесплатных библиотек с открытым исходным кодом под названием F Fmpeg позволяет записывать и преобразовывать цифровое аудио и видео в различные форматы.

Почему необходим ffmpeg? Файлы Ogg используются Telegram для сохранения аудиосообщений из твитов. Но формат wav не может быть обработан vosk. Мы будем конвертировать ogg в wav с помощью ffmpeg.

Fmpeg должен быть установлен для того, чтобы использовать многие библиотеки для обработки аудио в Python. Зачем использовать библиотеку, если у нас уже установлен ffmpeg?

# команда для конвертации ogg в wav
ffmpeg -i ./my_phrase.ogg 
-ar 16000 -ac 2 -ab 192K -f wav ./my_phrase_to_translite.wav
разбор параметров команды

База данных

Текстовые данные будут храниться в mongo db. Среди очевидных преимуществ такого средства:

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

import datetime
from pymongo.errors import DuplicateKeyError
from pymongo.collection import Collection


def add_value(database: Collection, value: str):
    """
    Добавить одну запись в базу данных
    """

    database_index = int(datetime.datetime.now().timestamp())
    try:
        database.insert_one({'_id': database_index, 'text': value})
        return True

    except DuplicateKeyError:
        return False

Мы признательны, что вы нашли время ознакомиться с информацией, размещенной на сайте:

Голосовой движок

Для распознавания голоса требуется языковая модель (онлайн или офлайн), которая может быстро преобразовывать аудио в текст. Как правило, он хорошо слышит голоса, но может распознавать голосовые сообщения.

Кроме того, предлагаются как очень легкие (43 мб), так и тяжелые (2,5 гб) российские модели – наличие вариантов всегда хорошо! На официальном сайте вы можете найти список предлагаемых моделей. В дополнение к русскому языку доступны немецкий и русский языки.

Код для модели распознавания русской речи приведен ниже. В качестве входных данных следует использовать Wav-файлы.

import wave
import json
import vosk
from vosk import KaldiRecognizer


def recognize_phrase(model: vosk.Model, phrase_wav_path: str) -> str:
    """
    Recognize Russian voice in wav
    """

    wave_audio_file = wave.open(phrase_wav_path, "rb")
    offline_recognizer = KaldiRecognizer(model, 24000)
    data = wave_audio_file.readframes(wave_audio_file.getnframes())

    offline_recognizer.AcceptWaveform(data)
    recognized_data = json.loads(offline_recognizer.Result())["text"]
    return recognized_data

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

Меньше, чем:

Задача 1: поиск по википедии

Установка и импорт модуля Wikipedia необходимы для того, чтобы отправлять поисковые запросы в Wikipedia.

Команда установки:

pip install wikipedia

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

if __name__ == "__main__":
    wishMe()
    while True:
        query = takeCommand().lower() #Приведём запрос к нижему регистру        
        # выполнение задач в соответствии с запросом
        if 'wikipedia' in query:  #если wikipedia встречается в запросе, выполнится блок:
            speak('Searching Wikipedia...')
            query = query.replace("wikipedia", "")
            results = wikipedia.summary(query, sentences=5) 
            speak("According to Wikipedia")
            print(results)
            speak(results)

Мы использовали if, чтобы проверить, содержит ли запрос пользователя слово “Википедия”. Помощник прочитает и произнесет первые пять предложений статьи Википедии, если это слово присутствует (вы можете изменить это число на любое другое).

Задача 4: воспроизвести музыку

Os – импортировать модуль.

elif 'play music' in query:
    music_dir = 'директория_с_музыкой'
    songs = os.listdir(music_dir)
    print(songs)    
    os.startfile(os.path.join(music_dir, songs[0]))

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

Мы можем воспроизвести любую из наших песен, используя функцию os.startfile, или вы можете выключить определенную песню, используя модуль random. Любая песня из выбранной папки начнет играть всякий раз, когда вы попросите голосового помощника начать воспроизведение музыки.

Задача 5: узнать время

elif 'the time' in query:
    strTime = datetime.datetime.now().strftime("%H:%M:%S")    
    speak(f"Sir, the time is {strTime}")

Функция datetime() используется в этом коде для хранения текущего времени в переменной strTime.

Мы передаем переменную из функции species() в место, где она преобразуется в слова, сохранив время в strTime.

Задача 7: открыть freecodecamp

elif 'open free code camp' in query :            
    webbrowser.open('freecodecamp.org')

Задача 8: открыть pycharm (или другую ide):

elif 'open code' in query:
    codePath = "/Applications/PyCharm CE.app" #путь к приложению
    os.startfile(codePath)

Вы должны указать путь к приложению, прежде чем PyCharm или любое другое приложение будет открыто.

Задача 9: отправить email

Мы импортируем модуль smtplib.

Электронные письма можно отправлять и направлять между различными почтовыми серверами с помощью протокола простой передачи почты (SMTP).

Модуль для отправки сообщений называется S MTP. Используя этот подход, вы можете отправлять электронные письма.

Принять 3 параметры:

  • Отправитель: адрес электронной почты отправителя.
  • Получатель: адрес электронной почты получателя.
  • Сообщение: строка, содержащая сообщение, которое должно быть отправлено одному или нескольким получателям.

Теперь, когда мы создали функцию sendEmail(), мы можем отправлять электронные письма с ее помощью.

Зачем всё это?

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

Голосовой дневник – это лишь одна из иллюстраций того, как голосовые функции могут быть включены в повседневные задачи.

Можно ли считать это искусственным интеллектом?

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

Этот вопрос в значительной степени решается с помощью голосового помощника.

И И!

Настройка среды

Хотя вы можете выбрать любой из этих редакторов, мне больше нравится PyCharm.

Сначала мы импортируем/установим все необходимые библиотеки:

  • pyttsx3;
  • datetime;
  • speech recognition;
  • wikipedia;
  • webbrowser;
  • os.path;
  • smtplib.

Определение функции takecommand():

Способность помощника принимать команды от микрофонов нашей системы является следующим важным компонентом. Для этого мы разработаем функцию takeCommand().

С помощью takeCommand() наш интеллектуальный ассистент сможет возвращать строку, принимая голосовые команды по микрофону.

Однако перед определением takeCommand() мы должны сначала установить модуль speechRecognition с помощью следующей команды:

pip install speechRecognition

После установки мы импортируем модуль в программу:

import speechRecognition as sr

Сначала создадим функцию takeCommand():

def takeCommand():
    #Принимает на входе аудио от микрофона, возвращает строку с нашими словами    
     r = sr.Recognizer()
     with sr.Microphone() as source:
         print("Listening...")
         r.pause_threshold = 1
         audio = r.listen(source)

Создание функции takeCommand() прошло успешно. Чтобы справиться с ошибками, мы добавим блок try-except.

Определение функции воспроизведения речи

Необходимость в интеллектуальном голосовом помощнике невозможно переоценить. Мы должны определить функцию speak(), которая принимает звук на вход и выводит его на экран, чтобы бот заговорил.

def speak(audio): pass #пока так, позже мы напишем все условия.

Чтобы обеспечить общение между пользователем и помощником, теперь необходимо аудио. Установка модуля pyttsx3 позволит нам это сделать.

Повторяем изученное

И вот здесь возникает самый спорный вопрос.

Постановка задачи

4 основные задачи голосового дневника

технологический стек голосового дневника
технологический стек голосового дневника

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

Компоненты нашего дневника будут организованы.

Пример работы

Затем мы ищем в базе данных наши текстовые сообщения.

После того, как текст был правильно распознан, пользователь вернул все записи, которые он сделал за предыдущие 10 минут.

Создание функции main()

Откройте функцию speak (), затем вызовите ее из функции main().

if __name__=="__main__" :

speak('Hello Sir, I am Friday, your Artificial intelligence assistant. Please tell me how may I help you')

В пятницу я позвоню своей ассистентке.

Все аргументы, которые вы передаете функции speak(), преобразуются в звук. Теперь у нашего голосового помощника есть голос, и он готов к разговору с нами!

Создание функции wishme()

Теперь, когда функция wishme() создана, мы можем запрограммировать ее на приветствие различными способами в зависимости от того, сколько времени прошло.

Модуль datetime должен быть импортирован, поэтому мы вставляем его с помощью команды:

import datetime

Теперь напишем функцию wishme():

def wishme():
   hour = int(datetime.datetime.now().hour)

В этом случае переменная hour используется для хранения целочисленного значения часа. С помощью оператора if-else:

def wishMe():
    hour = int(datetime.datetime.now().hour)
    if hour>=0 and hour<12:
        speak("Good Morning!")    
    
    elif hour>=12 and hour<18:
        speak("Good Afternoon!")       
    
    else:
        speak("Good Evening!")      
   
   speak('Hello Sir, I am Friday, your Artificial intelligence assistant. Please tell me how may I help you')

Шаг 1. обработка голосового ввода


Начнём с того, что научимся обрабатывать голосовой ввод. Нам потребуется микрофон и пара установленных библиотек: PyAudio и SpeechRecognition.

Подготовьте основной метод:

import speech_recognition

if __name__ == "__main__":

    # инициализация инструментов распознавания и ввода речи
    recognizer = speech_recognition.Recognizer()
    microphone = speech_recognition.Microphone()

    while True:
        # старт записи речи с последующим выводом распознанной речи 
        voice_input = record_and_recognize_audio()
        print(voice_input)

Теперь мы сможем распознавать речь. Google поможет нам понимать речь на самых разных языках.

def record_and_recognize_audio(*args: tuple):
    """
    Запись и распознавание аудио
    """
    with microphone:
        recognized_data = ""

        # регулирование уровня окружающего шума
        recognizer.adjust_for_ambient_noise(microphone, duration=2)

        try:
            print("Listening...")
            audio = recognizer.listen(microphone, 5, 5)

        except speech_recognition.WaitTimeoutError:
            print("Can you check if your microphone is on, please?")
            return

        # использование online-распознавания через Google 
        try:
            print("Started recognition...")
            recognized_data = recognizer.recognize_google(audio, language="ru").lower()

        except speech_recognition.UnknownValueError:
            pass

        # в случае проблем с доступом в Интернет происходит выброс ошибки
        except speech_recognition.RequestError:
            print("Check your Internet Connection, please")

        return recognized_data

Что делать при отсутствии доступа в Интернет? Существуют решения для автономного распознавания. Лично я чрезвычайно доволен проектом Vosk.

Кроме того, если вам не нужна автономная версия, вы можете не использовать ее. Я хотел продемонстрировать оба варианта только потому, что вы уже можете выбрать их в зависимости от ваших потребностей (например, в Google нет вопроса) и от того, какие языки поддерживает система.

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

Обратите внимание, что мне пришлось создать временный wav-файл, чтобы избежать повторения одной и той же фразы дважды в одной записи.

Соответственно, окончательный код выглядит следующим образом:

Полный код для работы распознавания речи

from vosk import Model, KaldiRecognizer  # оффлайн-распознавание от Vosk
import speech_recognition  # распознавание пользовательской речи (Speech-To-Text)
import wave  # создание и чтение аудиофайлов формата wav
import json  # работа с json-файлами и json-строками
import os  # работа с файловой системой


def record_and_recognize_audio(*args: tuple):
    """
    Запись и распознавание аудио
    """
    with microphone:
        recognized_data = ""

        # регулирование уровня окружающего шума
        recognizer.adjust_for_ambient_noise(microphone, duration=2)

        try:
            print("Listening...")
            audio = recognizer.listen(microphone, 5, 5)

            with open("microphone-results.wav", "wb") as file:
                file.write(audio.get_wav_data())

        except speech_recognition.WaitTimeoutError:
            print("Can you check if your microphone is on, please?")
            return

        # использование online-распознавания через Google 
        try:
            print("Started recognition...")
            recognized_data = recognizer.recognize_google(audio, language="ru").lower()

        except speech_recognition.UnknownValueError:
            pass

        # в случае проблем с доступом в Интернет происходит попытка 
        # использовать offline-распознавание через Vosk
        except speech_recognition.RequestError:
            print("Trying to use offline recognition...")
            recognized_data = use_offline_recognition()

        return recognized_data


def use_offline_recognition():
    """
    Переключение на оффлайн-распознавание речи
    :return: распознанная фраза
    """
    recognized_data = ""
    try:
        # проверка наличия модели на нужном языке в каталоге приложения
        if not os.path.exists("models/vosk-model-small-ru-0.4"):
            print("Please download the model from:n"
                  "https://alphacephei.com/vosk/models and unpack as 'model' in the current folder.")
            exit(1)

        # анализ записанного в микрофон аудио (чтобы избежать повторов фразы)
        wave_audio_file = wave.open("microphone-results.wav", "rb")
        model = Model("models/vosk-model-small-ru-0.4")
        offline_recognizer = KaldiRecognizer(model, wave_audio_file.getframerate())

        data = wave_audio_file.readframes(wave_audio_file.getnframes())
        if len(data) > 0:
            if offline_recognizer.AcceptWaveform(data):
                recognized_data = offline_recognizer.Result()

                # получение данных распознанного текста из JSON-строки
                # (чтобы можно было выдать по ней ответ)
                recognized_data = json.loads(recognized_data)
                recognized_data = recognized_data["text"]
    except:
        print("Sorry, speech service is unavailable. Try again later")

    return recognized_data


if __name__ == "__main__":

    # инициализация инструментов распознавания и ввода речи
    recognizer = speech_recognition.Recognizer()
    microphone = speech_recognition.Microphone()

    while True:
        # старт записи речи с последующим выводом распознанной речи
        # и удалением записанного в микрофон аудио
        voice_input = record_and_recognize_audio()
        os.remove("microphone-results.wav")
        print(voice_input)

Зачем поддерживать автономные возможности, спросите вы.

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

Шаг 2. конфигурация голосового ассистента

Мы выделим отдельный класс под эти данные, если наш голосовой помощник будет иметь пол, язык речи и имя (согласно классификации).

Будет использована автономная библиотека синтеза речи rpyttsx3. Она будет автоматически выбирать один из голосов, которые может синтезировать наш компьютер (могут быть и другие).

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

Полный код основы голосового ассистента (синтез и распознавание речи)

from vosk import Model, KaldiRecognizer  # оффлайн-распознавание от Vosk
import speech_recognition  # распознавание пользовательской речи (Speech-To-Text)
import pyttsx3  # синтез речи (Text-To-Speech)
import wave  # создание и чтение аудиофайлов формата wav
import json  # работа с json-файлами и json-строками
import os  # работа с файловой системой


class VoiceAssistant:
    """
    Настройки голосового ассистента, включающие имя, пол, язык речи
    """
    name = ""
    sex = ""
    speech_language = ""
    recognition_language = ""


def setup_assistant_voice():
    """
    Установка голоса по умолчанию (индекс может меняться в 
    зависимости от настроек операционной системы)
    """
    voices = ttsEngine.getProperty("voices")

    if assistant.speech_language == "en":
        assistant.recognition_language = "en-US"
        if assistant.sex == "female":
            # Microsoft Zira Desktop - English (United States)
            ttsEngine.setProperty("voice", voices[1].id)
        else:
            # Microsoft David Desktop - English (United States)
            ttsEngine.setProperty("voice", voices[2].id)
    else:
        assistant.recognition_language = "ru-RU"
        # Microsoft Irina Desktop - Russian
        ttsEngine.setProperty("voice", voices[0].id)


def play_voice_assistant_speech(text_to_speech):
    """
    Проигрывание речи ответов голосового ассистента (без сохранения аудио)
    :param text_to_speech: текст, который нужно преобразовать в речь
    """
    ttsEngine.say(str(text_to_speech))
    ttsEngine.runAndWait()


def record_and_recognize_audio(*args: tuple):
    """
    Запись и распознавание аудио
    """
    with microphone:
        recognized_data = ""

        # регулирование уровня окружающего шума
        recognizer.adjust_for_ambient_noise(microphone, duration=2)

        try:
            print("Listening...")
            audio = recognizer.listen(microphone, 5, 5)

            with open("microphone-results.wav", "wb") as file:
                file.write(audio.get_wav_data())

        except speech_recognition.WaitTimeoutError:
            print("Can you check if your microphone is on, please?")
            return

        # использование online-распознавания через Google 
        # (высокое качество распознавания)
        try:
            print("Started recognition...")
            recognized_data = recognizer.recognize_google(audio, language="ru").lower()

        except speech_recognition.UnknownValueError:
            pass

        # в случае проблем с доступом в Интернет происходит 
        # попытка использовать offline-распознавание через Vosk
        except speech_recognition.RequestError:
            print("Trying to use offline recognition...")
            recognized_data = use_offline_recognition()

        return recognized_data


def use_offline_recognition():
    """
    Переключение на оффлайн-распознавание речи
    :return: распознанная фраза
    """
    recognized_data = ""
    try:
        # проверка наличия модели на нужном языке в каталоге приложения
        if not os.path.exists("models/vosk-model-small-ru-0.4"):
            print("Please download the model from:n"
                  "https://alphacephei.com/vosk/models and unpack as 'model' in the current folder.")
            exit(1)

        # анализ записанного в микрофон аудио (чтобы избежать повторов фразы)
        wave_audio_file = wave.open("microphone-results.wav", "rb")
        model = Model("models/vosk-model-small-ru-0.4")
        offline_recognizer = KaldiRecognizer(model, wave_audio_file.getframerate())

        data = wave_audio_file.readframes(wave_audio_file.getnframes())
        if len(data) > 0:
            if offline_recognizer.AcceptWaveform(data):
                recognized_data = offline_recognizer.Result()

                # получение данных распознанного текста из JSON-строки 
                # (чтобы можно было выдать по ней ответ)
                recognized_data = json.loads(recognized_data)
                recognized_data = recognized_data["text"]
    except:
        print("Sorry, speech service is unavailable. Try again later")

    return recognized_data


if __name__ == "__main__":

    # инициализация инструментов распознавания и ввода речи
    recognizer = speech_recognition.Recognizer()
    microphone = speech_recognition.Microphone()

    # инициализация инструмента синтеза речи
    ttsEngine = pyttsx3.init()

    # настройка данных голосового помощника
    assistant = VoiceAssistant()
    assistant.name = "Alice"
    assistant.sex = "female"
    assistant.speech_language = "ru"

    # установка голоса по умолчанию
    setup_assistant_voice()

    while True:
        # старт записи речи с последующим выводом распознанной речи
        # и удалением записанного в микрофон аудио
        voice_input = record_and_recognize_audio()
        os.remove("microphone-results.wav")
        print(voice_input)

        # отделение комманд от дополнительной информации (аргументов)
        voice_input = voice_input.split(" ")
        command = voice_input[0]

        if command == "привет":
            play_voice_assistant_speech("Здравствуй")

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

Шаг 3. обработка команд

С помощью совершенно божественных достижений, сделанных нашими коллегами в этой области, мы овладели способностью распознавать и синтезировать речь:D

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

Я предоставлю вам два варианта хранения команд

Шаг 4. добавление мультиязычности


Чтобы научить нашего ассистента работать с несколькими языковыми моделями, будет удобнее всего организовать небольшой JSON-файл с простой структурой:

{
  "Can you check if your microphone is on, please?": {
    "ru": "Пожалуйста, проверь, что микрофон включен",
    "en": "Can you check if your microphone is on, please?"
  },
  "What did you say again?": {
    "ru": "Пожалуйста, повтори",
    "en": "What did you say again?"
  },
}

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

Чтобы получить перевод, необходимо создать отдельный класс с методом:

class Translation:
    """
    Получение вшитого в приложение перевода строк для 
    создания мультиязычного ассистента
    """
    with open("translations.json", "r", encoding="UTF-8") as file:
        translations = json.load(file)


    def get(self, text: str):
        """
        Получение перевода строки из файла на нужный язык (по его коду)
        :param text: текст, который требуется перевести
        :return: вшитый в приложение перевод текста
        """
        if text in self.translations:
            return self.translations[text][assistant.speech_language]
        else:
            # в случае отсутствия перевода происходит вывод сообщения 
            # об этом в логах и возврат исходного текста
            print(colored("Not translated phrase: {}".format(text), "red"))
            return text

Объявите наш перевод следующим образом в методе main перед циклом: translator = Translation().

Речь ассистента теперь звучит следующим образом:

play_voice_assistant_speech(translator.get(
    "Here is what I found for {} on Wikipedia").format(search_term))

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

Шаг 5. немного машинного обучения

Теперь, когда я упомянул пункт 3, мы вернулись к стандартному варианту, используемому большинством чат-ботов, который использует объект JSON для хранения команд, включающих несколько слов. При этом мы должны использовать несколько дополнительных приемов:

def prepare_corpus():
    """
    Подготовка модели для угадывания намерения пользователя
    """
    corpus = []
    target_vector = []
    for intent_name, intent_data in config["intents"].items():
        for example in intent_data["examples"]:
            corpus.append(example)
            target_vector.append(intent_name)

    training_vector = vectorizer.fit_transform(corpus)
    classifier_probability.fit(training_vector, target_vector)
    classifier.fit(training_vector, target_vector)


def get_intent(request):
    """
    Получение наиболее вероятного намерения в зависимости от запроса пользователя
    :param request: запрос пользователя
    :return: наиболее вероятное намерение
    """
    best_intent = classifier.predict(vectorizer.transform([request]))[0]

    index_of_best_intent = list(classifier_probability.classes_).index(best_intent)
    probabilities = classifier_probability.predict_proba(vectorizer.transform([request]))[0]

    best_intent_probability = probabilities[index_of_best_intent]

    # при добавлении новых намерений стоит уменьшать этот показатель
    if best_intent_probability > 0.57:
        return best_intent


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

# подготовка корпуса для распознавания запросов пользователя с некоторой вероятностью
# (поиск похожих)
vectorizer = TfidfVectorizer(analyzer="char", ngram_range=(2, 3))
classifier_probability = LogisticRegression()
classifier = LinearSVC()
prepare_corpus()

while True:
    # старт записи речи с последующим выводом распознанной речи 
    # и удалением записанного в микрофон аудио
    voice_input = record_and_recognize_audio()

    if os.path.exists("microphone-results.wav"):
        os.remove("microphone-results.wav")

    print(colored(voice_input, "blue"))

    # отделение команд от дополнительной информации (аргументов)
    if voice_input:
        voice_input_parts = voice_input.split(" ")

        # если было сказано одно слово - выполняем команду сразу 
        # без дополнительных аргументов
        if len(voice_input_parts) == 1:
            intent = get_intent(voice_input)
            if intent:
                config["intents"][intent]["responses"]()
            else:
                config["failure_phrases"]()

        # в случае длинной фразы - выполняется поиск ключевой фразы 
        # и аргументов через каждое слово,
        # пока не будет найдено совпадение
        if len(voice_input_parts) > 1:
            for guess in range(len(voice_input_parts)):
                intent = get_intent((" ".join(voice_input_parts[0:guess])).strip())
                if intent:
                    command_options = [voice_input_parts[guess:len(voice_input_parts)]]
                    config["intents"][intent]["responses"](*command_options)
                    break
                if not intent and guess == len(voice_input_parts)-1:
                    config["failure_phrases"]()

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

Заключение

На этом я завершил свой краткий учебник.

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

Задокументированные источники голосового помощника доступны здесь.

Конец!

Поздравляем, мы сделали шаг навстречу лени, разработав собственного голосового помощника!

Я благодарен вам за прочтение этой статьи.

Перейдите в репозиторий GitHub автора для лучшего понимания кода.

Python может быть включен для вас, если вы этого захотите! Руководство по любви к искусственному интеллекту!”.

Похожее:  Django allauth авторизация через социальную сеть | VIVAZZI

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *