Skip to content

Instantly share code, notes, and snippets.

@DiogenesAnalytics
Forked from RagingTiger/a_models_recall.py
Created November 24, 2023 10:25
Show Gist options
  • Save DiogenesAnalytics/3a8c1959e157f5a0d0865aba89a06e45 to your computer and use it in GitHub Desktop.
Save DiogenesAnalytics/3a8c1959e157f5a0d0865aba89a06e45 to your computer and use it in GitHub Desktop.
Example Solution from Bnomial: A Model's Recall
"""
bnomial: 10/16/2023
A team built a binary classification model. They named the classes A and B.
After finishing training, they evaluated the model on a validation set, and
here is the confusion matrix with the results:
A B
┌────┬────┐
A│ 52 │ 7 │
├────┼────┤
B│ 13 │ 28 │
└────┴────┘
Given the above confusion matrix, what of the following correctly represents
the model's recall predicting classes A and B, respectively:
+ The model's recall predicting class A is 80%, and class B is 80%.
+ The model's recall predicting class A is 88%, and class B is 68%.
+ The model's recall predicting class A is 88%, and class B is 88%.
+ The model's recall predicting class A is 68%, and class B is 88%.
"""
from dataclasses import dataclass
from typing import Tuple
@dataclass
class ConfusionMatrix:
"""2 x 2 confusion matrix class."""
matrix: Tuple[Tuple[int, int], Tuple[int, int]]
def __post_init__(self):
"""Create nice pointers to the different class combos."""
self.AA = self.matrix[0][0]
self.AB = self.matrix[1][0]
self.BA = self.matrix[0][1]
self.BB = self.matrix[1][1]
def _class_a_recall(self) -> float:
"""Calculate the recall for class A."""
return self.AA / (self.AA + self.BA)
def _class_b_recall(self) -> float:
"""Calculate the recall for class B."""
return self.BB / (self.AB + self.BB)
def _recall(self) -> Tuple[float, float]:
"""Calculate entire recall for both class A and B."""
return (self._class_a_recall(), self._class_b_recall())
def recall(self) -> None:
"""Pretty print the results from the _recall method."""
# create format string
fmt = "Class A recall: {0} / Class B recall: {1}"
# now print
print(fmt.format(*self.recall()))
def _class_a_precision(self) -> float:
"""Calculate the precision for class A."""
return self.AA / (self.AA + self.AB)
def _class_b_precision(self) -> float:
"""Calculate the precision for class B."""
return self.BB / (self.BB + self.BA)
def _class_a_f1_score(self) -> float:
"""Calculate f1 score for class A."""
precision = self._class_a_precision()
recall = self._class_a_recall()
return 2 * precision * recall / (precision + recall)
def _class_b_f1_score(self) -> float:
"""Calculate f1 score for class B."""
precision = self._class_b_precision()
recall = self._class_b_recall()
return 2 * precision * recall / (precision + recall)
def _f1_score(self) -> Tuple[float, float]:
"""Calculate f1 scores for both class A and B."""
return (self._class_a_f1_score(), self._class_b_f1_score())
def f1_score(self) -> None:
"""Pretty print the results from the _f1_score method."""
# create format string
fmt = "Class A F1 Score: {0} / Class B F1 Score: {1}"
# now print
print(fmt.format(*self._f1_score()))
# executable
if __name__ == "__main__":
# setup rows and columns
matrix = ((52, 7), (13, 28))
# setup confusion matrix instance
confuse_matrix = ConfusionMatrix(matrix)
# now print recall results
confuse_matrix.results()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment