Первый запуск

This commit is contained in:
KuzarinM
2026-05-02 18:33:38 +03:00
commit cb55eaef01
51 changed files with 2127373 additions and 0 deletions

97
Tester/QualityTest.py Normal file
View File

@@ -0,0 +1,97 @@
import difflib
import os
import re
from Generator.LogGenerator import LogGenerator
from Processor.StreamingLogCluster import StreamingLogCluster
from Tester.RegressionMetricsCalculator import RegressionMetricsCalculator
def evaluate_template_similarity(gt_template: str, gen_template: str) -> dict:
"""
Оценивает схожесть сгенерированного шаблона (gen) с эталонным (gt - Ground Truth).
"""
# 1. Разбиваем шаблоны на сегменты (текст и теги <...>)
gt_parts = [p for p in re.split(r'(<[^>]+>)', gt_template) if p]
gen_parts = [p for p in re.split(r'(<[^>]+>)', gen_template) if p]
# --- СТРОГАЯ ПРОВЕРКА (Regex) ---
# Создаем регулярное выражение из эталона:
# Текст должен совпасть жестко, а переменные эталона могут проглотить что угодно (.*)
regex_pattern = '^'
for part in gt_parts:
if part.startswith('<') and part.endswith('>'):
regex_pattern += '(.*)'
else:
regex_pattern += re.escape(part)
regex_pattern += '$'
# Подготавливаем Gen: заменяем его переменные на нулевой байт,
# чтобы они поглотились `(.*)`, но не совпали с реальным текстом случайно
gen_string_for_regex = re.sub(r'<[^>]+>', '\x00', gen_template)
is_perfect_structure = bool(re.match(regex_pattern, gen_string_for_regex, flags=re.DOTALL))
# --- МЯГКАЯ ОЦЕНКА В ПРОЦЕНТАХ (Preservation Score) ---
# Достаем только жесткие константы, выбрасывая все переменные
gt_consts = "".join(p for p in gt_parts if not (p.startswith('<') and p.endswith('>')))
gen_consts = "".join(p for p in gen_parts if not (p.startswith('<') and p.endswith('>')))
# Сравниваем, насколько "скелет" Gen содержит внутри себя "скелет" Эталона
matcher = difflib.SequenceMatcher(None, gt_consts, gen_consts)
# Считаем сумму символов эталона, которые остались на своих местах
matched_chars = sum(block.size for block in matcher.get_matching_blocks())
# Считаем процент от 0.0 до 1.0
preservation_score = matched_chars / len(gt_consts) if gt_consts else 1.0
return {
"is_perfect": is_perfect_structure, # True, если структура не нарушена вообще
"score": round(preservation_score, 4), # 1.0 = Идеал, < 1.0 = Переменные "съели" константы
}
if __name__ == '__main__':
gen = LogGenerator()
metrics = RegressionMetricsCalculator()
MODEL_PATH = '../Resources/model'
DB_FILE = "../Resources/logs.db"
if os.path.exists(DB_FILE):
os.remove(DB_FILE)
print("--- ЗАПУСК: Delta Mode ---")
clusterer = StreamingLogCluster(MODEL_PATH, db_path=DB_FILE)
# Генерируем 10 примеров
for i in range(1):
# 1. Получаем объект Term
term = gen.generate()
# 3. Используем данные (например, сохраняем в JSON для обучения)
print(f"--- Sample {i + 1} ---")
template = term.structure().text
print(f"Template :{template}")
for j in range(10):
# 2. Рендерим его в строку и метаданные
log = term.render(0.5)
processed = clusterer.process(log.text)
eval_result = evaluate_template_similarity(template, processed['template_view'])
score = eval_result['score']
metrics.add_sample(score)
print(f"Positive {j}: {processed['template_view']}")
#print(score)
print(f"Template : {template}")
# # --- ВЫВОДИТ ИТОГОВЫЕ МЕТРИКИ В КОНЦЕ СКРИПТА ---
# print("\n" + "=" * 40)
# print("Метрики:")
# print("=" * 40)
# results = metrics.calculate()
# for metric_name, value in results.items():
# print(f"{metric_name:<10}: {value}")