File size: 6,808 Bytes
125ddcd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
import numpy as np
import random
import re
from bs4 import BeautifulSoup
import requests
import wikipedia
greets = [
    'Добрый день!',
    'Здравствуй',
    'Привет, как могу помочь?',
    'Здравствуйте',
    'Приветики',
    'Привет, как дела!',
    'Привет, Привет и ещё раз Привет!'
]
searches = [
    'Ищу в интернете...',
    'Идёт поиск...',
    'Скоро отвечу...',
    'Секунду...',
    'Одну секунду...',
    'Сейчас найду...',
    'Ищу информацию...',
    'Источники не врут, нужно изучить информацию...',
    'Я сейчас...',
    'Подождите минутку...'
]
defaults = [
    'Не понял, повторите',
    'Я не расслышал, можете повторить',
    'Я вас не понял, скажите снова',
    'Вы говорите тихо, скажите пожалуйста погромче.',
    'Я вас не смог понять, можете повторить?'
]

class NeuralNet:
    def __init__(self, input_size, hidden_size, output_size):
        self.Wxh = np.random.randn(hidden_size, input_size) * 0.01
        self.Whh = np.random.randn(hidden_size, hidden_size) * 0.01
        self.Why = np.random.randn(output_size, hidden_size) * 0.01
        self.bh = np.zeros((hidden_size, 1))
        self.by = np.zeros((output_size, 1))
        
    def forward(self, inputs, h_prev):
        h = np.tanh(np.dot(self.Wxh, inputs) + np.dot(self.Whh, h_prev) + self.bh)
        y = np.dot(self.Why, h) + self.by
        return y, h
        
    def train(self, X, Y, learning_rate=0.01, epochs=1000):
        for epoch in range(epochs):
            loss = 0
            h_prev = np.zeros((self.Whh.shape[0], 1))
            
            for i in range(len(X)):
                x = np.array(X[i]).reshape(-1, 1)
                y_true = np.array(Y[i]).reshape(-1, 1)
                
                # Forward pass
                y_pred, h_prev = self.forward(x, h_prev)
                
                # Compute loss
                loss += np.sum((y_pred - y_true) ** 2)
                
                # Backward pass
                dy = y_pred - y_true
                dWhy = np.dot(dy, h_prev.T)
                dby = dy
                
                dh = np.dot(self.Why.T, dy)
                dh_raw = (1 - h_prev ** 2) * dh
                
                dWxh = np.dot(dh_raw, x.T)
                dWhh = np.dot(dh_raw, h_prev.T)
                dbh = dh_raw
                
                # Update weights
                self.Wxh -= learning_rate * dWxh
                self.Whh -= learning_rate * dWhh
                self.Why -= learning_rate * dWhy
                self.bh -= learning_rate * dbh
                self.by -= learning_rate * dby
            
            if epoch % 100 == 0:
                print(f'Epoch {epoch}, Loss: {loss}')

class MaestroAssistant:
    def __init__(self):
        self.wake_word = "эй маэстро"
        self.vocab = {}
        self.intents = {
            'greet': ['привет', 'здравствуй', 'добрый день'],
            'search': ['найди', 'поищи', 'что такое', 'кто такой'],
            'joke': ['расскажи шутку', 'пошути', 'анекдот'],
            'time': ['который час', 'сколько времени', 'время']
        }
        self.responses = {
            'greet': greets,
            'search': searches,
            'joke': 'Я не умею шутить, но могу найти сайт с шутками!',
            'default': defaults
        }
        
        
        self.init_vocab()
        input_size = len(self.vocab)
        hidden_size = 64
        output_size = len(self.intents)
        self.nn = NeuralNet(input_size, hidden_size, output_size)
        
        
        self.train()
        
    def init_vocab(self):
        
        words = set()
        for intent in self.intents.values():
            for phrase in intent:
                words.update(phrase.split())
        self.vocab = {word: i for i, word in enumerate(words)}
        
    def text_to_vector(self, text):
        
        vector = np.zeros(len(self.vocab))
        for word in text.split():
            if word in self.vocab:
                vector[self.vocab[word]] += 1
        return vector
        
    def train(self):
    
        X = []
        y = []
        for i, (intent, phrases) in enumerate(self.intents.items()):
            for phrase in phrases:
                X.append(self.text_to_vector(phrase))
                y_vec = np.zeros(len(self.intents))
                y_vec[i] = 1
                y.append(y_vec)
        
        
        X = np.array(X)
        y = np.array(y)
        
        
        self.nn.train(X, y, epochs=1000, learning_rate=0.01)
        
    def predict_intent(self, text):
        
        vector = self.text_to_vector(text)
        output, _ = self.nn.forward(vector.reshape(-1, 1), np.zeros((self.nn.Whh.shape[0], 1)))
        intent_idx = np.argmax(output)
        return list(self.intents.keys())[intent_idx]
        
    def handle_command(self, command):
    
        if not command.startswith(self.wake_word):
            return None
            
        command = command[len(self.wake_word):].strip()
        intent = self.predict_intent(command)
        
        if intent == 'greet':
            return random.choice(self.responses['greet'])
        elif intent == 'joke':
            return random.choice(self.responses['joke'])
        elif intent == 'search':
            query = re.sub(r'(найди|поищи|что такое|кто такой)', '', command).strip()
            return self.search(query)
        else:
            return random.choice(self.responses['default'])
            
    def search(self, query):
        
        try:
            wikipedia.set_lang('ru')
            result = wikipedia.summary(query, sentences=2)
            return f"Вот что я нашел в Википедии: {result}"
        except:
            pass
            
        
        try:
            url = f"https://www.google.com/search?q={query}"
            headers = {'User-Agent': 'Mozilla/5.0'}
            response = requests.get(url, headers=headers)
            soup = BeautifulSoup(response.text, 'html.parser')
            
            
            result = soup.find('div', class_='BNeawe').text
            return f"Вот что я нашел: {result[:200]}..."
        except Exception as e:
            return f"Не удалось найти информацию: {str(e)}"