dataeval 0.63.0__py3-none-any.whl → 0.64.0__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.
- dataeval/__init__.py +3 -3
- dataeval/_internal/detectors/clusterer.py +2 -1
- dataeval/_internal/detectors/drift/base.py +2 -1
- dataeval/_internal/detectors/drift/cvm.py +2 -1
- dataeval/_internal/detectors/drift/ks.py +2 -1
- dataeval/_internal/detectors/drift/mmd.py +4 -3
- dataeval/_internal/detectors/drift/uncertainty.py +1 -2
- dataeval/_internal/detectors/duplicates.py +2 -1
- dataeval/_internal/detectors/linter.py +1 -1
- dataeval/_internal/detectors/ood/ae.py +2 -1
- dataeval/_internal/detectors/ood/aegmm.py +2 -1
- dataeval/_internal/detectors/ood/base.py +2 -1
- dataeval/_internal/detectors/ood/llr.py +3 -2
- dataeval/_internal/detectors/ood/vae.py +2 -1
- dataeval/_internal/detectors/ood/vaegmm.py +2 -1
- dataeval/_internal/interop.py +2 -11
- dataeval/_internal/metrics/balance.py +180 -0
- dataeval/_internal/metrics/base.py +1 -83
- dataeval/_internal/metrics/ber.py +122 -48
- dataeval/_internal/metrics/coverage.py +83 -74
- dataeval/_internal/metrics/divergence.py +67 -67
- dataeval/_internal/metrics/diversity.py +206 -0
- dataeval/_internal/metrics/parity.py +300 -155
- dataeval/_internal/metrics/stats.py +7 -5
- dataeval/_internal/metrics/uap.py +37 -29
- dataeval/_internal/metrics/utils.py +393 -0
- dataeval/_internal/utils.py +64 -0
- dataeval/metrics/__init__.py +25 -6
- dataeval/utils/__init__.py +9 -0
- {dataeval-0.63.0.dist-info → dataeval-0.64.0.dist-info}/METADATA +1 -1
- dataeval-0.64.0.dist-info/RECORD +60 -0
- dataeval/_internal/functional/__init__.py +0 -0
- dataeval/_internal/functional/ber.py +0 -63
- dataeval/_internal/functional/coverage.py +0 -75
- dataeval/_internal/functional/divergence.py +0 -16
- dataeval/_internal/functional/hash.py +0 -79
- dataeval/_internal/functional/metadata.py +0 -136
- dataeval/_internal/functional/metadataparity.py +0 -190
- dataeval/_internal/functional/uap.py +0 -6
- dataeval/_internal/functional/utils.py +0 -158
- dataeval/_internal/maite/__init__.py +0 -0
- dataeval/_internal/maite/utils.py +0 -30
- dataeval/_internal/metrics/metadata.py +0 -610
- dataeval/_internal/metrics/metadataparity.py +0 -67
- dataeval-0.63.0.dist-info/RECORD +0 -68
- {dataeval-0.63.0.dist-info → dataeval-0.64.0.dist-info}/LICENSE.txt +0 -0
- {dataeval-0.63.0.dist-info → dataeval-0.64.0.dist-info}/WHEEL +0 -0
@@ -1,158 +0,0 @@
|
|
1
|
-
from typing import Any, Literal, NamedTuple, Tuple, Union
|
2
|
-
|
3
|
-
import numpy as np
|
4
|
-
from scipy.signal import convolve2d
|
5
|
-
from scipy.sparse import csr_matrix
|
6
|
-
from scipy.sparse.csgraph import minimum_spanning_tree as mst
|
7
|
-
from scipy.spatial.distance import pdist, squareform
|
8
|
-
from sklearn.neighbors import NearestNeighbors
|
9
|
-
|
10
|
-
EPSILON = 1e-5
|
11
|
-
EDGE_KERNEL = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]], dtype=np.int8)
|
12
|
-
BIT_DEPTH = (1, 8, 12, 16, 32)
|
13
|
-
|
14
|
-
|
15
|
-
def minimum_spanning_tree(X: np.ndarray) -> Any:
|
16
|
-
"""
|
17
|
-
Returns the minimum spanning tree from a NumPy image array.
|
18
|
-
|
19
|
-
Parameters
|
20
|
-
----------
|
21
|
-
X: np.ndarray
|
22
|
-
Numpy image array
|
23
|
-
|
24
|
-
Returns
|
25
|
-
-------
|
26
|
-
Data representing the minimum spanning tree
|
27
|
-
"""
|
28
|
-
# All features belong on second dimension
|
29
|
-
X = X.reshape((X.shape[0], -1))
|
30
|
-
# We add a small constant to the distance matrix to ensure scipy interprets
|
31
|
-
# the input graph as fully-connected.
|
32
|
-
dense_eudist = squareform(pdist(X)) + EPSILON
|
33
|
-
eudist_csr = csr_matrix(dense_eudist)
|
34
|
-
return mst(eudist_csr)
|
35
|
-
|
36
|
-
|
37
|
-
def get_classes_counts(labels: np.ndarray) -> Tuple[int, int]:
|
38
|
-
"""
|
39
|
-
Returns the classes and counts of from an array of labels
|
40
|
-
|
41
|
-
Parameters
|
42
|
-
----------
|
43
|
-
label: np.ndarray
|
44
|
-
Numpy labels array
|
45
|
-
|
46
|
-
Returns
|
47
|
-
-------
|
48
|
-
Classes and counts
|
49
|
-
|
50
|
-
Raises
|
51
|
-
------
|
52
|
-
ValueError
|
53
|
-
If the number of unique classes is less than 2
|
54
|
-
"""
|
55
|
-
classes, counts = np.unique(labels, return_counts=True)
|
56
|
-
M = len(classes)
|
57
|
-
if M < 2:
|
58
|
-
raise ValueError("Label vector contains less than 2 classes!")
|
59
|
-
N = np.sum(counts).astype(int)
|
60
|
-
return M, N
|
61
|
-
|
62
|
-
|
63
|
-
def compute_neighbors(
|
64
|
-
A: np.ndarray,
|
65
|
-
B: np.ndarray,
|
66
|
-
k: int = 1,
|
67
|
-
algorithm: Literal["auto", "ball_tree", "kd_tree"] = "auto",
|
68
|
-
) -> np.ndarray:
|
69
|
-
"""
|
70
|
-
For each sample in A, compute the nearest neighbor in B
|
71
|
-
|
72
|
-
Parameters
|
73
|
-
----------
|
74
|
-
A, B : np.ndarray
|
75
|
-
The n_samples and n_features respectively
|
76
|
-
k : int
|
77
|
-
The number of neighbors to find
|
78
|
-
algorithm : Literal
|
79
|
-
Tree method for nearest neighbor (auto, ball_tree or kd_tree)
|
80
|
-
|
81
|
-
Note
|
82
|
-
----
|
83
|
-
Do not use kd_tree if n_features > 20
|
84
|
-
|
85
|
-
Returns
|
86
|
-
-------
|
87
|
-
List:
|
88
|
-
Closest points to each point in A and B
|
89
|
-
|
90
|
-
See Also
|
91
|
-
--------
|
92
|
-
:func:`sklearn.neighbors.NearestNeighbors`
|
93
|
-
"""
|
94
|
-
|
95
|
-
nbrs = NearestNeighbors(n_neighbors=k + 1, algorithm=algorithm).fit(B)
|
96
|
-
nns = nbrs.kneighbors(A)[1]
|
97
|
-
nns = nns[:, 1:].squeeze()
|
98
|
-
|
99
|
-
return nns
|
100
|
-
|
101
|
-
|
102
|
-
class BitDepth(NamedTuple):
|
103
|
-
depth: int
|
104
|
-
pmin: Union[float, int]
|
105
|
-
pmax: Union[float, int]
|
106
|
-
|
107
|
-
|
108
|
-
def get_bitdepth(image: np.ndarray) -> BitDepth:
|
109
|
-
"""
|
110
|
-
Approximates the bit depth of the image using the
|
111
|
-
min and max pixel values.
|
112
|
-
"""
|
113
|
-
pmin, pmax = np.min(image), np.max(image)
|
114
|
-
if pmin < 0:
|
115
|
-
return BitDepth(0, pmin, pmax)
|
116
|
-
else:
|
117
|
-
depth = ([x for x in BIT_DEPTH if 2**x > pmax] or [max(BIT_DEPTH)])[0]
|
118
|
-
return BitDepth(depth, 0, 2**depth - 1)
|
119
|
-
|
120
|
-
|
121
|
-
def rescale(image: np.ndarray, depth: int = 1) -> np.ndarray:
|
122
|
-
"""
|
123
|
-
Rescales the image using the bit depth provided.
|
124
|
-
"""
|
125
|
-
bitdepth = get_bitdepth(image)
|
126
|
-
if bitdepth.depth == depth:
|
127
|
-
return image
|
128
|
-
else:
|
129
|
-
normalized = (image + bitdepth.pmin) / (bitdepth.pmax - bitdepth.pmin)
|
130
|
-
return normalized * (2**depth - 1)
|
131
|
-
|
132
|
-
|
133
|
-
def normalize_image_shape(image: np.ndarray) -> np.ndarray:
|
134
|
-
"""
|
135
|
-
Normalizes the image shape into (C,H,W).
|
136
|
-
"""
|
137
|
-
ndim = image.ndim
|
138
|
-
if ndim == 2:
|
139
|
-
return np.expand_dims(image, axis=0)
|
140
|
-
elif ndim == 3:
|
141
|
-
return image
|
142
|
-
elif ndim > 3:
|
143
|
-
# Slice all but the last 3 dimensions
|
144
|
-
return image[(0,) * (ndim - 3)]
|
145
|
-
else:
|
146
|
-
raise ValueError("Images must have 2 or more dimensions.")
|
147
|
-
|
148
|
-
|
149
|
-
def edge_filter(image: np.ndarray, offset: float = 0.5) -> np.ndarray:
|
150
|
-
"""
|
151
|
-
Returns the image filtered using a 3x3 edge detection kernel:
|
152
|
-
[[ -1, -1, -1 ],
|
153
|
-
[ -1, 8, -1 ],
|
154
|
-
[ -1, -1, -1 ]]
|
155
|
-
"""
|
156
|
-
edges = convolve2d(image, EDGE_KERNEL, mode="same", boundary="symm") + offset
|
157
|
-
np.clip(edges, 0, 255, edges)
|
158
|
-
return edges
|
File without changes
|
@@ -1,30 +0,0 @@
|
|
1
|
-
from typing import Tuple
|
2
|
-
|
3
|
-
import numpy as np
|
4
|
-
import torch
|
5
|
-
|
6
|
-
import maite.protocols.image_classification as ic
|
7
|
-
from maite.protocols import ArrayLike
|
8
|
-
|
9
|
-
|
10
|
-
def arraylike_to_numpy(xp: ArrayLike) -> np.ndarray:
|
11
|
-
"""Converts ArrayLike objects to numpy"""
|
12
|
-
|
13
|
-
# Must ensure Tensors are not on GPU
|
14
|
-
return xp.detach().cpu().numpy() if isinstance(xp, torch.Tensor) else np.asarray(xp)
|
15
|
-
|
16
|
-
|
17
|
-
# TODO: Overload with od.Dataset
|
18
|
-
# TODO: Check if batching aggregation is faster (e.g. DataLoader)
|
19
|
-
# TODO: Add verbosity flags (tqdm?)
|
20
|
-
def extract_to_numpy(dataset: ic.Dataset) -> Tuple[np.ndarray, np.ndarray]:
|
21
|
-
"""Iterate over dataset and separate images from labels"""
|
22
|
-
images = []
|
23
|
-
labels = []
|
24
|
-
|
25
|
-
# (image, label, metadata)
|
26
|
-
for image, label, _ in dataset:
|
27
|
-
images.append(image)
|
28
|
-
labels.append(label)
|
29
|
-
|
30
|
-
return np.asarray(images), np.asarray(labels)
|