23 июня 2020 Python
В этом руководстве разберем создание голосового бота использующего технологии нейронных сетей на языке Python. Бот может распознавать человеческий голос в реальном времени с вашего устройства, например с микрофона ноутбука, и произносить осознанные ответы, которые обрабатывает нейронная сеть.
Бот состоит из двух основных частей: это часть обрабатывающая словарь и часть с голосовым ассистентом.
Всю разработку по написанию бота вы можете вести в IDE PyCharm, скачать можно с официального сайта JetBrains.
Все необходимые библиотеки можно установить с помощью PyPI прямо в консоле PyCharm. Команды для установки вы можете найти на официальном сайте в разделе нужной библиотеки.
Официальный сайт PyPI
Проблема возникла только с библиотекой PyAudio в Windows. Помогло следующее решение:
pip install pipwin pipwin install pyaudio
Содержание
- 1 Дата-сет
- 2 Голосовой ассистент
- 3 Текст дата-сета
- 4 Код Python
Дата-сет
Дата-сет — это набор данных для анализа. В нашем случае это будет некий текстовый файл содержащий строки в виде вопрос\ответ.
Все строки текста перебираются с помощью функции for
, при этом из текста удаляются все ненужные символы по маске, находящейся в переменной alphabet
. Каждое значение строки раздельно заносится в массив dataset
.
После обработки текста все его значения преобразуются в вектора с помощью библиотеки для машинного обучения Scikit-learn. В этом примере используется функция CountVectorizer()
. Далее всем векторам присваивается класс с помощью классификатора LogisticRegression()
.
Когда приходит сообщение от пользователя оно так же преобразуется в вектор, и далее нейросеть пытается найти похожий вектор в датасете соответствующий какому-то вопросу, когда вектор найден, мы получим ответ.
Голосовой ассистент
Для распознавания голоса и озвучивания ответов бота, используется библиотека SpeechRecognition. Система ждет в бесконечном цикле, когда придет вопрос, в нашем случае голос с микрофона, после чего преобразует его в текст и отправляет на обработку в нейросеть. После получения текстового ответа он преобразуется в речь, запись сохраняется в папке с проектом и удаляется после воспроизведения. Вот так все просто! Для удобства все сообщения дублируются текстом в консоль.
При дефолтных настройках время ответа было достаточно долгим, иногда нужно было ждать по 15-30 сек. К тому же вопрос принимался от малейшего шума. Помогли следующие настройки:
voice_recognizer.dynamic_energy_threshold = False voice_recognizer.energy_threshold = 1000 voice_recognizer.pause_threshold = 0.5
И timeout = None, phrase_time_limit = 2
в функции listen()
После чего бот стал отвечать с минимальной задержкой.
Возможно вам подойдут другие значения. Описание этих и других настроек вы можете посмотреть все на том же сайте PyPI в разделе библиотеки SpeechRecognition. Но настройку phrase_time_limit
я там почему-то не нашел, наткнулся на нее случайно в Stack Overflow.
Текст дата-сета
Это небольшой пример текста. Конечно же вопросов и ответов должно быть гораздо больше.
привет\привет как дела\всё прекрасно как дела\спасибо отлично кто ты\я бот что делаешь\с тобой разговариваю
Код Python
import speech_recognition as sr from gtts import gTTS import playsound import os import random from sklearn.feature_extraction.text import CountVectorizer from sklearn.linear_model import LogisticRegression # Словарь def clean_str(r): r = r.lower() r = [c for c in r if c in alphabet] return ''.join(r) alphabet = ' 1234567890-йцукенгшщзхъфывапролджэячсмитьбюёqwertyuiopasdfghjklzxcvbnm' with open('dialogues.txt', encoding='utf-8') as f: content = f.read() blocks = content.split('\n') dataset = [] for block in blocks: replicas = block.split('\\')[:2] if len(replicas) == 2: pair = [clean_str(replicas[0]), clean_str(replicas[1])] if pair[0] and pair[1]: dataset.append(pair) X_text = [] y = [] for question, answer in dataset[:10000]: X_text.append(question) y += [answer] vectorizer = CountVectorizer() X = vectorizer.fit_transform(X_text) clf = LogisticRegression() clf.fit(X, y) def get_generative_replica(text): text_vector = vectorizer.transform([text]).toarray()[0] question = clf.predict([text_vector])[0] return question # Голосовой ассистент def listen(): voice_recognizer = sr.Recognizer() voice_recognizer.dynamic_energy_threshold = False voice_recognizer.energy_threshold = 1000 voice_recognizer.pause_threshold = 0.5 with sr.Microphone() as source: print("Говорите 🎤") audio = voice_recognizer.listen(source, timeout = None, phrase_time_limit = 2) try: voice_text = voice_recognizer.recognize_google(audio, language="ru") print(f"Вы сказали: {voice_text}") return voice_text except sr.UnknownValueError: return "Ошибка распознания" except sr.RequestError: return "Ошибка соединения" def say(text): voice = gTTS(text, lang="ru") unique_file = "audio_" + str(random.randint(0, 10000)) + ".mp3" voice.save(unique_file) playsound.playsound(unique_file) os.remove(unique_file) print(f"Бот: {text}") def handle_command(command): command = command.lower() reply = get_generative_replica(command) say(reply) def stop(): say("Пока") def start(): print(f"Запуск бота...") while True: command = listen() handle_command(command) try: start() except KeyboardInterrupt: stop()
Работа бота в PyCharm