Первый запуск
This commit is contained in:
97
Tester/QualityTest.py
Normal file
97
Tester/QualityTest.py
Normal 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}")
|
||||
Reference in New Issue
Block a user