Skip to content

Commit 6a5bb22

Browse files
authored
Merge pull request #1411 from Giskard-AI/task/GSK-1765
Improve reporting on robustness/ethical issues [GSK-1765]
2 parents 4a1e2da + 1dab597 commit 6a5bb22

1 file changed

Lines changed: 24 additions & 8 deletions

File tree

giskard/scanner/robustness/base_detector.py

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -134,26 +134,26 @@ def _detect_issues(
134134
# Severity
135135
issue_level = IssueLevel.MAJOR if fail_rate >= 2 * threshold else IssueLevel.MEDIUM
136136

137-
# Prepare examples dataframe
138-
examples = original_data.df.loc[~passed, (feature,)].copy()
139-
examples[f"{transformation_fn.name}({feature})"] = perturbed_data.df.loc[~passed, feature]
140-
examples["Original prediction"] = original_pred.prediction[~passed]
141-
examples["Prediction after perturbation"] = perturbed_pred.prediction[~passed]
142-
143137
# Description
144138
desc = "When we perturb the content of feature “{feature}” with the transformation “{transformation_fn}” (see examples below), your model changes its prediction in about {fail_rate_percent}% of the cases. We expected the predictions not to be affected by this transformation."
145139

140+
failed_size = (~passed).sum()
141+
slice_size = len(passed)
142+
146143
issue = Issue(
147144
model,
148145
dataset,
149146
group=self._issue_group,
150147
level=issue_level,
151148
transformation_fn=transformation_fn,
152149
description=desc,
150+
features=[feature],
153151
meta={
154152
"feature": feature,
155153
"domain": f"Feature `{feature}`",
156-
"deviation": f"{round(fail_rate * 100, 2)}% of tested samples changed prediction after perturbation",
154+
"deviation": f"{failed_size}/{slice_size} tested samples ({round(fail_rate * 100, 2)}%) changed prediction after perturbation",
155+
"failed_size": failed_size,
156+
"slice_size": slice_size,
157157
"fail_rate": fail_rate,
158158
"fail_rate_percent": round(fail_rate * 100, 2),
159159
"metric": "Fail rate",
@@ -164,10 +164,26 @@ def _detect_issues(
164164
"perturbed_data_slice_predictions": perturbed_pred,
165165
},
166166
importance=fail_rate,
167-
examples=examples,
168167
tests=_generate_robustness_tests,
169168
)
170169

170+
# Add examples
171+
examples = original_data.df.loc[~passed, (feature,)].copy()
172+
examples[f"{transformation_fn.name}({feature})"] = perturbed_data.df.loc[~passed, feature]
173+
174+
examples["Original prediction"] = original_pred.prediction[~passed]
175+
examples["Prediction after perturbation"] = perturbed_pred.prediction[~passed]
176+
177+
if model.is_classification:
178+
examples["Original prediction"] = examples["Original prediction"].astype(str)
179+
examples["Prediction after perturbation"] = examples["Prediction after perturbation"].astype(str)
180+
ps_before = pd.Series(original_pred.probabilities[~passed], index=examples.index)
181+
ps_after = pd.Series(perturbed_pred.probabilities[~passed], index=examples.index)
182+
examples["Original prediction"] += ps_before.apply(lambda p: f" (p = {p:.2f})")
183+
examples["Prediction after perturbation"] += ps_after.apply(lambda p: f" (p = {p:.2f})")
184+
185+
issue.add_examples(examples)
186+
171187
issues.append(issue)
172188

173189
return issues

0 commit comments

Comments
 (0)