import math from typing import List class RegressionMetricsCalculator: def __init__(self): self.errors: List[float] =[] def add_sample(self, score: float): """ score: число от 0.0 до 1.0 (результат evaluate_template_similarity) Идеал - это 1.0. Ошибка - это то, насколько мы отклонились от 1.0. """ # Защита от кривых значений (если вдруг score вылезет за пределы) score = max(0.0, min(1.0, score)) error = 1.0 - score self.errors.append(error) def calculate(self) -> dict: n = len(self.errors) if n == 0: return {} # 1. MAE (Mean Absolute Error) - Средняя абсолютная ошибка mae = sum(abs(e) for e in self.errors) / n # 2. MSE (Mean Squared Error) - Среднеквадратичная ошибка mse = sum(e**2 for e in self.errors) / n # 3. RMSE (Root Mean Squared Error) - Корень из MSE rmse = math.sqrt(mse) # 4. MAPE (Mean Absolute Percentage Error) - в процентах # Так как наше "истинное" значение всегда 1.0, деление на 1.0 ничего не меняет, # мы просто умножаем на 100 для получения процентов. mape = (sum(abs(e) / 1.0 for e in self.errors) / n) * 100 # 5. MAD (Mean Absolute Deviation) # В статистике часто означает среднее отклонение от СРЕДНЕЙ ошибки # (чтобы показать разброс ошибок вокруг их собственного среднего). mean_error = sum(self.errors) / n mad = sum(abs(e - mean_error) for e in self.errors) / n return { "MAE": round(mae, 4), "MAPE (%)": round(mape, 2), "MAD": round(mad, 4), "MSE": round(mse, 6), "RMSE": round(rmse, 4) }