John Graham Reynolds commited on
Commit
677fc21
·
1 Parent(s): 495a21f

add precision file

Browse files
Files changed (2) hide show
  1. __init__.py +5 -0
  2. fixed_precision.py +72 -0
__init__.py ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ from fixed_precision import FixedPrecision
2
+
3
+ __all__ =[
4
+ "FixedPrecision"
5
+ ]
fixed_precision.py ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import datasets
2
+ import evaluate
3
+ # from evaluate.metrics.precision import Precision
4
+ from sklearn.metrics import precision_score
5
+
6
+ _DESCRIPTION = """
7
+ Custom built Precision metric that accepts underlying kwargs at instantiation time.
8
+ This class allows one to circumvent the current issue of `combine`-ing the precision metric, instantiated with its own parameters, into a `CombinedEvaluations` class with other metrics.
9
+ \n
10
+ In general, the precision is the ratio tp / (tp + fp) where tp is the number of true positives and fp the number of false positives.
11
+ The precision is intuitively the ability of the classifier not to label as positive a sample that is negative.
12
+ """
13
+
14
+ _CITATION = """
15
+ @online{MarioBbqPrec,
16
+ author = {John Graham Reynolds aka @MarioBarbeque},
17
+ title = {{Fixed Precision Hugging Face Metric},
18
+ year = 2024,
19
+ url = {https://huggingface.co/spaces/MarioBarbeque/FixedPrecision},
20
+ urldate = {2024-11-6}
21
+ }
22
+ """
23
+
24
+ _INPUTS = """
25
+ 'average': This parameter is required for multiclass/multilabel targets.
26
+ If None, the scores for each class are returned. Otherwise, this determines the type of averaging performed on the data.
27
+ Options include: {‘micro’, ‘macro’, ‘samples’, ‘weighted’, ‘binary’} or `None`. The default value for binary classification is `"binary"`.\n
28
+
29
+ 'zero_division': "Sets the value to return when there is a zero division". Options include:
30
+ {`“warn”`, `0.0`, `1.0`, `np.nan`}. The default value is `"warn"`.
31
+ """
32
+
33
+ # could in principle subclass Precision, but ideally we can work the fix into the Precision class to maintain SOLID code
34
+ # for this immediate fix we create a new class
35
+
36
+ class FixedPrecision(evaluate.Metric):
37
+
38
+ def __init__(self, average="binary", zero_division="warn"):
39
+ super().__init__()
40
+ self.average = average
41
+ self.zero_division = zero_division
42
+ # additional values passed to compute() could and probably should (?) all be passed here so that the final computation is configured immediately at Metric instantiation
43
+
44
+ def _info(self):
45
+ return evaluate.MetricInfo(
46
+ description=_DESCRIPTION,
47
+ citation=_CITATION,
48
+ inputs_description=_INPUTS,
49
+ features=datasets.Features(
50
+ {
51
+ "predictions": datasets.Sequence(datasets.Value("int32")),
52
+ "references": datasets.Sequence(datasets.Value("int32")),
53
+ }
54
+ if self.config_name == "multilabel"
55
+ else {
56
+ "predictions": datasets.Value("int32"),
57
+ "references": datasets.Value("int32"),
58
+ }
59
+ ),
60
+ reference_urls=["https://scikit-learn.org/stable/modules/generated/sklearn.metrics.precision_score.html"],
61
+ )
62
+
63
+ # could remove specific kwargs like average, sample_weight from _compute() method and simply pass them to the underlying scikit-learn function in the form of a class var self.*
64
+ # but leaving for sake of potentially subclassing Precision
65
+
66
+ def _compute(
67
+ self, predictions, references, labels=None, pos_label=1, average="binary", sample_weight=None, zero_division="warn",
68
+ ):
69
+ score = precision_score(
70
+ references, predictions, labels=labels, pos_label=pos_label, average=self.average, sample_weight=sample_weight, zero_division=self.zero_division,
71
+ )
72
+ return {"precision": float(score) if score.size == 1 else score}