Skip to content

Commit 386de9b

Browse files
fix: Fairness metrics and tests
1 parent 150cf01 commit 386de9b

File tree

8 files changed

+63
-10030
lines changed

8 files changed

+63
-10030
lines changed
Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
from typing import Callable
22
import numpy as np
3+
from sklearn.metrics import confusion_matrix
34

45
def filter_rows_by_inputs(data: np.ndarray, filter_func: Callable[[np.ndarray], bool]):
56
return data[np.apply_along_axis(filter_func, 1, data)]
67

78
def calculate_confusion_matrix(test: np.array, truth: np.array, positive_class: int) -> dict:
8-
tp = np.sum((test == positive_class) & (truth == positive_class))
9-
tn = np.sum((test != positive_class) & (truth != positive_class))
10-
fp = np.sum((test == positive_class) & (truth != positive_class))
11-
fn = np.sum((test != positive_class) & (truth == positive_class))
12-
return {"tp": tp, "tn": tn, "fp": fp, "fn": fn}
9+
# cast test and truth to int
10+
test = test.astype(int)
11+
truth = truth.astype(int)
12+
# calculate confusion matrix
13+
cm = confusion_matrix(truth, test, labels=[positive_class, 1 - positive_class])
14+
tp = cm[0, 0]
15+
fn = cm[0, 1]
16+
fp = cm[1, 0]
17+
tn = cm[1, 1]
18+
return {"tp": tp, "tn": tn, "fp": fp, "fn": fn}

src/core/metrics/fairness/group/disparate_impact_ratio.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# pylint: disable=line-too-long
2-
from typing import List, Any, Union
2+
from typing import List, Union
33

44
import numpy as np
5+
from sklearn.base import ClassifierMixin
56

67
class DisparateImpactRatio:
78
"""
@@ -10,7 +11,7 @@ class DisparateImpactRatio:
1011
@staticmethod
1112
def calculate_model(
1213
samples: np.ndarray,
13-
model: Any,
14+
model: ClassifierMixin,
1415
privilege_columns: List[int],
1516
privilege_values: List[int],
1617
favorable_output: np.ndarray

src/core/metrics/fairness/group/group_average_odds_difference.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# pylint: disable=line-too-long, too-many-arguments
2-
from typing import List, Any
2+
from typing import List
33

44
import numpy as np
5+
from sklearn.base import ClassifierMixin
56

67
from src.core.metrics.fairness.fairness_metrics_utils import filter_rows_by_inputs, calculate_confusion_matrix
78

@@ -12,7 +13,7 @@ class GroupAverageOddsDifference:
1213
@ staticmethod
1314
def calculate_model(
1415
samples: np.ndarray,
15-
model: Any,
16+
model: ClassifierMixin,
1617
privilege_columns: List[int],
1718
privilege_values: List[int],
1819
postive_class: List[int],

src/core/metrics/fairness/group/group_average_predictive_value_difference.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# pylint: disable=line-too-long, too-many-arguments
2-
from typing import List, Any
2+
from typing import List
33

44
import numpy as np
5+
from sklearn.base import ClassifierMixin
56

67
from src.core.metrics.fairness.fairness_metrics_utils import filter_rows_by_inputs, calculate_confusion_matrix
78

@@ -12,7 +13,7 @@ class GroupAveragePredictiveValueDifference:
1213
@staticmethod
1314
def calculate_model(
1415
samples: np.ndarray,
15-
model: Any,
16+
model: ClassifierMixin,
1617
privilege_columns: List[int],
1718
privilege_values: List[int],
1819
positive_class: int,

src/core/metrics/fairness/group/group_statistical_parity_difference.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from typing import List
33

44
import numpy as np
5+
from sklearn.base import ClassifierMixin
56

67
class GroupStatisticalParityDifference:
78
"""
@@ -10,7 +11,7 @@ class GroupStatisticalParityDifference:
1011
@staticmethod
1112
def calculate_model(
1213
samples: np.ndarray,
13-
model,
14+
model: ClassifierMixin,
1415
privilege_columns: List[int],
1516
privilege_values: List[int],
1617
favorable_output,

src/core/metrics/fairness/individual/individual_consistency.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from typing import Any
33

44
import numpy as np
5+
from sklearn.base import ClassifierMixin
56

67
class IndividualConsistency:
78
"""
@@ -15,21 +16,23 @@ class IndividualConsistency:
1516
def calculate(
1617
proximity_function: Any,
1718
samples: np.ndarray,
18-
prediction_provider: Any
19+
model: ClassifierMixin
1920
) -> float:
2021
"""
2122
Calculate individual fairness.
2223
:param proximity_function: a function that finds the top k similar inputs, given a reference input and a list of inputs
23-
:param samples a list of inputs to be tested for consistency
24-
:param prediction_provider the model under inspection
24+
:param samples: a list of inputs to be tested for consistency
25+
:param model: the model under inspection
2526
return the consistency measure
2627
"""
2728
consistency = 1
2829
for sample in samples:
29-
prediction_outputs = prediction_provider.predict(sample)
30+
prediction_outputs = model.predict(sample)
31+
if len(prediction_outputs) == 0:
32+
raise ValueError("Model output cannot be empty.")
3033
prediction_output = prediction_outputs[0]
3134
neighbors = proximity_function(sample, samples)
32-
neighbors_outputs = prediction_provider.predict(neighbors)
35+
neighbors_outputs = model.predict(neighbors)
3336
for output in prediction_outputs:
3437
for neighbor_output in neighbors_outputs:
3538
if neighbor_output != output:

0 commit comments

Comments
 (0)