valor-lite 0.33.7__py3-none-any.whl → 0.33.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
valor_lite/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Striveworks
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -3,11 +3,39 @@ from dataclasses import dataclass
3
3
 
4
4
  @dataclass
5
5
  class Classification:
6
+ """
7
+ Classification data structure containing a ground truth label and a list of predictions.
8
+
9
+ Parameters
10
+ ----------
11
+ uid : str
12
+ Unique identifier for the instance.
13
+ groundtruth : str
14
+ The true label for the instance.
15
+ predictions : list of str
16
+ List of predicted labels.
17
+ scores : list of float
18
+ Confidence scores corresponding to each predicted label.
19
+
20
+ Examples
21
+ --------
22
+ >>> classification = Classification(
23
+ ... uid='123',
24
+ ... groundtruth='cat',
25
+ ... predictions=['cat', 'dog', 'bird'],
26
+ ... scores=[0.9, 0.05, 0.05]
27
+ ... )
28
+ """
29
+
6
30
  uid: str
7
- groundtruths: list[tuple[str, str]]
8
- predictions: list[tuple[str, str]]
31
+ groundtruth: str
32
+ predictions: list[str]
9
33
  scores: list[float]
10
34
 
11
35
  def __post_init__(self):
36
+ if not isinstance(self.groundtruth, str):
37
+ raise ValueError(
38
+ "A classification must contain a single groundtruth."
39
+ )
12
40
  if len(self.predictions) != len(self.scores):
13
41
  raise ValueError("There must be a score per prediction label.")
@@ -3,28 +3,18 @@ from numpy.typing import NDArray
3
3
 
4
4
 
5
5
  def _compute_rocauc(
6
- data: NDArray[np.floating],
6
+ data: NDArray[np.float64],
7
7
  label_metadata: NDArray[np.int32],
8
8
  n_datums: int,
9
9
  n_labels: int,
10
- n_label_keys: int,
11
10
  mask_matching_labels: NDArray[np.bool_],
12
11
  pd_labels: NDArray[np.int32],
13
12
  ):
14
13
  """
15
14
  Compute ROCAUC and mean ROCAUC.
16
15
  """
17
- count_labels_per_key = np.bincount(label_metadata[:, 2])
18
- count_groundtruths_per_key = np.bincount(
19
- label_metadata[:, 2],
20
- weights=label_metadata[:, 0],
21
- minlength=n_label_keys,
22
- )
23
-
24
16
  positive_count = label_metadata[:, 0]
25
- negative_count = (
26
- count_groundtruths_per_key[label_metadata[:, 2]] - label_metadata[:, 0]
27
- )
17
+ negative_count = label_metadata[:, 1] - label_metadata[:, 0]
28
18
 
29
19
  true_positives = np.zeros((n_labels, n_datums), dtype=np.int32)
30
20
  false_positives = np.zeros_like(true_positives)
@@ -35,7 +25,6 @@ def _compute_rocauc(
35
25
  continue
36
26
 
37
27
  mask_pds = pd_labels == label_idx
38
-
39
28
  true_positives[label_idx] = mask_matching_labels[mask_pds]
40
29
  false_positives[label_idx] = ~mask_matching_labels[mask_pds]
41
30
  scores[label_idx] = data[mask_pds, 3]
@@ -70,32 +59,25 @@ def _compute_rocauc(
70
59
  rocauc = np.trapz(x=fpr, y=tpr, axis=1) # type: ignore - numpy will be switching to `trapezoid` in the future.
71
60
 
72
61
  # compute mean rocauc
73
- summed_rocauc = np.bincount(label_metadata[:, 2], weights=rocauc)
74
- mean_rocauc = np.zeros(n_label_keys, dtype=np.float64)
75
- np.divide(
76
- summed_rocauc,
77
- count_labels_per_key,
78
- where=count_labels_per_key > 1e-9,
79
- out=mean_rocauc,
80
- )
62
+ mean_rocauc = rocauc.mean()
81
63
 
82
64
  return rocauc, mean_rocauc
83
65
 
84
66
 
85
67
  def compute_metrics(
86
- data: NDArray[np.floating],
68
+ data: NDArray[np.float64],
87
69
  label_metadata: NDArray[np.int32],
88
- score_thresholds: NDArray[np.floating],
70
+ score_thresholds: NDArray[np.float64],
89
71
  hardmax: bool,
90
72
  n_datums: int,
91
73
  ) -> tuple[
92
74
  NDArray[np.int32],
93
- NDArray[np.floating],
94
- NDArray[np.floating],
95
- NDArray[np.floating],
96
- NDArray[np.floating],
97
- NDArray[np.floating],
98
- NDArray[np.floating],
75
+ NDArray[np.float64],
76
+ NDArray[np.float64],
77
+ NDArray[np.float64],
78
+ NDArray[np.float64],
79
+ NDArray[np.float64],
80
+ float,
99
81
  ]:
100
82
  """
101
83
  Computes classification metrics.
@@ -110,14 +92,14 @@ def compute_metrics(
110
92
 
111
93
  Parameters
112
94
  ----------
113
- data : NDArray[np.floating]
95
+ data : NDArray[np.float64]
114
96
  A sorted array of classification pairs.
115
97
  label_metadata : NDArray[np.int32]
116
98
  An array containing metadata related to labels.
117
- score_thresholds : NDArray[np.floating]
99
+ score_thresholds : NDArray[np.float64]
118
100
  A 1-D array contains score thresholds to compute metrics over.
119
101
  hardmax : bool
120
- Option to only allow a single positive prediction per label key.
102
+ Option to only allow a single positive prediction.
121
103
  n_datums : int
122
104
  The number of datums being operated over.
123
105
 
@@ -125,22 +107,21 @@ def compute_metrics(
125
107
  -------
126
108
  NDArray[np.int32]
127
109
  TP, FP, FN, TN counts.
128
- NDArray[np.floating]
110
+ NDArray[np.float64]
129
111
  Precision.
130
- NDArray[np.floating]
112
+ NDArray[np.float64]
131
113
  Recall.
132
- NDArray[np.floating]
114
+ NDArray[np.float64]
133
115
  Accuracy
134
- NDArray[np.floating]
116
+ NDArray[np.float64]
135
117
  F1 Score
136
- NDArray[np.floating]
118
+ NDArray[np.float64]
137
119
  ROCAUC.
138
- NDArray[np.floating]
120
+ float
139
121
  mROCAUC.
140
122
  """
141
123
 
142
124
  n_labels = label_metadata.shape[0]
143
- n_label_keys = np.unique(label_metadata[:, 2]).size
144
125
  n_scores = score_thresholds.shape[0]
145
126
 
146
127
  pd_labels = data[:, 2].astype(int)
@@ -155,7 +136,6 @@ def compute_metrics(
155
136
  label_metadata=label_metadata,
156
137
  n_datums=n_datums,
157
138
  n_labels=n_labels,
158
- n_label_keys=n_label_keys,
159
139
  mask_matching_labels=mask_matching_labels,
160
140
  pd_labels=pd_labels,
161
141
  )
@@ -229,16 +209,16 @@ def compute_metrics(
229
209
 
230
210
 
231
211
  def _count_with_examples(
232
- data: NDArray[np.floating],
212
+ data: NDArray[np.float64],
233
213
  unique_idx: int | list[int],
234
214
  label_idx: int | list[int],
235
- ) -> tuple[NDArray[np.floating], NDArray[np.int32], NDArray[np.int32]]:
215
+ ) -> tuple[NDArray[np.float64], NDArray[np.int32], NDArray[np.int32]]:
236
216
  """
237
217
  Helper function for counting occurences of unique detailed pairs.
238
218
 
239
219
  Parameters
240
220
  ----------
241
- data : NDArray[np.floating]
221
+ data : NDArray[np.float64]
242
222
  A masked portion of a detailed pairs array.
243
223
  unique_idx : int | list[int]
244
224
  The index or indices upon which uniqueness is constrained.
@@ -247,7 +227,7 @@ def _count_with_examples(
247
227
 
248
228
  Returns
249
229
  -------
250
- NDArray[np.floating]
230
+ NDArray[np.float64]
251
231
  Examples drawn from the data input.
252
232
  NDArray[np.int32]
253
233
  Unique label indices.
@@ -267,13 +247,12 @@ def _count_with_examples(
267
247
 
268
248
 
269
249
  def compute_confusion_matrix(
270
- data: NDArray[np.floating],
250
+ data: NDArray[np.float64],
271
251
  label_metadata: NDArray[np.int32],
272
- score_thresholds: NDArray[np.floating],
252
+ score_thresholds: NDArray[np.float64],
273
253
  hardmax: bool,
274
254
  n_examples: int,
275
- ) -> tuple[NDArray[np.floating], NDArray[np.int32]]:
276
-
255
+ ) -> tuple[NDArray[np.float64], NDArray[np.int32]]:
277
256
  """
278
257
  Compute detailed confusion matrix.
279
258
 
@@ -287,20 +266,20 @@ def compute_confusion_matrix(
287
266
 
288
267
  Parameters
289
268
  ----------
290
- data : NDArray[np.floating]
269
+ data : NDArray[np.float64]
291
270
  A sorted array summarizing the IOU calculations of one or more pairs.
292
271
  label_metadata : NDArray[np.int32]
293
272
  An array containing metadata related to labels.
294
- iou_thresholds : NDArray[np.floating]
273
+ iou_thresholds : NDArray[np.float64]
295
274
  A 1-D array containing IoU thresholds.
296
- score_thresholds : NDArray[np.floating]
275
+ score_thresholds : NDArray[np.float64]
297
276
  A 1-D array containing score thresholds.
298
277
  n_examples : int
299
278
  The maximum number of examples to return per count.
300
279
 
301
280
  Returns
302
281
  -------
303
- NDArray[np.floating]
282
+ NDArray[np.float64]
304
283
  Confusion matrix.
305
284
  NDArray[np.int32]
306
285
  Ground truths with missing predictions.