aisp 0.1.40__py3-none-any.whl → 0.1.42__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.
- aisp/__init__.py +2 -2
- aisp/base/__init__.py +1 -0
- aisp/base/_classifier.py +50 -24
- aisp/exceptions.py +9 -8
- aisp/nsa/__init__.py +2 -2
- aisp/nsa/_base.py +35 -27
- aisp/nsa/_negative_selection.py +193 -197
- aisp/nsa/_ns_core.py +49 -39
- aisp/utils/__init__.py +1 -1
- aisp/utils/_multiclass.py +18 -12
- aisp/utils/distance.py +96 -78
- aisp/utils/metrics.py +10 -8
- aisp/utils/sanitizers.py +27 -18
- {aisp-0.1.40.dist-info → aisp-0.1.42.dist-info}/METADATA +1 -1
- aisp-0.1.42.dist-info/RECORD +18 -0
- {aisp-0.1.40.dist-info → aisp-0.1.42.dist-info}/WHEEL +1 -1
- aisp-0.1.40.dist-info/RECORD +0 -18
- {aisp-0.1.40.dist-info → aisp-0.1.42.dist-info}/licenses/LICENSE +0 -0
- {aisp-0.1.40.dist-info → aisp-0.1.42.dist-info}/top_level.txt +0 -0
aisp/nsa/_negative_selection.py
CHANGED
@@ -12,7 +12,6 @@ from ._ns_core import (
|
|
12
12
|
check_detector_rnsa_validity,
|
13
13
|
)
|
14
14
|
from ..exceptions import MaxDiscardsReachedError
|
15
|
-
from ..utils import slice_index_list_by_class
|
16
15
|
from ..utils.distance import (
|
17
16
|
min_distance_to_class_vectors,
|
18
17
|
get_metric_code,
|
@@ -23,58 +22,64 @@ from ._base import BaseNSA, Detector
|
|
23
22
|
|
24
23
|
|
25
24
|
class RNSA(BaseNSA):
|
26
|
-
"""
|
27
|
-
|
28
|
-
|
25
|
+
"""Real-Valued Negative Selection Algorithm (RNSA) for classification and anomaly detection.
|
26
|
+
|
27
|
+
Uses the self and non-self method to identify anomalies.
|
29
28
|
|
30
29
|
Parameters
|
31
30
|
----------
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
31
|
+
N : int, default=100
|
32
|
+
Number of detectors.
|
33
|
+
r : float, default=0.05
|
34
|
+
Radius of the detector.
|
35
|
+
r_s : float, default=0.0001
|
36
|
+
rₛ Radius of the ``X`` own samples.
|
37
|
+
k : int, default=1
|
38
|
+
Number of neighbors near the randomly generated detectors to perform the distance average
|
39
|
+
calculation.
|
40
|
+
metric: str, default='euclidean'
|
41
|
+
Way to calculate the distance between the detector and the sample:
|
42
|
+
|
43
|
+
+ ``'Euclidean'`` ➜ The calculation of the distance is given by the expression:
|
44
|
+
√( (x₁ – x₂)² + (y₁ – y₂)² + ... + (yn – yn)²).
|
45
|
+
+ ``'minkowski'`` ➜ The calculation of the distance is given by the expression:
|
46
|
+
( |X₁ – Y₁|p + |X₂ – Y₂|p + ... + |Xn – Yn|p) ¹/ₚ.
|
47
|
+
+ ``'manhattan'`` ➜ The calculation of the distance is given by the expression:
|
48
|
+
( |x₁ – x₂| + |y₁ – y₂| + ... + |yn – yn|) .
|
49
|
+
max_discards : int, default=1000
|
50
|
+
This parameter indicates the maximum number of consecutive detector discards, aimed at
|
51
|
+
preventing a possible infinite loop in case a radius is defined that cannot generate
|
52
|
+
non-self detectors.
|
53
|
+
seed : int, default=None
|
54
|
+
Seed for the random generation of values in the detectors.
|
55
|
+
algorithm : str, default='default-NSA'
|
56
|
+
Set the algorithm version:
|
57
|
+
|
58
|
+
+ ``'default-NSA'``: Default algorithm with fixed radius.
|
59
|
+
+ ``'V-detector'``: This algorithm is based on the article Ji & Dasgupta (2004) [1]_
|
60
|
+
and uses a variable radius for anomaly detection in feature spaces.
|
61
|
+
|
62
|
+
**kwargs : dict
|
63
|
+
Parâmetros adicionais. Os seguintes argumentos são reconhecidos:
|
64
|
+
|
65
|
+
+ non_self_label : str, default='non-self'
|
66
|
+
This variable stores the label that will be assigned when the data has only one
|
67
|
+
output class, and the sample is classified as not belonging to that class.
|
68
|
+
+ cell_bounds : bool, default=False
|
69
|
+
If set to ``True``, this option limits the generation of detectors to the space
|
70
|
+
within the plane between 0 and 1. This means that any detector whose radius exceeds
|
71
|
+
this limit is discarded, this variable is only used in the ``V-detector`` algorithm.
|
72
|
+
+ p : float, default=2
|
73
|
+
This parameter stores the value of ``p`` used in the Minkowski distance. The default
|
74
|
+
is ``2``, which represents Euclidean distance. Different values of p lead
|
75
|
+
to different variants of the Minkowski Distance.
|
76
|
+
|
77
|
+
References
|
73
78
|
----------
|
74
|
-
[1]
|
75
|
-
|
76
|
-
|
77
|
-
|
79
|
+
.. [1] Ji, Z.; Dasgupta, D. (2004).
|
80
|
+
Real-Valued Negative Selection Algorithm with Variable-Sized Detectors.
|
81
|
+
In *Lecture Notes in Computer Science*, vol. 3025.
|
82
|
+
https://doi.org/10.1007/978-3-540-24854-5_30
|
78
83
|
"""
|
79
84
|
|
80
85
|
def __init__(
|
@@ -111,27 +116,37 @@ class RNSA(BaseNSA):
|
|
111
116
|
self._detectors: Union[dict, None] = None
|
112
117
|
self.classes: npt.NDArray = None
|
113
118
|
|
119
|
+
@property
|
120
|
+
def detectors(self) -> Dict[str, list[Detector]]:
|
121
|
+
"""Returns the trained detectors, organized by class."""
|
122
|
+
return self._detectors
|
123
|
+
|
114
124
|
def fit(self, X: npt.NDArray, y: npt.NDArray, verbose: bool = True):
|
115
125
|
"""
|
116
|
-
|
117
|
-
method negative selection method(``NegativeSelect``).
|
126
|
+
Perform training according to X and y, using the negative selection method (NegativeSelect).
|
118
127
|
|
119
128
|
Parameters
|
120
129
|
----------
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
130
|
+
X : npt.NDArray
|
131
|
+
Training array, containing the samples and their characteristics, [``N samples`` (
|
132
|
+
rows)][``N features`` (columns)].
|
133
|
+
y : npt.NDArray
|
134
|
+
Array of target classes of ``X`` with [``N samples`` (lines)].
|
135
|
+
verbose: bool, default=True
|
136
|
+
Feedback from detector generation to the user.
|
125
137
|
|
126
138
|
Raises
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
139
|
+
------
|
140
|
+
TypeError
|
141
|
+
If X or y are not ndarrays or have incompatible shapes.
|
142
|
+
MaxDiscardsReachedError
|
143
|
+
The maximum number of detector discards was reached during maturation. Check the
|
144
|
+
defined radius value and consider reducing it.
|
131
145
|
|
132
146
|
Returns
|
133
|
-
|
134
|
-
|
147
|
+
-------
|
148
|
+
self : RNSA
|
149
|
+
Returns the instance itself.
|
135
150
|
"""
|
136
151
|
progress = None
|
137
152
|
super()._check_and_raise_exceptions_fit(X, y)
|
@@ -141,7 +156,7 @@ class RNSA(BaseNSA):
|
|
141
156
|
# Dictionary that will store detectors with classes as keys.
|
142
157
|
list_detectors_by_class = {}
|
143
158
|
# Separates the classes for training.
|
144
|
-
sample_index = self.
|
159
|
+
sample_index = self._slice_index_list_by_class(y)
|
145
160
|
# Progress bar for generating all detectors.
|
146
161
|
if verbose:
|
147
162
|
progress = tqdm(
|
@@ -168,7 +183,9 @@ class RNSA(BaseNSA):
|
|
168
183
|
# If the detector is valid, add it to the list of valid detectors.
|
169
184
|
if valid_detector is not False:
|
170
185
|
discard_count = 0
|
171
|
-
radius =
|
186
|
+
radius = (
|
187
|
+
valid_detector[1] if self.algorithm == "V-detector" else None
|
188
|
+
)
|
172
189
|
valid_detectors_set.append(Detector(vector_x, radius))
|
173
190
|
if verbose:
|
174
191
|
progress.update(1)
|
@@ -178,7 +195,7 @@ class RNSA(BaseNSA):
|
|
178
195
|
raise MaxDiscardsReachedError(_class_)
|
179
196
|
|
180
197
|
# Add detectors, with classes as keys in the dictionary.
|
181
|
-
list_detectors_by_class[_class_] =
|
198
|
+
list_detectors_by_class[_class_] = valid_detectors_set
|
182
199
|
# Notify completion of detector generation for the classes.
|
183
200
|
if verbose:
|
184
201
|
progress.set_description(
|
@@ -191,29 +208,26 @@ class RNSA(BaseNSA):
|
|
191
208
|
|
192
209
|
def predict(self, X: npt.NDArray) -> Optional[npt.NDArray]:
|
193
210
|
"""
|
194
|
-
|
195
|
-
created after training.
|
211
|
+
Prediction of classes based on detectors created after training.
|
196
212
|
|
197
213
|
Parameters
|
198
214
|
----------
|
199
|
-
|
200
|
-
Array with input samples with [``
|
201
|
-
|
215
|
+
X : npt.NDArray
|
216
|
+
Array with input samples with [``N_samples`` (Lines)] and [``N_characteristics``
|
217
|
+
(Columns)]
|
202
218
|
|
203
219
|
Raises
|
204
|
-
|
205
|
-
|
220
|
+
------
|
221
|
+
TypeError
|
206
222
|
If X is not an ndarray or list.
|
207
|
-
|
223
|
+
FeatureDimensionMismatch
|
208
224
|
If the number of features in X does not match the expected number.
|
209
225
|
|
210
226
|
Returns
|
211
|
-
|
212
|
-
|
227
|
+
-------
|
228
|
+
C : npt.NDArray or None
|
213
229
|
an ndarray of the form ``C`` [``N samples``], containing the predicted classes
|
214
|
-
for ``X``.
|
215
|
-
* ``None``
|
216
|
-
If there are no detectors for the prediction.
|
230
|
+
for ``X``. Returns `None` if no detectors are available for prediction.
|
217
231
|
"""
|
218
232
|
# If there are no detectors, Returns None.
|
219
233
|
if self._detectors is None:
|
@@ -253,40 +267,23 @@ class RNSA(BaseNSA):
|
|
253
267
|
c.append(max(average_distance, key=average_distance.get))
|
254
268
|
return np.array(c)
|
255
269
|
|
256
|
-
def __slice_index_list_by_class(self, y: npt.NDArray) -> dict:
|
257
|
-
"""
|
258
|
-
The function ``__slice_index_list_by_class(...)``, separates the indices of the lines
|
259
|
-
according to the output class, to loop through the sample array, only in positions where
|
260
|
-
the output is the class being trained.
|
261
|
-
|
262
|
-
Parameters
|
263
|
-
----------
|
264
|
-
* y (npt.NDArray)
|
265
|
-
Receives a ``y``[``N sample``] array with the output classes of the \
|
266
|
-
``X`` sample array.
|
267
|
-
|
268
|
-
Returns
|
269
|
-
----------
|
270
|
-
* dict: A dictionary with the list of array positions(``y``), with the classes as key.
|
271
|
-
"""
|
272
|
-
return slice_index_list_by_class(self.classes, y)
|
273
|
-
|
274
270
|
def __checks_valid_detector(
|
275
|
-
self, x_class: npt.NDArray
|
271
|
+
self, x_class: npt.NDArray, vector_x: npt.NDArray
|
276
272
|
) -> Union[bool, tuple[bool, float]]:
|
277
273
|
"""
|
278
|
-
|
274
|
+
Check if the detector has a valid non-proper r radius for the class.
|
279
275
|
|
280
276
|
Parameters
|
281
277
|
----------
|
282
|
-
|
278
|
+
x_class : npt.NDArray
|
283
279
|
Array ``x_class`` with the samples per class.
|
284
|
-
|
280
|
+
vector_x : npt.NDArray
|
285
281
|
Randomly generated vector x candidate detector with values between[0, 1].
|
286
282
|
|
287
283
|
Returns
|
288
|
-
|
289
|
-
|
284
|
+
-------
|
285
|
+
Validity : bool
|
286
|
+
Returns whether the detector is valid or not.
|
290
287
|
"""
|
291
288
|
# If any of the input arrays have zero size, Returns false.
|
292
289
|
if np.size(x_class) == 0 or np.size(vector_x) == 0:
|
@@ -294,7 +291,7 @@ class RNSA(BaseNSA):
|
|
294
291
|
# If self.k > 1, uses the k nearest neighbors (kNN); otherwise, checks the detector
|
295
292
|
# without considering kNN.
|
296
293
|
if self.k > 1:
|
297
|
-
knn_list =
|
294
|
+
knn_list = []
|
298
295
|
for x in x_class:
|
299
296
|
# Calculates the distance between the two vectors and adds it to the kNN list if
|
300
297
|
# the distance is smaller than the largest distance in the list.
|
@@ -329,20 +326,21 @@ class RNSA(BaseNSA):
|
|
329
326
|
self, knn: npt.NDArray, distance: float
|
330
327
|
) -> npt.NDArray:
|
331
328
|
"""
|
332
|
-
|
333
|
-
if the distance of the new sample is less, replace it and sort in ascending order.
|
329
|
+
Compare the k-nearest neighbor distance at position k=1 in the list knn.
|
334
330
|
|
331
|
+
If the distance of the new sample is less, replace it and sort in ascending order.
|
335
332
|
|
336
333
|
Parameters
|
337
334
|
----------
|
338
|
-
|
335
|
+
knn : npt.NDArray
|
339
336
|
List of k-nearest neighbor distances.
|
340
|
-
|
337
|
+
distance : float
|
341
338
|
Distance to check.
|
342
339
|
|
343
340
|
Returns
|
344
|
-
|
345
|
-
|
341
|
+
-------
|
342
|
+
knn : npt.NDArray
|
343
|
+
Updated and sorted nearest neighbor list.
|
346
344
|
"""
|
347
345
|
# If the number of distances in kNN is less than k, adds the distance.
|
348
346
|
if len(knn) < self.k:
|
@@ -358,18 +356,20 @@ class RNSA(BaseNSA):
|
|
358
356
|
|
359
357
|
return knn
|
360
358
|
|
361
|
-
def __compare_sample_to_detectors(self, line: npt.NDArray):
|
359
|
+
def __compare_sample_to_detectors(self, line: npt.NDArray) -> Optional[str]:
|
362
360
|
"""
|
363
|
-
|
361
|
+
Compare a sample with the detectors, verifying if the sample is proper.
|
364
362
|
|
365
363
|
Parameters
|
366
364
|
----------
|
367
|
-
|
365
|
+
line : npt.NDArray
|
366
|
+
vector with N-features
|
368
367
|
|
369
368
|
Returns
|
370
|
-
|
371
|
-
|
372
|
-
|
369
|
+
-------
|
370
|
+
possible_classes : Optional[str]
|
371
|
+
Returns the predicted class with the detectors or None if the sample does not qualify
|
372
|
+
for any class.
|
373
373
|
"""
|
374
374
|
# List to store the classes and the average distance between the detectors and the sample.
|
375
375
|
possible_classes = []
|
@@ -403,37 +403,45 @@ class RNSA(BaseNSA):
|
|
403
403
|
|
404
404
|
def __distance(self, u: npt.NDArray, v: npt.NDArray) -> float:
|
405
405
|
"""
|
406
|
-
|
406
|
+
Calculate the distance between two points by the chosen ``metric``.
|
407
407
|
|
408
408
|
Parameters
|
409
409
|
----------
|
410
|
-
|
411
|
-
|
410
|
+
u : npt.NDArray
|
411
|
+
Coordinates of the first point.
|
412
|
+
v : npt.NDArray
|
413
|
+
Coordinates of the second point.
|
412
414
|
|
413
415
|
Returns
|
414
|
-
|
415
|
-
|
416
|
+
-------
|
417
|
+
Distance : float
|
418
|
+
between the two points.
|
416
419
|
"""
|
417
420
|
return compute_metric_distance(u, v, get_metric_code(self.metric), self.p)
|
418
421
|
|
419
422
|
def __detector_is_valid_to_vdetector(
|
420
423
|
self, distance: float, vector_x: npt.NDArray
|
421
424
|
) -> Union[bool, tuple[bool, float]]:
|
422
|
-
"""
|
423
|
-
|
424
|
-
|
425
|
+
"""Validate the detector against the vdetector.
|
426
|
+
|
427
|
+
Check if the distance between the detector and the samples, minus the radius of the
|
428
|
+
samples, is greater than the minimum radius.
|
425
429
|
|
426
430
|
Parameters
|
427
431
|
----------
|
428
|
-
|
429
|
-
|
430
|
-
|
432
|
+
distance : float
|
433
|
+
minimum distance calculated between all samples.
|
434
|
+
vector_x : np.ndarray
|
435
|
+
randomly generated candidate detector vector x with values between 0 and 1.
|
431
436
|
|
432
437
|
Returns
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
438
|
+
-------
|
439
|
+
valid : bool
|
440
|
+
|
441
|
+
- ``False`` if the calculated radius is smaller than the minimum distance or exceeds
|
442
|
+
the edge of the space, if this option is enabled.
|
443
|
+
|
444
|
+
- ``True`` and the distance minus the radius of the samples, if the radius is valid.`
|
437
445
|
"""
|
438
446
|
new_detector_r = float(distance - self.r_s)
|
439
447
|
if self.r >= new_detector_r:
|
@@ -449,27 +457,33 @@ class RNSA(BaseNSA):
|
|
449
457
|
|
450
458
|
|
451
459
|
class BNSA(BaseNSA):
|
452
|
-
"""
|
453
|
-
|
454
|
-
identification purposes of anomalies through the self and not
|
460
|
+
"""BNSA (Binary Negative Selection Algorithm).
|
461
|
+
|
462
|
+
Class is for classification and identification purposes of anomalies through the self and not
|
463
|
+
self method.
|
455
464
|
|
456
465
|
Parameters
|
457
466
|
----------
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
467
|
+
N : int, default=100
|
468
|
+
Number of detectors.
|
469
|
+
aff_thresh : float, default=0.1
|
470
|
+
The variable represents the percentage of similarity between the T cell and the own
|
471
|
+
samples. The default value is 10% (0.1), while a value of 1.0 represents 100% similarity.
|
472
|
+
max_discards : int, default=1000
|
473
|
+
This parameter indicates the maximum number of detector discards in sequence, which aims
|
474
|
+
to avoid a possible infinite loop if a radius is defined that it is not possible to
|
475
|
+
generate non-self detectors.
|
476
|
+
seed : Optional[int], default=None
|
477
|
+
Seed for the random generation of values in the detectors.
|
478
|
+
no_label_sample_selection : str, default="max_average_difference"
|
479
|
+
Method for selecting labels for samples designated as non-self by all detectors.
|
480
|
+
Available method types:
|
481
|
+
|
482
|
+
- max_average_difference - Selects the class with the highest average difference among the
|
483
|
+
detectors.
|
484
|
+
|
485
|
+
- max_nearest_difference - Selects the class with the highest difference between the
|
486
|
+
nearest and farthest detector from the sample.
|
473
487
|
"""
|
474
488
|
|
475
489
|
def __init__(
|
@@ -482,8 +496,6 @@ class BNSA(BaseNSA):
|
|
482
496
|
"max_average_difference", "max_nearest_difference"
|
483
497
|
] = "max_average_difference",
|
484
498
|
):
|
485
|
-
super().__init__()
|
486
|
-
|
487
499
|
self.N: int = sanitize_param(N, 100, lambda x: x > 0)
|
488
500
|
self.aff_thresh: float = sanitize_param(aff_thresh, 0.1, lambda x: 0 < x < 1)
|
489
501
|
self.max_discards: float = sanitize_param(max_discards, 1000, lambda x: x > 0)
|
@@ -503,23 +515,28 @@ class BNSA(BaseNSA):
|
|
503
515
|
self._detectors: Optional[dict] = None
|
504
516
|
self._detectors_stack: npt.NDArray = None
|
505
517
|
|
518
|
+
@property
|
519
|
+
def detectors(self) -> Dict[str, npt.NDArray[np.bool_]]:
|
520
|
+
"""Returns the trained detectors, organized by class."""
|
521
|
+
return self._detectors
|
522
|
+
|
506
523
|
def fit(self, X: npt.NDArray, y: npt.NDArray, verbose: bool = True):
|
507
|
-
"""
|
508
|
-
The function ``fit(...)``, performs the training according to ``X`` and ``y``, using the
|
509
|
-
method negative selection method(``NegativeSelect``).
|
524
|
+
"""Training according to X and y, using the method negative selection method.
|
510
525
|
|
511
526
|
Parameters
|
512
527
|
----------
|
513
|
-
|
514
|
-
Training array, containing the samples and their characteristics,
|
515
|
-
|
516
|
-
|
528
|
+
X : npt.NDArray
|
529
|
+
Training array, containing the samples and their characteristics, [``N samples`` (
|
530
|
+
rows)][``N features`` (columns)].
|
531
|
+
y : npt.NDArray
|
517
532
|
Array of target classes of ``X`` with [``N samples`` (lines)].
|
518
|
-
|
533
|
+
verbose : bool, default=True
|
534
|
+
Feedback from detector generation to the user.
|
519
535
|
|
520
536
|
Returns
|
521
|
-
|
522
|
-
|
537
|
+
-------
|
538
|
+
self : BNSA
|
539
|
+
Returns the instance it self.
|
523
540
|
"""
|
524
541
|
super()._check_and_raise_exceptions_fit(X, y, "BNSA")
|
525
542
|
|
@@ -531,7 +548,7 @@ class BNSA(BaseNSA):
|
|
531
548
|
# Dictionary that will store detectors with classes as keys.
|
532
549
|
list_detectors_by_class = {}
|
533
550
|
# Separates the classes for training.
|
534
|
-
sample_index: dict = self.
|
551
|
+
sample_index: dict = self._slice_index_list_by_class(y)
|
535
552
|
# Progress bar for generating all detectors.
|
536
553
|
if verbose:
|
537
554
|
progress = tqdm(
|
@@ -581,20 +598,19 @@ class BNSA(BaseNSA):
|
|
581
598
|
return self
|
582
599
|
|
583
600
|
def predict(self, X: npt.NDArray) -> Optional[npt.NDArray]:
|
584
|
-
"""
|
585
|
-
Function to perform the prediction of classes based on detectors
|
586
|
-
created after training.
|
601
|
+
"""Prediction of classes based on detectors created after training.
|
587
602
|
|
588
603
|
Parameters
|
589
604
|
----------
|
590
|
-
|
591
|
-
[``
|
605
|
+
X : npt.NDArray
|
606
|
+
Array with input samples with [``N_samples`` (Lines)] and [``N_characteristics``(
|
607
|
+
Columns)]
|
592
608
|
|
593
609
|
Returns
|
594
|
-
|
595
|
-
|
596
|
-
containing the predicted classes for
|
597
|
-
|
610
|
+
-------
|
611
|
+
c : Optional[npt.NDArray]
|
612
|
+
an ndarray of the form ``C`` [``N samples``], containing the predicted classes for
|
613
|
+
``X``. Returns``None``: If there are no detectors for the prediction.
|
598
614
|
"""
|
599
615
|
# If there are no detectors, Returns None.
|
600
616
|
if self._detectors is None:
|
@@ -636,19 +652,17 @@ class BNSA(BaseNSA):
|
|
636
652
|
return np.array(c)
|
637
653
|
|
638
654
|
def __assign_class_to_non_self_sample(self, line: npt.NDArray, c: list):
|
639
|
-
"""
|
640
|
-
|
641
|
-
|
642
|
-
|
655
|
+
"""Determine the class of a sample when all detectors classify it as "non-self".
|
656
|
+
|
657
|
+
Classification is performed using the ``max_average_difference`` and
|
658
|
+
``max_nearest_difference`` methods.
|
643
659
|
|
644
660
|
Parameters
|
645
661
|
----------
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
----------
|
651
|
-
* list: The list of predictions `c` updated with the class assigned to the sample.
|
662
|
+
line : npt.NDArray
|
663
|
+
Sample to be classified.
|
664
|
+
c : list
|
665
|
+
List of predictions to be updated with the new classification.
|
652
666
|
"""
|
653
667
|
class_differences: dict = {}
|
654
668
|
for _class_ in self.classes:
|
@@ -662,21 +676,3 @@ class BNSA(BaseNSA):
|
|
662
676
|
class_differences[_class_] = distances.sum() / self.N
|
663
677
|
|
664
678
|
c.append(max(class_differences, key=class_differences.get))
|
665
|
-
|
666
|
-
def __slice_index_list_by_class(self, y: npt.NDArray) -> dict:
|
667
|
-
"""
|
668
|
-
The function ``__slice_index_list_by_class(...)``, separates the indices of the lines
|
669
|
-
according to the output class, to loop through the sample array, only in positions where
|
670
|
-
the output is the class being trained.
|
671
|
-
|
672
|
-
Parameters
|
673
|
-
----------
|
674
|
-
* y (``npt.NDArray``):
|
675
|
-
Receives a ``y``[``N sample``] array with the output classes of the ``X``
|
676
|
-
sample array.
|
677
|
-
|
678
|
-
Returns
|
679
|
-
----------
|
680
|
-
* dict: A dictionary with the list of array positions(``y``), with the classes as key.
|
681
|
-
"""
|
682
|
-
return slice_index_list_by_class(self.classes, y)
|