feat: enhance report generation with target name and content injection

- Added target_name parameter to Reports class for improved report context.
- Updated inject_content function to ensure proper handling of HTML sections.
- Modified DataManagerRepository to join predictions with training and validation data for accurate report generation.
This commit is contained in:
vitor-aignosi
2026-04-16 10:26:42 -03:00
parent 1e05ebe147
commit 8d4dc65aaa
2 changed files with 41 additions and 9 deletions

View File

@@ -2,7 +2,7 @@ import os
from collections.abc import Sequence from collections.abc import Sequence
from typing import Any from typing import Any
from bs4 import BeautifulSoup from bs4 import BeautifulSoup, Tag
from evidently.metric_preset import DataDriftPreset from evidently.metric_preset import DataDriftPreset
from evidently.metrics import ( from evidently.metrics import (
ColumnSummaryMetric, ColumnSummaryMetric,
@@ -20,6 +20,7 @@ from evidently.metrics import (
from evidently.metrics.base_metric import generate_column_metrics from evidently.metrics.base_metric import generate_column_metrics
from evidently.options import ColorOptions from evidently.options import ColorOptions
from evidently.report import Report from evidently.report import Report
from evidently.pipeline.column_mapping import ColumnMapping
COLOR_DISCRETE_SEQUENCE = ( COLOR_DISCRETE_SEQUENCE = (
'#ed0400', '#ed0400',
@@ -44,9 +45,14 @@ def load_html_from_file(file_path):
def inject_content(main_html, section_id, content): def inject_content(main_html, section_id, content):
soup = BeautifulSoup(main_html, 'html.parser') soup = BeautifulSoup(main_html, 'html.parser')
section = soup.find(id=section_id) section = soup.find(id=section_id)
if section:
# Verifica se a seção foi encontrada E se ela é uma Tag (não uma string)
if section and isinstance(section, Tag):
section.clear() section.clear()
section.append(BeautifulSoup(content, 'html.parser')) # Converte o conteúdo para um fragmento de BeautifulSoup e anexa
new_content = BeautifulSoup(content, 'html.parser')
section.append(new_content)
return str(soup) return str(soup)
@@ -68,7 +74,7 @@ class Reports:
""" """
def __init__( def __init__(
self, reference_data: Any, current_data: Any, base_path: str | None = None self, reference_data: Any, current_data: Any, target_name: str, base_path: str | None = None
) -> None: ) -> None:
""" """
Initializes an instance of the AigReport class. Initializes an instance of the AigReport class.
@@ -84,6 +90,7 @@ class Reports:
self.report: Any = None self.report: Any = None
self.ref_data = reference_data self.ref_data = reference_data
self.cur_data = current_data self.cur_data = current_data
self.target_name = target_name
self.set_color_options(primary_color='#0F4C81', secondary_color='#001E60') self.set_color_options(primary_color='#0F4C81', secondary_color='#001E60')
self.base_path = base_path self.base_path = base_path
@@ -145,8 +152,17 @@ class Reports:
] ]
self.metrics.extend(metrics) self.metrics.extend(metrics)
if run: if run:
mapping = ColumnMapping()
mapping.target = self.target_name
mapping.prediction = 'prediction'
report = Report(metrics=metrics, options=self.options) report = Report(metrics=metrics, options=self.options)
report.run(reference_data=self.ref_data, current_data=self.cur_data) report.run(
reference_data=self.ref_data,
current_data=self.cur_data,
column_mapping=mapping,
)
self.sections['regression'] = report.as_dict() self.sections['regression'] = report.as_dict()
if self.base_path: if self.base_path:
# Note: Relies on Evidently's save_html() to properly manage file I/O # Note: Relies on Evidently's save_html() to properly manage file I/O

View File

@@ -511,11 +511,26 @@ class DataManagerRepository(SientiaMonitoring):
if data.run_name is None: if data.run_name is None:
raise ValueError('run_name is not set, cannot generate report') raise ValueError('run_name is not set, cannot generate report')
# Convert data to float64 for report generation if data.y_train_pred is None or data.y_pred is None:
# This may raise ValueError if data contains non-numeric values raise ValueError('y_train_pred or y_pred is not set, cannot generate report')
reference_data = data.train_data
current_data = data.val_data
y_train_pred = data.y_train_pred.rename(
columns={data.params.target_variable: 'prediction'}
)
y_val_pred = data.y_pred.rename(
columns={data.params.target_variable: 'prediction'}
)
# Join the predictions to the data
reference_data = y_train_pred[['prediction']].join(
data.train_data, how='inner'
)
reference_data_float = reference_data.astype(np.float64) reference_data_float = reference_data.astype(np.float64)
current_data = y_val_pred[['prediction']].join(
data.val_data, how='inner'
)
current_data_float = current_data.astype(np.float64) current_data_float = current_data.astype(np.float64)
# Initialize report generator # Initialize report generator
@@ -524,6 +539,7 @@ class DataManagerRepository(SientiaMonitoring):
reference_data=reference_data_float, reference_data=reference_data_float,
current_data=current_data_float, current_data=current_data_float,
base_path=data.run_dir, base_path=data.run_dir,
target_name=data.params.target_variable,
) )
# Generate report sections # Generate report sections