dataeval 0.69.4__py3-none-any.whl → 0.70.1__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.
Files changed (66) hide show
  1. dataeval/__init__.py +8 -8
  2. dataeval/_internal/datasets.py +235 -131
  3. dataeval/_internal/detectors/clusterer.py +2 -0
  4. dataeval/_internal/detectors/drift/base.py +7 -8
  5. dataeval/_internal/detectors/drift/mmd.py +4 -4
  6. dataeval/_internal/detectors/duplicates.py +64 -45
  7. dataeval/_internal/detectors/merged_stats.py +23 -54
  8. dataeval/_internal/detectors/ood/ae.py +8 -6
  9. dataeval/_internal/detectors/ood/aegmm.py +6 -4
  10. dataeval/_internal/detectors/ood/base.py +12 -7
  11. dataeval/_internal/detectors/ood/llr.py +6 -4
  12. dataeval/_internal/detectors/ood/vae.py +5 -3
  13. dataeval/_internal/detectors/ood/vaegmm.py +6 -4
  14. dataeval/_internal/detectors/outliers.py +137 -63
  15. dataeval/_internal/interop.py +11 -7
  16. dataeval/_internal/metrics/balance.py +13 -11
  17. dataeval/_internal/metrics/ber.py +5 -3
  18. dataeval/_internal/metrics/coverage.py +4 -0
  19. dataeval/_internal/metrics/divergence.py +9 -5
  20. dataeval/_internal/metrics/diversity.py +14 -12
  21. dataeval/_internal/metrics/parity.py +32 -22
  22. dataeval/_internal/metrics/stats/base.py +231 -0
  23. dataeval/_internal/metrics/stats/boxratiostats.py +159 -0
  24. dataeval/_internal/metrics/stats/datasetstats.py +99 -0
  25. dataeval/_internal/metrics/stats/dimensionstats.py +113 -0
  26. dataeval/_internal/metrics/stats/hashstats.py +75 -0
  27. dataeval/_internal/metrics/stats/labelstats.py +125 -0
  28. dataeval/_internal/metrics/stats/pixelstats.py +119 -0
  29. dataeval/_internal/metrics/stats/visualstats.py +124 -0
  30. dataeval/_internal/metrics/uap.py +8 -4
  31. dataeval/_internal/metrics/utils.py +30 -15
  32. dataeval/_internal/models/pytorch/autoencoder.py +5 -5
  33. dataeval/_internal/models/tensorflow/pixelcnn.py +1 -4
  34. dataeval/_internal/output.py +3 -18
  35. dataeval/_internal/utils.py +11 -16
  36. dataeval/_internal/workflows/sufficiency.py +152 -151
  37. dataeval/detectors/__init__.py +4 -0
  38. dataeval/detectors/drift/__init__.py +8 -3
  39. dataeval/detectors/drift/kernels/__init__.py +4 -0
  40. dataeval/detectors/drift/updates/__init__.py +4 -0
  41. dataeval/detectors/linters/__init__.py +15 -4
  42. dataeval/detectors/ood/__init__.py +14 -2
  43. dataeval/metrics/__init__.py +5 -0
  44. dataeval/metrics/bias/__init__.py +13 -4
  45. dataeval/metrics/estimators/__init__.py +8 -8
  46. dataeval/metrics/stats/__init__.py +25 -3
  47. dataeval/utils/__init__.py +16 -3
  48. dataeval/utils/tensorflow/__init__.py +11 -0
  49. dataeval/utils/torch/__init__.py +12 -0
  50. dataeval/utils/torch/datasets/__init__.py +7 -0
  51. dataeval/workflows/__init__.py +6 -2
  52. {dataeval-0.69.4.dist-info → dataeval-0.70.1.dist-info}/METADATA +12 -4
  53. dataeval-0.70.1.dist-info/RECORD +80 -0
  54. {dataeval-0.69.4.dist-info → dataeval-0.70.1.dist-info}/WHEEL +1 -1
  55. dataeval/_internal/flags.py +0 -77
  56. dataeval/_internal/metrics/stats.py +0 -397
  57. dataeval/flags/__init__.py +0 -3
  58. dataeval/tensorflow/__init__.py +0 -3
  59. dataeval/torch/__init__.py +0 -3
  60. dataeval-0.69.4.dist-info/RECORD +0 -74
  61. /dataeval/{tensorflow → utils/tensorflow}/loss/__init__.py +0 -0
  62. /dataeval/{tensorflow → utils/tensorflow}/models/__init__.py +0 -0
  63. /dataeval/{tensorflow → utils/tensorflow}/recon/__init__.py +0 -0
  64. /dataeval/{torch → utils/torch}/models/__init__.py +0 -0
  65. /dataeval/{torch → utils/torch}/trainer/__init__.py +0 -0
  66. {dataeval-0.69.4.dist-info → dataeval-0.70.1.dist-info}/LICENSE.txt +0 -0
@@ -61,9 +61,9 @@ class AETrainer:
61
61
  List[float]
62
62
  A list of average loss values for each epoch.
63
63
 
64
- Notes
64
+ Note
65
65
  ----
66
- To replace this function with a custom function, do
66
+ To replace this function with a custom function, do:
67
67
  AETrainer.train = custom_function
68
68
  """
69
69
  # Setup training
@@ -120,7 +120,7 @@ class AETrainer:
120
120
 
121
121
  Note
122
122
  ----
123
- To replace this function with a custom function, do
123
+ To replace this function with a custom function, do:
124
124
  AETrainer.eval = custom_function
125
125
  """
126
126
  self.model.eval()
@@ -155,8 +155,8 @@ class AETrainer:
155
155
  torch.Tensor
156
156
  Data encoded by the model
157
157
 
158
- Notes
159
- -----
158
+ Note
159
+ ----
160
160
  This function should be run after the model has been trained and evaluated.
161
161
  """
162
162
  self.model.eval()
@@ -272,8 +272,6 @@ class PixelCNN(distribution.Distribution):
272
272
  The minimum value of the input data.
273
273
  dtype : tensorflow dtype, default tf.float32
274
274
  Data type of the `Distribution`.
275
- name : str, default "PixelCNN"
276
- The name of the `Distribution`.
277
275
  """
278
276
 
279
277
  def __init__(
@@ -293,10 +291,9 @@ class PixelCNN(distribution.Distribution):
293
291
  high: int = 255,
294
292
  low: int = 0,
295
293
  dtype=tf.float32,
296
- name: str = "PixelCNN",
297
294
  ) -> None:
298
295
  parameters = dict(locals())
299
- with tf.name_scope(name) as name:
296
+ with tf.name_scope("PixelCNN") as name:
300
297
  super().__init__(
301
298
  dtype=dtype,
302
299
  reparameterization_type=reparameterization.NOT_REPARAMETERIZED,
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  import inspect
4
4
  from datetime import datetime, timezone
5
5
  from functools import wraps
6
+ from typing import Any
6
7
 
7
8
  import numpy as np
8
9
 
@@ -17,10 +18,10 @@ class OutputMetadata:
17
18
  _state: dict[str, str]
18
19
  _version: str
19
20
 
20
- def dict(self) -> dict:
21
+ def dict(self) -> dict[str, Any]:
21
22
  return {k: v for k, v in self.__dict__.items() if not k.startswith("_")}
22
23
 
23
- def meta(self) -> dict:
24
+ def meta(self) -> dict[str, Any]:
24
25
  return {k.removeprefix("_"): v for k, v in self.__dict__.items() if k.startswith("_")}
25
26
 
26
27
 
@@ -67,19 +68,3 @@ def set_metadata(module_name: str = "", state_attr: list[str] | None = None):
67
68
  return wrapper
68
69
 
69
70
  return decorator
70
-
71
-
72
- def populate_defaults(d: dict, c: type) -> dict:
73
- def default(t):
74
- t = (
75
- t if isinstance(t, str) else t._name if hasattr(t, "_name") else t.__name__
76
- ).lower() # py3.9 : _name, py3.10 : __name__
77
- if t.startswith("dict"):
78
- return {}
79
- if t.startswith("list"):
80
- return []
81
- if t.startswith("ndarray"):
82
- return np.array([])
83
- raise TypeError("Unrecognized annotation type")
84
-
85
- return {k: d[k] if k in d else default(t) for k, t in c.__annotations__.items()}
@@ -8,7 +8,7 @@ from torch.utils.data import Dataset
8
8
 
9
9
  def read_dataset(dataset: Dataset) -> list[list[Any]]:
10
10
  """
11
- Extract information from a dataset at each index into a individual lists of each information position
11
+ Extract information from a dataset at each index into individual lists of each information position
12
12
 
13
13
  Parameters
14
14
  ----------
@@ -31,36 +31,31 @@ def read_dataset(dataset: Dataset) -> list[list[Any]]:
31
31
  Examples
32
32
  --------
33
33
  >>> import numpy as np
34
-
35
- >>> data = np.ones((10, 3, 3))
34
+ >>> data = np.ones((10, 1, 3, 3))
36
35
  >>> labels = np.ones((10,))
37
36
  >>> class ICDataset:
38
37
  ... def __init__(self, data, labels):
39
38
  ... self.data = data
40
39
  ... self.labels = labels
41
-
40
+ ...
42
41
  ... def __getitem__(self, idx):
43
42
  ... return self.data[idx], self.labels[idx]
44
43
 
45
44
  >>> ds = ICDataset(data, labels)
46
45
 
47
46
  >>> result = read_dataset(ds)
48
- >>> assert len(result) == 2
49
- True
50
- >>> assert result[0].shape == (10, 3, 3) # 10 3x3 images
51
- True
52
- >>> assert result[1].shape == (10,) # 10 labels
53
- True
47
+ >>> len(result) # images and labels
48
+ 2
49
+ >>> np.asarray(result[0]).shape # images
50
+ (10, 1, 3, 3)
51
+ >>> np.asarray(result[1]).shape # labels
52
+ (10,)
54
53
  """
55
54
 
56
- ddict: dict[int, list] = defaultdict(list)
55
+ ddict: dict[int, list[Any]] = defaultdict(list[Any])
57
56
 
58
57
  for data in dataset:
59
- # Convert to tuple if single return (e.g. images only)
60
- if not isinstance(data, tuple):
61
- data = (data,)
62
-
63
- for i, d in enumerate(data):
58
+ for i, d in enumerate(data if isinstance(data, tuple) else (data,)):
64
59
  ddict[i].append(d)
65
60
 
66
61
  return list(ddict.values())
@@ -2,23 +2,26 @@ from __future__ import annotations
2
2
 
3
3
  import warnings
4
4
  from dataclasses import dataclass
5
- from typing import Any, Callable, Sequence, cast
5
+ from typing import Any, Callable, Iterable, Mapping, Sequence, cast
6
6
 
7
7
  import matplotlib.pyplot as plt
8
8
  import numpy as np
9
9
  import torch
10
10
  import torch.nn as nn
11
11
  from matplotlib.figure import Figure
12
- from numpy.typing import NDArray
12
+ from numpy.typing import ArrayLike, NDArray
13
13
  from scipy.optimize import basinhopping
14
14
  from torch.utils.data import Dataset
15
15
 
16
+ from dataeval._internal.interop import as_numpy
16
17
  from dataeval._internal.output import OutputMetadata, set_metadata
17
18
 
18
19
 
19
20
  @dataclass(frozen=True)
20
21
  class SufficiencyOutput(OutputMetadata):
21
22
  """
23
+ Output class for :class:`Sufficiency` workflow
24
+
22
25
  Attributes
23
26
  ----------
24
27
  steps : NDArray
@@ -42,6 +45,130 @@ class SufficiencyOutput(OutputMetadata):
42
45
  if c != c_v:
43
46
  raise ValueError(f"{m} does not contain the expected number ({c}) of data points.")
44
47
 
48
+ @set_metadata("dataeval.workflows.SufficiencyOutput")
49
+ def project(
50
+ self,
51
+ projection: int | Iterable[int],
52
+ ) -> SufficiencyOutput:
53
+ """Projects the measures for each value of X
54
+
55
+ Parameters
56
+ ----------
57
+ projection : int | Iterable[int]
58
+ Step or steps to project
59
+
60
+ Returns
61
+ -------
62
+ SufficiencyOutput
63
+ Dataclass containing the projected measures per projection
64
+
65
+ Raises
66
+ ------
67
+ ValueError
68
+ If the length of data points in the measures do not match
69
+ If `projection` is not numerical
70
+ """
71
+ projection = np.asarray(list(projection) if isinstance(projection, Iterable) else [projection])
72
+
73
+ if not np.issubdtype(projection.dtype, np.number):
74
+ raise ValueError("'projection' must consist of numerical values")
75
+
76
+ output = {}
77
+ for name, measures in self.measures.items():
78
+ if measures.ndim > 1:
79
+ result = []
80
+ for i in range(len(measures)):
81
+ projected = project_steps(self.params[name][i], projection)
82
+ result.append(projected)
83
+ output[name] = np.array(result)
84
+ else:
85
+ output[name] = project_steps(self.params[name], projection)
86
+ return SufficiencyOutput(projection, self.params, output)
87
+
88
+ def plot(self, class_names: Sequence[str] | None = None) -> list[Figure]:
89
+ """Plotting function for data sufficiency tasks
90
+
91
+ Parameters
92
+ ----------
93
+ class_names : Sequence[str] | None, default None
94
+ List of class names
95
+
96
+ Returns
97
+ -------
98
+ list[plt.Figure]
99
+ List of Figures for each measure
100
+
101
+ Raises
102
+ ------
103
+ ValueError
104
+ If the length of data points in the measures do not match
105
+ """
106
+ # Extrapolation parameters
107
+ last_X = self.steps[-1]
108
+ geomshape = (0.01 * last_X, last_X * 4, len(self.steps))
109
+ extrapolated = np.geomspace(*geomshape).astype(np.int64)
110
+
111
+ # Stores all plots
112
+ plots = []
113
+
114
+ # Create a plot for each measure on one figure
115
+ for name, measures in self.measures.items():
116
+ if measures.ndim > 1:
117
+ if class_names is not None and len(measures) != len(class_names):
118
+ raise IndexError("Class name count does not align with measures")
119
+ for i, measure in enumerate(measures):
120
+ class_name = str(i) if class_names is None else class_names[i]
121
+ fig = plot_measure(
122
+ f"{name}_{class_name}",
123
+ self.steps,
124
+ measure,
125
+ self.params[name][i],
126
+ extrapolated,
127
+ )
128
+ plots.append(fig)
129
+
130
+ else:
131
+ fig = plot_measure(name, self.steps, measures, self.params[name], extrapolated)
132
+ plots.append(fig)
133
+
134
+ return plots
135
+
136
+ def inv_project(self, targets: Mapping[str, ArrayLike]) -> dict[str, NDArray[np.float64]]:
137
+ """
138
+ Calculate training samples needed to achieve target model metric values.
139
+
140
+ Parameters
141
+ ----------
142
+ targets : Mapping[str, ArrayLike]
143
+ Mapping of target metric scores (from 0.0 to 1.0) that we want
144
+ to achieve, where the key is the name of the metric.
145
+
146
+ Returns
147
+ -------
148
+ dict[str, NDArray]
149
+ List of the number of training samples needed to achieve each
150
+ corresponding entry in targets
151
+ """
152
+
153
+ projection = {}
154
+
155
+ for name, target in targets.items():
156
+ tarray = as_numpy(target)
157
+ if name not in self.measures:
158
+ continue
159
+
160
+ measure = self.measures[name]
161
+ if measure.ndim > 1:
162
+ projection[name] = np.zeros((len(measure), len(tarray)))
163
+ for i in range(len(measure)):
164
+ projection[name][i] = inv_project_steps(
165
+ self.params[name][i], tarray[i] if tarray.ndim == measure.ndim else tarray
166
+ )
167
+ else:
168
+ projection[name] = inv_project_steps(self.params[name], tarray)
169
+
170
+ return projection
171
+
45
172
 
46
173
  def f_out(n_i: NDArray, x: NDArray) -> NDArray:
47
174
  """
@@ -256,18 +383,18 @@ class Sufficiency:
256
383
  Function which takes a model (torch.nn.Module), a dataset
257
384
  (torch.utils.data.Dataset), indices to train on and executes model
258
385
  training against the data.
259
- eval_fn : Callable[[nn.Module, Dataset], Dict[str, float | NDArray]]
386
+ eval_fn : Callable[[nn.Module, Dataset], Mapping[str, float | ArrayLike]]
260
387
  Function which takes a model (torch.nn.Module), a dataset
261
388
  (torch.utils.data.Dataset) and returns a dictionary of metric
262
- values (Dict[str, float]) which is used to assess model performance
389
+ values (Mapping[str, float]) which is used to assess model performance
263
390
  given the model and data.
264
391
  runs : int, default 1
265
392
  Number of models to run over all subsets
266
393
  substeps : int, default 5
267
394
  Total number of dataset partitions that each model will train on
268
- train_kwargs : Dict | None, default None
395
+ train_kwargs : Mapping | None, default None
269
396
  Additional arguments required for custom training function
270
- eval_kwargs : Dict | None, default None
397
+ eval_kwargs : Mapping | None, default None
271
398
  Additional arguments required for custom evaluation function
272
399
  """
273
400
 
@@ -277,11 +404,11 @@ class Sufficiency:
277
404
  train_ds: Dataset,
278
405
  test_ds: Dataset,
279
406
  train_fn: Callable[[nn.Module, Dataset, Sequence[int]], None],
280
- eval_fn: Callable[[nn.Module, Dataset], dict[str, float] | dict[str, NDArray]],
407
+ eval_fn: Callable[[nn.Module, Dataset], Mapping[str, float] | Mapping[str, ArrayLike]],
281
408
  runs: int = 1,
282
409
  substeps: int = 5,
283
- train_kwargs: dict[str, Any] | None = None,
284
- eval_kwargs: dict[str, Any] | None = None,
410
+ train_kwargs: Mapping[str, Any] | None = None,
411
+ eval_kwargs: Mapping[str, Any] | None = None,
285
412
  ):
286
413
  self.model = model
287
414
  self.train_ds = train_ds
@@ -324,42 +451,42 @@ class Sufficiency:
324
451
  @property
325
452
  def eval_fn(
326
453
  self,
327
- ) -> Callable[[nn.Module, Dataset], dict[str, float] | dict[str, NDArray]]:
454
+ ) -> Callable[[nn.Module, Dataset], dict[str, float] | Mapping[str, ArrayLike]]:
328
455
  return self._eval_fn
329
456
 
330
457
  @eval_fn.setter
331
458
  def eval_fn(
332
459
  self,
333
- value: Callable[[nn.Module, Dataset], dict[str, float] | dict[str, NDArray]],
460
+ value: Callable[[nn.Module, Dataset], dict[str, float] | Mapping[str, ArrayLike]],
334
461
  ):
335
462
  if not callable(value):
336
463
  raise TypeError("Must provide a callable for eval_fn.")
337
464
  self._eval_fn = value
338
465
 
339
466
  @property
340
- def train_kwargs(self) -> dict[str, Any]:
467
+ def train_kwargs(self) -> Mapping[str, Any]:
341
468
  return self._train_kwargs
342
469
 
343
470
  @train_kwargs.setter
344
- def train_kwargs(self, value: dict[str, Any] | None):
471
+ def train_kwargs(self, value: Mapping[str, Any] | None):
345
472
  self._train_kwargs = {} if value is None else value
346
473
 
347
474
  @property
348
- def eval_kwargs(self) -> dict[str, Any]:
475
+ def eval_kwargs(self) -> Mapping[str, Any]:
349
476
  return self._eval_kwargs
350
477
 
351
478
  @eval_kwargs.setter
352
- def eval_kwargs(self, value: dict[str, Any] | None):
479
+ def eval_kwargs(self, value: Mapping[str, Any] | None):
353
480
  self._eval_kwargs = {} if value is None else value
354
481
 
355
482
  @set_metadata("dataeval.workflows", ["runs", "substeps"])
356
- def evaluate(self, eval_at: NDArray | None = None, niter: int = 1000) -> SufficiencyOutput:
483
+ def evaluate(self, eval_at: int | Iterable[int] | None = None, niter: int = 1000) -> SufficiencyOutput:
357
484
  """
358
485
  Creates data indices, trains models, and returns plotting data
359
486
 
360
487
  Parameters
361
488
  ----------
362
- eval_at : NDArray | None, default None
489
+ eval_at : int | Iterable[int] | None, default None
363
490
  Specify this to collect accuracies over a specific set of dataset lengths, rather
364
491
  than letting Sufficiency internally create the lengths to evaluate at.
365
492
  niter : int, default 1000
@@ -370,6 +497,11 @@ class Sufficiency:
370
497
  SufficiencyOutput
371
498
  Dataclass containing the average of each measure per substep
372
499
 
500
+ Raises
501
+ ------
502
+ ValueError
503
+ If `eval_at` is not numerical
504
+
373
505
  Examples
374
506
  --------
375
507
  >>> suff = Sufficiency(
@@ -379,7 +511,9 @@ class Sufficiency:
379
511
  SufficiencyOutput(steps=array([ 1, 3, 10, 31, 100], dtype=uint32), params={'test': array([ 0., 42., 0.])}, measures={'test': array([1., 1., 1., 1., 1.])})
380
512
  """ # noqa: E501
381
513
  if eval_at is not None:
382
- ranges = eval_at
514
+ ranges = np.asarray(list(eval_at) if isinstance(eval_at, Iterable) else [eval_at])
515
+ if not np.issubdtype(ranges.dtype, np.number):
516
+ raise ValueError("'eval_at' must consist of numerical values")
383
517
  else:
384
518
  geomshape = (
385
519
  0.01 * self._length,
@@ -421,136 +555,3 @@ class Sufficiency:
421
555
  measures = {k: (v / self.runs).T for k, v in measures.items()}
422
556
  params_output = get_curve_params(measures, ranges, niter)
423
557
  return SufficiencyOutput(ranges, params_output, measures)
424
-
425
- @classmethod
426
- def project(
427
- cls,
428
- data: SufficiencyOutput,
429
- projection: int | Sequence[int] | NDArray[np.uint],
430
- ) -> SufficiencyOutput:
431
- """Projects the measures for each value of X
432
-
433
- Parameters
434
- ----------
435
- data : SufficiencyOutput
436
- Dataclass containing the average of each measure per substep
437
- projection : int | Sequence[int] | NDArray[np.uint]
438
- Step or steps to project
439
-
440
- Returns
441
- -------
442
- SufficiencyOutput
443
- Dataclass containing the projected measures per projection
444
-
445
- Raises
446
- ------
447
- ValueError
448
- If the length of data points in the measures do not match
449
- If the steps are not int, Sequence[int] or an ndarray
450
- """
451
- projection = [projection] if isinstance(projection, int) else projection
452
- projection = np.array(projection) if isinstance(projection, Sequence) else projection
453
- if not isinstance(projection, np.ndarray):
454
- raise ValueError("'steps' must be an int, Sequence[int] or ndarray")
455
-
456
- output = {}
457
- for name, measures in data.measures.items():
458
- if measures.ndim > 1:
459
- result = []
460
- for i in range(len(measures)):
461
- projected = project_steps(data.params[name][i], projection)
462
- result.append(projected)
463
- output[name] = np.array(result)
464
- else:
465
- output[name] = project_steps(data.params[name], projection)
466
- return SufficiencyOutput(projection, data.params, output)
467
-
468
- @classmethod
469
- def plot(cls, data: SufficiencyOutput, class_names: Sequence[str] | None = None) -> list[Figure]:
470
- """Plotting function for data sufficiency tasks
471
-
472
- Parameters
473
- ----------
474
- data : SufficiencyOutput
475
- Dataclass containing the average of each measure per substep
476
- class_names : Sequence[str] | None, default None
477
- List of class names
478
-
479
- Returns
480
- -------
481
- List[plt.Figure]
482
- List of Figures for each measure
483
-
484
- Raises
485
- ------
486
- ValueError
487
- If the length of data points in the measures do not match
488
- """
489
- # Extrapolation parameters
490
- last_X = data.steps[-1]
491
- geomshape = (0.01 * last_X, last_X * 4, len(data.steps))
492
- extrapolated = np.geomspace(*geomshape).astype(np.int64)
493
-
494
- # Stores all plots
495
- plots = []
496
-
497
- # Create a plot for each measure on one figure
498
- for name, measures in data.measures.items():
499
- if measures.ndim > 1:
500
- if class_names is not None and len(measures) != len(class_names):
501
- raise IndexError("Class name count does not align with measures")
502
- for i, measure in enumerate(measures):
503
- class_name = str(i) if class_names is None else class_names[i]
504
- fig = plot_measure(
505
- f"{name}_{class_name}",
506
- data.steps,
507
- measure,
508
- data.params[name][i],
509
- extrapolated,
510
- )
511
- plots.append(fig)
512
-
513
- else:
514
- fig = plot_measure(name, data.steps, measures, data.params[name], extrapolated)
515
- plots.append(fig)
516
-
517
- return plots
518
-
519
- @classmethod
520
- def inv_project(cls, targets: dict[str, NDArray], data: SufficiencyOutput) -> dict[str, NDArray]:
521
- """
522
- Calculate training samples needed to achieve target model metric values.
523
-
524
- Parameters
525
- ----------
526
- targets : Dict[str, NDArray]
527
- Dictionary of target metric scores (from 0.0 to 1.0) that we want
528
- to achieve, where the key is the name of the metric.
529
-
530
- data : SufficiencyOutput
531
- Dataclass containing the average of each measure per substep
532
-
533
- Returns
534
- -------
535
- Dict[str, NDArray]
536
- List of the number of training samples needed to achieve each
537
- corresponding entry in targets
538
- """
539
-
540
- projection = {}
541
-
542
- for name, target in targets.items():
543
- if name not in data.measures:
544
- continue
545
-
546
- measure = data.measures[name]
547
- if measure.ndim > 1:
548
- projection[name] = np.zeros((len(measure), len(target)))
549
- for i in range(len(measure)):
550
- projection[name][i] = inv_project_steps(
551
- data.params[name][i], target[i] if target.ndim == measure.ndim else target
552
- )
553
- else:
554
- projection[name] = inv_project_steps(data.params[name], target)
555
-
556
- return projection
@@ -1,3 +1,7 @@
1
+ """
2
+ Detectors can determine if a dataset or individual images in a dataset are indicative of a specific issue.
3
+ """
4
+
1
5
  from dataeval import _IS_TENSORFLOW_AVAILABLE
2
6
 
3
7
  from . import drift, linters
@@ -1,16 +1,21 @@
1
+ """
2
+ Drift detectors identify if the statistical properties of the data has changed.
3
+ """
4
+
1
5
  from dataeval import _IS_TORCH_AVAILABLE
6
+ from dataeval._internal.detectors.drift.base import DriftOutput
2
7
  from dataeval._internal.detectors.drift.cvm import DriftCVM
3
8
  from dataeval._internal.detectors.drift.ks import DriftKS
4
9
 
5
10
  from . import updates
6
11
 
7
- __all__ = ["DriftCVM", "DriftKS", "updates"]
12
+ __all__ = ["DriftCVM", "DriftKS", "DriftOutput", "updates"]
8
13
 
9
14
  if _IS_TORCH_AVAILABLE: # pragma: no cover
10
- from dataeval._internal.detectors.drift.mmd import DriftMMD
15
+ from dataeval._internal.detectors.drift.mmd import DriftMMD, DriftMMDOutput
11
16
  from dataeval._internal.detectors.drift.torch import preprocess_drift
12
17
  from dataeval._internal.detectors.drift.uncertainty import DriftUncertainty
13
18
 
14
19
  from . import kernels
15
20
 
16
- __all__ += ["DriftMMD", "DriftUncertainty", "kernels", "preprocess_drift"]
21
+ __all__ += ["DriftMMD", "DriftMMDOutput", "DriftUncertainty", "kernels", "preprocess_drift"]
@@ -1,3 +1,7 @@
1
+ """
2
+ Kernels are used to map non-linear data to a higher dimensional space.
3
+ """
4
+
1
5
  from dataeval import _IS_TORCH_AVAILABLE
2
6
 
3
7
  if _IS_TORCH_AVAILABLE: # pragma: no cover
@@ -1,3 +1,7 @@
1
+ """
2
+ Update strategies inform how the drift detector classes update the reference data when monitoring for drift.
3
+ """
4
+
1
5
  from dataeval._internal.detectors.drift.base import LastSeenUpdate, ReservoirSamplingUpdate
2
6
 
3
7
  __all__ = ["LastSeenUpdate", "ReservoirSamplingUpdate"]
@@ -1,5 +1,16 @@
1
- from dataeval._internal.detectors.clusterer import Clusterer
2
- from dataeval._internal.detectors.duplicates import Duplicates
3
- from dataeval._internal.detectors.outliers import Outliers
1
+ """
2
+ Linters help identify potential issues in training and test data and are an important aspect of data cleaning.
3
+ """
4
4
 
5
- __all__ = ["Clusterer", "Duplicates", "Outliers"]
5
+ from dataeval._internal.detectors.clusterer import Clusterer, ClustererOutput
6
+ from dataeval._internal.detectors.duplicates import Duplicates, DuplicatesOutput
7
+ from dataeval._internal.detectors.outliers import Outliers, OutliersOutput
8
+
9
+ __all__ = [
10
+ "Clusterer",
11
+ "ClustererOutput",
12
+ "Duplicates",
13
+ "DuplicatesOutput",
14
+ "Outliers",
15
+ "OutliersOutput",
16
+ ]
@@ -1,11 +1,23 @@
1
+ """
2
+ Out-of-distribution detectors identify data that is different from the data used to train a particular model.
3
+ """
4
+
1
5
  from dataeval import _IS_TENSORFLOW_AVAILABLE
2
6
 
3
7
  if _IS_TENSORFLOW_AVAILABLE: # pragma: no cover
4
8
  from dataeval._internal.detectors.ood.ae import OOD_AE
5
9
  from dataeval._internal.detectors.ood.aegmm import OOD_AEGMM
6
- from dataeval._internal.detectors.ood.base import OODOutput, OODScore
10
+ from dataeval._internal.detectors.ood.base import OODOutput, OODScoreOutput
7
11
  from dataeval._internal.detectors.ood.llr import OOD_LLR
8
12
  from dataeval._internal.detectors.ood.vae import OOD_VAE
9
13
  from dataeval._internal.detectors.ood.vaegmm import OOD_VAEGMM
10
14
 
11
- __all__ = ["OODOutput", "OODScore", "OOD_AE", "OOD_AEGMM", "OOD_LLR", "OOD_VAE", "OOD_VAEGMM"]
15
+ __all__ = [
16
+ "OOD_AE",
17
+ "OOD_AEGMM",
18
+ "OOD_LLR",
19
+ "OOD_VAE",
20
+ "OOD_VAEGMM",
21
+ "OODOutput",
22
+ "OODScoreOutput",
23
+ ]
@@ -1,3 +1,8 @@
1
+ """
2
+ Metrics are a way to measure the performance of your models or datasets that
3
+ can then be analyzed in the context of a given problem.
4
+ """
5
+
1
6
  from . import bias, estimators, stats
2
7
 
3
8
  __all__ = ["bias", "estimators", "stats"]