исправь и улучши
# rnn_chatbot.py

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, SimpleRNN, Dense
from tensorflow.keras.preprocessing.sequence import pad_sequences
import numpy as np

# Для взаимодействия с пользователем через консоль
import sys

# Данные: пары "вопрос-ответ"
data = [
    {"question": "Как тебя зовут", "answer": "Меня зовут AI"},
    {"question": "Как дела", "answer": "У меня всё хорошо спасибо"},
    {"question": "Что ты умеешь", "answer": "Я могу отвечать на вопросы"},
    # Добавьте дополнительные пары "вопрос-ответ" для обучения
]

# Шаг 1: Токенизация и создание словаря
def tokenize(text):
    return text.lower().replace('.', '').replace(',', '').replace('?', '').replace('!', '').split()

vocab = {}
index = 1  # Начинаем с 1, 0 использовать для неизвестных слов и паддинга

for pair in data:
    question_tokens = tokenize(pair["question"])
    answer_tokens = tokenize(pair["answer"])

    for token in question_tokens + answer_tokens:
        if token not in vocab:
            vocab[token] = index
            index += 1

vocab_size = index  # Размер словаря

# Создаем обратный словарь для преобразования индексов обратно в слова
reversed_vocab = {idx: word for word, idx in vocab.items()}
reversed_vocab[0] = '?'  # Добавляем символ для индекса 0 (неизвестно)

# Функция для преобразования текста в числовую последовательность
def text_to_sequence(text):
    tokens = tokenize(text)
    return [vocab.get(token, 0) for token in tokens]  # Неизвестные слова преобразуем в 0

# Преобразуем вопросы и ответы в числовые последовательности
questions_seq = [text_to_sequence(pair["question"]) for pair in data]
answers_seq = [text_to_sequence(pair["answer"]) for pair in data]

# Определяем максимальную длину вопросов и ответов для паддинга
max_question_len = max(len(seq) for seq in questions_seq)
max_answer_len = max(len(seq) for seq in answers_seq)

# Паддим последовательности
questions_padded = pad_sequences(questions_seq, maxlen=max_question_len, padding='pre')
answers_padded = pad_sequences(answers_seq, maxlen=max_answer_len, padding='pre')

# Преобразование данных в тензоры
xs = np.array(questions_padded)
ys = np.array([seq[0] if len(seq) > 0 else 0 for seq in answers_padded])  # Предсказываем первое слово ответа

# Шаг 2: Построение модели
model = Sequential()
model.add(Embedding(input_dim=vocab_size + 1, output_dim=64, input_length=max_question_len))
model.add(SimpleRNN(units=128))
model.add(Dense(units=vocab_size + 1, activation='softmax'))

# Компиляция модели
model.compile(loss='sparse_categorical_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])

# Функция для преобразования числовой последовательности в текст
def sequence_to_text(sequence):
    return ' '.join([reversed_vocab.get(num, '?') for num in sequence])

# Шаг 3: Обучение модели
def train_model():
    history = model.fit(xs, ys, epochs=500, batch_size=2, verbose=0,
                        callbacks=[
                            tf.keras.callbacks.LambdaCallback(
                                on_epoch_end=lambda epoch, logs: print(f"Epoch {epoch + 1}: loss = {logs['loss']:.4f}, accuracy = {logs['accuracy'] * 100:.2f}%") if (epoch + 1) % 100 == 0 else None)
                        ])
    print('Модель обучена')

# Шаг 4: Функция для получения ответа от модели
def get_answer(question):
    sequence = text_to_sequence(question)
    padded_sequence = pad_sequences([sequence], maxlen=max_question_len, padding='pre')
    prediction = model.predict(padded_sequence)
    output_index = np.argmax(prediction, axis=1)[0]
    answer_word = reversed_vocab.get(output_index, None)
    if answer_word and answer_word != '?':
        # Можно добавить логику для более полного ответа
        return answer_word
    else:
        return 'Извините, я не понял'

# Запуск обучения и взаимодействие с пользователем через консоль
if __name__ == "__main__":
    train_model()

    while True:
        try:
            user_question = input('Ваш вопрос (или "выход" для завершения): ')
            if user_question.lower() == 'выход':
                print('До свидания!')
                break
            response = get_answer(user_question)
            print('Ответ:', response)
        except KeyboardInterrupt:
            print('\nДо свидания!')
            sys.exit()