antimoda1 commited on
Commit ·
361f7d9
1
Parent(s): d6c895c
some refactor
Browse files- _2_splitting.py +8 -36
- generation.py +2 -31
- lemmatizer.py +2 -7
_2_splitting.py
CHANGED
|
@@ -3,7 +3,7 @@ import re
|
|
| 3 |
|
| 4 |
|
| 5 |
# Конфиги для парсинга дат
|
| 6 |
-
|
| 7 |
'O': 1918,
|
| 8 |
'M': 2000,
|
| 9 |
'N': 2026
|
|
@@ -11,17 +11,15 @@ YEARS = {
|
|
| 11 |
|
| 12 |
|
| 13 |
def _parse_single_year(year_str: str) -> int:
|
| 14 |
-
"""
|
| 15 |
-
Парсит один год.
|
| 16 |
-
|
| 17 |
Args:
|
| 18 |
-
year_str: "1962"
|
| 19 |
|
| 20 |
Returns:
|
| 21 |
int: Год
|
| 22 |
"""
|
| 23 |
-
if year_str in
|
| 24 |
-
return
|
| 25 |
else:
|
| 26 |
try:
|
| 27 |
return int(year_str)
|
|
@@ -30,16 +28,11 @@ def _parse_single_year(year_str: str) -> int:
|
|
| 30 |
|
| 31 |
|
| 32 |
def _parse_date_range(date_str: str) -> tuple[int, int]:
|
| 33 |
-
"""
|
| 34 |
-
Парсит строку с датой и возвращает (start_year, end_year).
|
| 35 |
|
| 36 |
Поддерживает:
|
| 37 |
- "1962-2002" -> (1962, 2002)
|
| 38 |
- "1962" -> (1962, 1962)
|
| 39 |
-
- "O" -> (1918, 1918)
|
| 40 |
-
- "N" -> (2026, 2026)
|
| 41 |
-
- "1962-N" -> (1962, 2026)
|
| 42 |
-
- "O-1962" -> (1918, 1962)
|
| 43 |
|
| 44 |
Args:
|
| 45 |
date_str: Строка с датой
|
|
@@ -56,10 +49,8 @@ def _parse_date_range(date_str: str) -> tuple[int, int]:
|
|
| 56 |
end = _parse_single_year(parts[1].strip())
|
| 57 |
assert start <= end, f"Год начала {start} должен быть меньше или равен году конца {end}"
|
| 58 |
return (start, end)
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
year = _parse_single_year(date_str)
|
| 62 |
-
return (year, year)
|
| 63 |
|
| 64 |
|
| 65 |
def parse_metadata_from_document(text: str) -> list[tuple[str, tuple[int, int], str]]:
|
|
@@ -108,25 +99,6 @@ def parse_metadata_from_document(text: str) -> list[tuple[str, tuple[int, int],
|
|
| 108 |
return result
|
| 109 |
|
| 110 |
|
| 111 |
-
def years_overlap(range1: tuple[int, int], range2: tuple[int, int]) -> bool:
|
| 112 |
-
"""
|
| 113 |
-
Проверяет, имеют ли два года диапазонов ненулевое пересечение (включительно).
|
| 114 |
-
|
| 115 |
-
range1 (start1, end1) пересекается с range2 (start2, end2) если:
|
| 116 |
-
start1 <= end2 AND end1 >= start2
|
| 117 |
-
|
| 118 |
-
Args:
|
| 119 |
-
range1: (start_year, end_year)
|
| 120 |
-
range2: (start_year, end_year)
|
| 121 |
-
|
| 122 |
-
Returns:
|
| 123 |
-
bool: True если есть пересечение
|
| 124 |
-
"""
|
| 125 |
-
start1, end1 = range1
|
| 126 |
-
start2, end2 = range2
|
| 127 |
-
return start1 <= end2 and end1 >= start2
|
| 128 |
-
|
| 129 |
-
|
| 130 |
def process_documents(documents) -> tuple[pd.DataFrame, pd.DataFrame]:
|
| 131 |
"""
|
| 132 |
Обрабатывает документы с парсингом дат и создает два датафрейма.
|
|
|
|
| 3 |
|
| 4 |
|
| 5 |
# Конфиги для парсинга дат
|
| 6 |
+
YEARS_ALIASES = {
|
| 7 |
'O': 1918,
|
| 8 |
'M': 2000,
|
| 9 |
'N': 2026
|
|
|
|
| 11 |
|
| 12 |
|
| 13 |
def _parse_single_year(year_str: str) -> int:
|
| 14 |
+
"""
|
|
|
|
|
|
|
| 15 |
Args:
|
| 16 |
+
year_str: "1962" or alias like "O", "M", "N"
|
| 17 |
|
| 18 |
Returns:
|
| 19 |
int: Год
|
| 20 |
"""
|
| 21 |
+
if year_str in YEARS_ALIASES:
|
| 22 |
+
return YEARS_ALIASES[year_str]
|
| 23 |
else:
|
| 24 |
try:
|
| 25 |
return int(year_str)
|
|
|
|
| 28 |
|
| 29 |
|
| 30 |
def _parse_date_range(date_str: str) -> tuple[int, int]:
|
| 31 |
+
"""Парсит строку с датой и возвращает (start_year, end_year).
|
|
|
|
| 32 |
|
| 33 |
Поддерживает:
|
| 34 |
- "1962-2002" -> (1962, 2002)
|
| 35 |
- "1962" -> (1962, 1962)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
|
| 37 |
Args:
|
| 38 |
date_str: Строка с датой
|
|
|
|
| 49 |
end = _parse_single_year(parts[1].strip())
|
| 50 |
assert start <= end, f"Год начала {start} должен быть меньше или равен году конца {end}"
|
| 51 |
return (start, end)
|
| 52 |
+
year = _parse_single_year(date_str)
|
| 53 |
+
return (year, year)
|
|
|
|
|
|
|
| 54 |
|
| 55 |
|
| 56 |
def parse_metadata_from_document(text: str) -> list[tuple[str, tuple[int, int], str]]:
|
|
|
|
| 99 |
return result
|
| 100 |
|
| 101 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 102 |
def process_documents(documents) -> tuple[pd.DataFrame, pd.DataFrame]:
|
| 103 |
"""
|
| 104 |
Обрабатывает документы с парсингом дат и создает два датафрейма.
|
generation.py
CHANGED
|
@@ -3,7 +3,7 @@ import re
|
|
| 3 |
warnings.filterwarnings('ignore')
|
| 4 |
|
| 5 |
|
| 6 |
-
def lemmatize(text, vocabulary):
|
| 7 |
"""
|
| 8 |
Лемматизирует текст и возвращает список терминов из словаря.
|
| 9 |
Поддерживает поиск полных термин и частичный поиск по словам.
|
|
@@ -21,8 +21,6 @@ def lemmatize(text, vocabulary):
|
|
| 21 |
|
| 22 |
# Приводим текст в нижний регистр для поиска
|
| 23 |
text_lower = text.lower()
|
| 24 |
-
# Извлекаем все слова из текста
|
| 25 |
-
words_in_text = set(re.findall(r'\b\w+(?:-\w+)*\b', text_lower, re.UNICODE))
|
| 26 |
|
| 27 |
# Сначала - поиск полных терминов
|
| 28 |
for term in vocabulary.keys():
|
|
@@ -33,38 +31,11 @@ def lemmatize(text, vocabulary):
|
|
| 33 |
if re.search(pattern, text_lower) and term not in found_terms_set:
|
| 34 |
found_terms.append(term)
|
| 35 |
found_terms_set.add(term)
|
| 36 |
-
|
| 37 |
-
# Затем - поиск по первым компонентам составных терминов
|
| 38 |
-
# Например, "Икарус-280" будет найден по слову "Икарусы" или "икарус"
|
| 39 |
-
for term in vocabulary.keys():
|
| 40 |
-
if term in found_terms_set:
|
| 41 |
-
continue # Пропускаем уже найденные
|
| 42 |
-
|
| 43 |
-
term_lower = term.lower()
|
| 44 |
|
| 45 |
-
# Если термин содержит дефис, ищем первую часть
|
| 46 |
-
for separator in ['-', ' ']:
|
| 47 |
-
if separator in term_lower:
|
| 48 |
-
first_part = term_lower.split(separator)[0]
|
| 49 |
-
|
| 50 |
-
# Проверяем каждое слово в тексте
|
| 51 |
-
for word in words_in_text:
|
| 52 |
-
# Статья совпадает с первой частью полностью или является словоформой
|
| 53 |
-
if word == first_part or word.startswith(first_part + 'ы') or \
|
| 54 |
-
word.startswith(first_part + 'а') or word.startswith(first_part + 'у') or \
|
| 55 |
-
word.startswith(first_part + 'е') or word.startswith(first_part + 'и') or \
|
| 56 |
-
word.startswith(first_part + 'о'):
|
| 57 |
-
found_terms.append(term)
|
| 58 |
-
found_terms_set.add(term)
|
| 59 |
-
break
|
| 60 |
-
|
| 61 |
-
if term in found_terms_set:
|
| 62 |
-
break
|
| 63 |
-
|
| 64 |
return found_terms
|
| 65 |
|
| 66 |
|
| 67 |
-
def wrap_prompt(retrieved_text, query_text, inp_vocabula: dict[str, str]):
|
| 68 |
vocabula = inp_vocabula.copy() # Создаем копию словаря, чтобы не изменять оригинал
|
| 69 |
tokens_from_query = lemmatize(query_text, vocabula)
|
| 70 |
tokens_from_retrieved = lemmatize(retrieved_text, vocabula)
|
|
|
|
| 3 |
warnings.filterwarnings('ignore')
|
| 4 |
|
| 5 |
|
| 6 |
+
def lemmatize(text: str, vocabulary: dict[str, str]) -> list[str]:
|
| 7 |
"""
|
| 8 |
Лемматизирует текст и возвращает список терминов из словаря.
|
| 9 |
Поддерживает поиск полных термин и частичный поиск по словам.
|
|
|
|
| 21 |
|
| 22 |
# Приводим текст в нижний регистр для поиска
|
| 23 |
text_lower = text.lower()
|
|
|
|
|
|
|
| 24 |
|
| 25 |
# Сначала - поиск полных терминов
|
| 26 |
for term in vocabulary.keys():
|
|
|
|
| 31 |
if re.search(pattern, text_lower) and term not in found_terms_set:
|
| 32 |
found_terms.append(term)
|
| 33 |
found_terms_set.add(term)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
return found_terms
|
| 36 |
|
| 37 |
|
| 38 |
+
def wrap_prompt(retrieved_text: str, query_text: str, inp_vocabula: dict[str, str]):
|
| 39 |
vocabula = inp_vocabula.copy() # Создаем копию словаря, чтобы не изменять оригинал
|
| 40 |
tokens_from_query = lemmatize(query_text, vocabula)
|
| 41 |
tokens_from_retrieved = lemmatize(retrieved_text, vocabula)
|
lemmatizer.py
CHANGED
|
@@ -92,10 +92,5 @@ class RussianLemmatizer:
|
|
| 92 |
text = text.replace('ё', 'е').lower()
|
| 93 |
doc = self.nlp(text)
|
| 94 |
|
| 95 |
-
# Извлекаем леммы, пропускаем пунктуацию
|
| 96 |
-
|
| 97 |
-
for token in doc:
|
| 98 |
-
if not token.is_punct and token.lemma_.strip(): # Пропускаем пунктуацию и пробелы
|
| 99 |
-
lemmas.append(token.lemma_)
|
| 100 |
-
|
| 101 |
-
return lemmas
|
|
|
|
| 92 |
text = text.replace('ё', 'е').lower()
|
| 93 |
doc = self.nlp(text)
|
| 94 |
|
| 95 |
+
# Извлекаем леммы, пропускаем пунктуацию и пробелы
|
| 96 |
+
return [token.lemma_ for token in doc if not token.is_punct and token.lemma_.strip()]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|