ekaterina-simonova commited on
Commit
4e59b84
·
verified ·
1 Parent(s): 907aa22

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +26 -33
app.py CHANGED
@@ -160,11 +160,11 @@ class HybridSearch:
160
  """Основная инициализация BM25"""
161
  if not os.path.exists(self.db_path):
162
  raise FileNotFoundError(f"Файл БД не найден: {self.db_path}")
163
-
164
  conn = sqlite3.connect(self.db_path)
165
  conn.row_factory = sqlite3.Row
166
  cursor = conn.cursor()
167
-
168
  try:
169
  cursor.execute("SELECT COUNT(*) FROM content")
170
  count = cursor.fetchone()[0]
@@ -172,7 +172,7 @@ class HybridSearch:
172
 
173
  if count == 0:
174
  raise ValueError("Таблица content пуста")
175
-
176
  cursor.execute("SELECT id, chunk_text FROM content")
177
  valid_docs = 0
178
 
@@ -183,28 +183,27 @@ class HybridSearch:
183
  continue
184
 
185
  tokens = self._preprocess_text(text)
186
- if tokens and len(tokens) >= 2: # Проверяем, что токены не пустые
187
  self.corpus.append(tokens)
188
  self.doc_ids.append(row['id'])
189
  valid_docs += 1
190
- if valid_docs % 1000 == 0: # Логируем прогресс
191
  logger.info(f"Обработано {valid_docs} документов")
192
  except Exception as e:
193
  logger.warning(f"Ошибка обработки документа ID {row['id']}: {str(e)}")
194
-
195
  if valid_docs == 0:
196
  raise ValueError("Нет пригодных документов после обработки")
197
 
198
  logger.info(f"Создание BM25 индекса для {valid_docs} документов")
199
  self.bm25 = BM25Okapi(self.corpus)
200
  logger.info(f"BM25 успешно инициализирован с {valid_docs} документами")
201
-
202
  except Exception as e:
203
  logger.error(f"Ошибка при инициализации BM25: {str(e)}")
204
  raise
205
  finally:
206
  conn.close()
207
-
208
 
209
  def _create_fallback_index(self):
210
  """Создаем минимальный резервный индекс"""
@@ -219,11 +218,10 @@ class HybridSearch:
219
  "измерительные приборы"
220
  ]
221
  self.corpus = [self._preprocess_text(doc) for doc in test_docs]
222
- self.corpus = [doc for doc in self.corpus if doc] # Убираем пустые документы
223
-
224
  if not self.corpus:
225
  logger.error("Не удалось создать даже тестовый корпус")
226
- # Создаем минимальный корпус, чтобы избежать None
227
  self.corpus = [["пусто"]]
228
  self.doc_ids = [0]
229
  else:
@@ -234,39 +232,34 @@ class HybridSearch:
234
  logger.info(f"Резервный индекс создан с {len(self.corpus)} документами")
235
  except Exception as e:
236
  logger.error(f"Ошибка создания резервного индекса: {str(e)}")
237
- # Создаем минимальный индекс
238
  self.corpus = [["пусто"]]
239
  self.doc_ids = [0]
240
  self.bm25 = BM25Okapi(self.corpus)
241
 
242
-
243
  def _preprocess_text(self, text):
244
- """Улучшенная обработка текста"""
245
  try:
246
  if not text or not isinstance(text, str):
247
  return []
248
 
249
  text = re.sub(r"[^\w\s\-']", " ", text.lower())
250
-
251
- try:
252
- # Пробуем использовать NLTK токенизацию
253
- tokens = word_tokenize(text, language='russian')
 
 
 
 
 
 
 
 
 
254
  except Exception as e:
255
- # При ошибке используем простую токенизацию
256
- logger.warning(f"Ошибка NLTK токенизации: {str(e)}")
257
- tokens = text.split()
258
-
259
- # Фильтруем токены
260
- return [
261
- token for token in tokens
262
- if token not in self.stop_words
263
- and len(token) > 2
264
- and not token.isdigit()
265
- ]
266
- except Exception as e:
267
- logger.warning(f"Ошибка обработки текста: {str(e)}")
268
- # Возвращаем простую токенизацию как последнее средство
269
- return [t for t in text.lower().split() if len(t) > 2]
270
 
271
  def search(self, query, top_k=5):
272
  """Поиск с помощью BM25"""
 
160
  """Основная инициализация BM25"""
161
  if not os.path.exists(self.db_path):
162
  raise FileNotFoundError(f"Файл БД не найден: {self.db_path}")
163
+
164
  conn = sqlite3.connect(self.db_path)
165
  conn.row_factory = sqlite3.Row
166
  cursor = conn.cursor()
167
+
168
  try:
169
  cursor.execute("SELECT COUNT(*) FROM content")
170
  count = cursor.fetchone()[0]
 
172
 
173
  if count == 0:
174
  raise ValueError("Таблица content пуста")
175
+
176
  cursor.execute("SELECT id, chunk_text FROM content")
177
  valid_docs = 0
178
 
 
183
  continue
184
 
185
  tokens = self._preprocess_text(text)
186
+ if tokens and len(tokens) >= 2:
187
  self.corpus.append(tokens)
188
  self.doc_ids.append(row['id'])
189
  valid_docs += 1
190
+ if valid_docs % 1000 == 0:
191
  logger.info(f"Обработано {valid_docs} документов")
192
  except Exception as e:
193
  logger.warning(f"Ошибка обработки документа ID {row['id']}: {str(e)}")
194
+
195
  if valid_docs == 0:
196
  raise ValueError("Нет пригодных документов после обработки")
197
 
198
  logger.info(f"Создание BM25 индекса для {valid_docs} документов")
199
  self.bm25 = BM25Okapi(self.corpus)
200
  logger.info(f"BM25 успешно инициализирован с {valid_docs} документами")
201
+
202
  except Exception as e:
203
  logger.error(f"Ошибка при инициализации BM25: {str(e)}")
204
  raise
205
  finally:
206
  conn.close()
 
207
 
208
  def _create_fallback_index(self):
209
  """Создаем минимальный резервный индекс"""
 
218
  "измерительные приборы"
219
  ]
220
  self.corpus = [self._preprocess_text(doc) for doc in test_docs]
221
+ self.corpus = [doc for doc in self.corpus if doc]
222
+
223
  if not self.corpus:
224
  logger.error("Не удалось создать даже тестовый корпус")
 
225
  self.corpus = [["пусто"]]
226
  self.doc_ids = [0]
227
  else:
 
232
  logger.info(f"Резервный индекс создан с {len(self.corpus)} документами")
233
  except Exception as e:
234
  logger.error(f"Ошибка создания резервного индекса: {str(e)}")
 
235
  self.corpus = [["пусто"]]
236
  self.doc_ids = [0]
237
  self.bm25 = BM25Okapi(self.corpus)
238
 
 
239
  def _preprocess_text(self, text):
240
+ """Улучшенная обработка текста с запасным вариантом"""
241
  try:
242
  if not text or not isinstance(text, str):
243
  return []
244
 
245
  text = re.sub(r"[^\w\s\-']", " ", text.lower())
246
+
247
+ try:
248
+ tokens = word_tokenize(text, language='russian')
249
+ except Exception as e:
250
+ logger.warning(f"Ошибка NLTK токенизации: {str(e)}")
251
+ tokens = text.split()
252
+
253
+ return [
254
+ token for token in tokens
255
+ if token not in self.stop_words
256
+ and len(token) > 2
257
+ and not token.isdigit()
258
+ ]
259
  except Exception as e:
260
+ logger.warning(f"Ошибка обработки текста: {str(e)}")
261
+ return [t for t in text.lower().split() if len(t) > 2]
262
+
 
 
 
 
 
 
 
 
 
 
 
 
263
 
264
  def search(self, query, top_k=5):
265
  """Поиск с помощью BM25"""