import numpy as np import pandas as pd import requests from io import StringIO from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import cosine_similarity import speech_recognition as sr import pyttsx3 import time class HybridChatBot: def __init__(self, dataset_url=None): self.dataset_url = dataset_url self.qa_pairs = {} self.vectorizer = TfidfVectorizer() self.X = None self.recognizer = sr.Recognizer() self.engine = pyttsx3.init() # Настройки голосового движка voices = self.engine.getProperty('voices') self.engine.setProperty('voice', voices[0].id) self.engine.setProperty('rate', 150) if dataset_url: self.load_dataset() self.train() def load_dataset(self): """Загрузка датасета с веб-ресурса""" try: response = requests.get(self.dataset_url) response.raise_for_status() if self.dataset_url.endswith('.csv'): data = pd.read_csv(StringIO(response.text)) elif self.dataset_url.endswith('.json'): data = pd.read_json(StringIO(response.text)) else: print("Формат файла не поддерживается") return for _, row in data.iterrows(): self.qa_pairs[row["question"].lower()] = row["answer"] print(f"Загружено {len(self.qa_pairs)} пар вопрос-ответ") except Exception as e: print(f"Ошибка загрузки датасета: {e}") def train(self): """Обучение модели на загруженных данных""" if not self.qa_pairs: print("Нет данных для обучения!") return questions = list(self.qa_pairs.keys()) self.X = self.vectorizer.fit_transform(questions) print("Модель обучена на загруженных данных") def add_qa_pair(self, question, answer): """Добавление новой пары вопрос-ответ""" self.qa_pairs[question.lower()] = answer self.train() def get_response(self, user_input): """Получение ответа на ввод пользователя""" if not self.qa_pairs: return "Я еще не обучен. Пожалуйста, добавьте вопросы и ответы." user_vec = self.vectorizer.transform([user_input.lower()]) similarities = cosine_similarity(user_vec, self.X) best_match_idx = np.argmax(similarities) best_match_score = similarities[0, best_match_idx] if best_match_score > 0.5: best_question = list(self.qa_pairs.keys())[best_match_idx] return self.qa_pairs[best_question] else: return None def text_to_speech(self, text): """Озвучивание текста""" self.engine.say(text) self.engine.runAndWait() def speech_to_text(self): """Распознавание голоса с микрофона""" with sr.Microphone() as source: print("\nГоворите сейчас...") self.recognizer.adjust_for_ambient_noise(source) try: audio = self.recognizer.listen(source, timeout=5) text = self.recognizer.recognize_google(audio, language="ru-RU") print(f"Распознано: {text}") return text except sr.UnknownValueError: print("Речь не распознана") return None except sr.RequestError: print("Ошибка сервиса распознавания") return None except sr.WaitTimeoutError: print("Время ожидания истекло") return None def run(self): """Улучшенный интерфейс взаимодействия""" print("\n" + "="*50) print("ДОБРО ПОЖАЛОВАТЬ В ИНТЕЛЛЕКТУАЛЬНЫЙ ЧАТ-БОТ".center(50)) print("="*50) current_mode = "текст" while True: print("\n" + "-"*50) print(f"Текущий режим ввода: {current_mode.upper()}") print("[1] Отправить текстовое сообщение") print("[2] Говорить с ботом голосом") print("[3] Переключить режим ввода") print("[4] Обучить бота новому ответу") print("[5] Выход") try: choice = input("Выберите действие (1-5): ").strip() if choice == "1": user_input = input("\nВаше сообщение: ") if user_input.lower() in ["выход", "стоп"]: break response = self.get_response(user_input) if response: print(f"\nБот: {response}") self.text_to_speech(response) else: print("\nБот: Я не знаю что ответить. Хотите научить меня?") elif choice == "2": user_input = self.speech_to_text() if user_input: if user_input.lower() in ["выход", "стоп"]: break response = self.get_response(user_input) if response: print(f"\nБот: {response}") self.text_to_speech(response) else: print("\nБот: Я не знаю что ответить на это.") self.text_to_speech("Я не знаю что ответить на это") elif choice == "3": current_mode = "голос" if current_mode == "текст" else "текст" print(f"\nРежим изменен на: {current_mode.upper()}") elif choice == "4": print("\nОбучение бота:") question = input("Введите вопрос: ") answer = input("Введите ответ: ") self.add_qa_pair(question, answer) print("Бот успешно обучен!") elif choice == "5": print("\nЗавершение работы...") break else: print("\nПожалуйста, выберите вариант от 1 до 5") except KeyboardInterrupt: print("\nЗавершение работы...") break if __name__ == "__main__": # Пример URL датасета (можно заменить на свой) DATASET_URL = "https://raw.githubusercontent.com/user/repo/main/qa_data.csv" bot = HybridChatBot(DATASET_URL) bot.run()