Last active
November 24, 2023 10:25
-
-
Save RagingTiger/9f8dbc5327d6a761497633417aa74c5d to your computer and use it in GitHub Desktop.
Example Solution from Bnomial: A Model's Recall
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
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