aisp 0.1.21__py3-none-any.whl → 0.1.31__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.
@@ -1,52 +1,57 @@
1
1
  import numpy as np
2
2
  import numpy.typing as npt
3
3
  from tqdm import tqdm
4
- from typing import Dict, Literal, Union
4
+ from typing import Dict, Literal, Optional, Union
5
5
  from collections import namedtuple
6
6
  from scipy.spatial.distance import hamming
7
7
 
8
- from aisp._base import Base
8
+ from ._base import Base
9
9
 
10
10
 
11
11
  class RNSA(Base):
12
12
  """
13
- The ``RNSA`` (Real-Valued Negative Selection Algorithm) class is for classification and identification purposes.
14
- of anomalies through the self and not self method.
13
+ The ``RNSA`` (Real-Valued Negative Selection Algorithm) class is for classification and \
14
+ identification purposes. of anomalies through the self and not self method.
15
15
 
16
16
  Attributes:
17
17
  ---
18
18
  * N (``int``): Number of detectors.
19
19
  * r (``float``): Radius of the detector.
20
20
  * r_s (``float``): rₛ Radius of the ``X`` own samples.
21
- * k (``int``): K number of near neighbors to calculate the average distance of the detectors.
21
+ * k (``int``): K number of near neighbors to calculate the average
22
+ distance of the detectors.
22
23
  * metric (``str``): Way to calculate the distance: ``'euclidean', 'minkowski', or 'manhattan'``.
23
- * max_discards (``int``): This parameter indicates the maximum number of consecutive detector discards,
24
- aimed at preventing a possible infinite loop in case a radius is defined that cannot generate non-self
25
- detectors.
24
+ * max_discards (``int``): This parameter indicates the maximum number of consecutive \
25
+ detector discards, aimed at preventing a possible infinite loop in case a radius is \
26
+ defined that cannot generate non-self detectors.
26
27
  * seed (``int``): Seed for the random generation of detector values.
27
28
  * algorithm(``str``), Set the algorithm version:
28
29
 
29
30
  * ``'default-NSA'``: Default algorithm with fixed radius.
30
- * ``'V-detector'``: This algorithm uses a variable radius for anomaly detection in feature spaces.
31
+ * ``'V-detector'``: This algorithm uses a variable radius for anomaly detection \
32
+ in feature spaces.
31
33
 
32
34
  Defaults to ``'default-NSA'``.
33
35
 
34
- * non_self_label (``str``): This variable stores the label that will be assigned when the data has only one
35
- output class, and the sample is classified as not belonging to that class. Defaults to ``'non-self'``.
36
- * cell_bounds (``bool``): If set to ``True``, this option limits the generation of detectors to the space within
37
- the plane between 0 and 1. This means that any detector whose radius exceeds this limit is discarded,
38
- this variable is only used in the ``V-detector`` algorithm. Defaults to ``False``.
39
- * p (``float``): This parameter stores the value of ``p`` used in the Minkowski distance. The default is ``2``, which
40
- represents normalized Euclidean distance. Different values of p lead to different variants of the Minkowski
41
- distance [learn more](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.minkowski.html).
42
-
36
+ * non_self_label (``str``): This variable stores the label that will be when the data has \
37
+ only one output class, and the sample is classified as not belonging to that class. \
38
+ Defaults to ``'non-self'``.
39
+ * cell_bounds (``bool``): If set to ``True``, this option limits the generation of \
40
+ detectors to the space within the plane between 0 and 1. This means that any detector \
41
+ whose radius exceeds this limit is discarded, this variable is only used in the \
42
+ ``V-detector`` algorithm. Defaults to ``False``.
43
+ * p (``float``): This parameter stores the value of ``p`` used in the Minkowski distance. \
44
+ The default is ``2``, which represents normalized Euclidean distance. Different values \
45
+ of p lead to different variants of the Minkowski distance \
46
+ [learn more](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.minkowski.html).
47
+
43
48
  * detectors (``dict``): This variable stores a list of detectors by class.
44
49
  * classes (``npt.NDArray``): list of output classes.
45
-
50
+
46
51
  ---
47
52
 
48
- A classe ``RNSA`` (Algoritmo de Seleção Negativa de Valor Real) tem a finalidade de classificação e identificação
49
- de anomalias através do método self e not self .
53
+ A classe ``RNSA`` (Algoritmo de Seleção Negativa de Valor Real) tem a finalidade de classificação \
54
+ e identificação de anomalias através do método self e not self .
50
55
 
51
56
  Attributes:
52
57
  ---
@@ -55,134 +60,154 @@ class RNSA(Base):
55
60
  * r_s (``float``): O valor de ``rₛ`` é o raio das amostras próprias da matriz ``X``.
56
61
  * k (``int``): K quantidade de vizinhos próximos para calcular a média da distância dos detectores.
57
62
  * metric (``str``): Forma de calcular a distância: ``'euclidiana', 'minkowski', or 'manhattan'``.
58
- * max_discards (``int``): Este parâmetro indica o número máximo de descartes de detectores em sequência,
59
- que tem como objetivo evitar um possível loop infinito caso seja definido um raio que não seja possível
60
- gerar detectores do não-próprio.
63
+ * max_discards (``int``): Este parâmetro indica o número máximo de descartes de detectores \
64
+ em sequência, que tem como objetivo evitar um possível loop infinito caso seja definido \
65
+ um raio que não seja possível gerar detectores do não-próprio.
61
66
  * seed (``int``): Semente para a geração randômica dos valores dos detectores.
62
67
  * algorithm (``str``), Definir a versão do algoritmo:
63
68
 
64
69
  * ``'default-NSA'``: Algoritmo padrão com raio fixo.
65
- * ``'V-detector'``: Este algoritmo utiliza um raio variável para a detecção de anomalias em espaços
66
- de características.
70
+ * ``'V-detector'``: Este algoritmo utiliza um raio variável para a detecção de \
71
+ anomalias em espaços de características.
67
72
 
68
73
  Defaults to ``'default-NSA'``.
69
74
 
70
- * non_self_label (``str``): Esta variável armazena o rótulo que será atribuído quando os dados possuírem
71
- apenas uma classe de saída, e a amostra for classificada como não pertencente a essa classe. Defaults to ``'non-self'``.
72
- * cell_bounds (``bool``): Se definido como ``True``, esta opção limita a geração dos detectores ao espaço do plano
73
- compreendido entre 0 e 1. Isso significa que qualquer detector cujo raio ultrapasse esse limite é descartado,
74
- e esta variável é usada exclusivamente no algoritmo ``V-detector``.
75
- * p (``float``): Este parâmetro armazena o valor de ``p`` utilizada na distância de Minkowski. O padrão é ``2``, o que significa
76
- distância euclidiana normalizada. Diferentes valores de p levam a diferentes variantes da distância de
77
- Minkowski [saiba mais](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.minkowski.html).
78
-
75
+ * non_self_label (``str``): Esta variável armazena o rótulo que será atribuído quando \
76
+ os dados possuírem apenas uma classe de saída, e a amostra for classificada como não \
77
+ pertencente a essa classe. Defaults to ``'non-self'``.
78
+ * cell_bounds (``bool``): Se definido como ``True``, esta opção limita a geração dos \
79
+ detectores ao espaço do plano compreendido entre 0 e 1. Isso significa que qualquer \
80
+ detector cujo raio ultrapasse esse limite é descartado, e esta variável é usada \
81
+ exclusivamente no algoritmo ``V-detector``.
82
+ * p (``float``): Este parâmetro armazena o valor de ``p`` utilizada na distância de \
83
+ Minkowski. O padrão é ``2``, o que significa distância euclidiana normalizada. \
84
+ Diferentes valores de p levam a diferentes variantes da distância de Minkowski \
85
+ [saiba mais](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.minkowski.html).
86
+
79
87
  * detectors (``dict``): Essa variável armazena uma lista com detectores por classes.
80
88
  * classes (``npt.NDArray``): lista com as classes de saída.
81
89
  """
82
-
83
- def __init__(
84
- self,
85
- N: int = 100,
86
- r: float = 0.05,
87
- r_s: float = 0.0001,
88
- k: int = 1,
89
- metric: Literal['manhattan', 'minkowski', 'euclidean'] = 'euclidean',
90
- max_discards: int = 1000,
91
- seed: int = None,
92
- algorithm: Literal['default-NSA', 'V-detector'] ='default-NSA',
93
- **kwargs: Dict[str, Union[bool, str, float]]
94
- ):
90
+
91
+ def __init__(self, N: int = 100, r: float = 0.05, r_s: float = 0.0001, k: int = 1,
92
+ metric: Literal["manhattan", "minkowski", "euclidean"] = "euclidean", max_discards: int = 1000,
93
+ seed: int = None, algorithm: Literal["default-NSA", "V-detector"] = "default-NSA",
94
+ **kwargs: Dict[str, Union[bool, str, float]]):
95
95
  """
96
96
  Negative Selection class constructor (``RNSA``).
97
97
 
98
98
  Details:
99
99
  ---
100
- This method initializes the ``detectors``, ``classes``, ``k``, ``metric``, ``N``, ``r``, ``r_S``,
101
- ``max_discards``, ``seed`` and ``algorithm`` attributes.
100
+ This method initializes the ``detectors``, ``classes``, ``k``, ``metric``, ``N``, ``r``, \
101
+ ``r_S``, ``max_discards``, ``seed`` and ``algorithm`` attributes.
102
102
 
103
103
  Parameters:
104
104
  ---
105
105
  * N (``int``): Number of detectors. Defaults to ``100``.
106
106
  * r (``float``): Radius of the detector. Defaults to ``0.05``.
107
107
  * r_s (``float``): rₛ Radius of the ``X`` own samples. Defaults to ``0.0001``.
108
- * k (``int``): Number of neighbors near the randomly generated detectors to perform the
109
- distance average calculation. Defaults to ``1``.
108
+ * k (``int``): Number of neighbors near the randomly generated detectors to perform the \
109
+ distance average calculation. Defaults to ``1``.
110
110
  * metric (``str``): Way to calculate the distance between the detector and the sample:
111
111
 
112
- * ``'Euclidean'`` ➜ The calculation of the distance is given by the expression: √( (x₁ – x₂)² + (y₁ – y₂)² + ... + (yn – yn)²).
113
- * ``'minkowski'`` ➜ The calculation of the distance is given by the expression: ( |X₁ – Y₁|p + |X₂Y₂|p + ... + |XnYn|p) ¹/ₚ.
114
- * ``'manhattan'`` ➜ The calculation of the distance is given by the expression: ( |x₁ – x₂| + |y₁ – y₂| + ... + |yn – yn|) .
112
+ * ``'Euclidean'`` ➜ The calculation of the distance is given by the expression: \
113
+ √( (x₁ – x₂)² + (y₁y₂)² + ... + (ynyn)²).
114
+ * ``'minkowski'`` ➜ The calculation of the distance is given by the expression: \
115
+ ( |X₁ – Y₁|p + |X₂ – Y₂|p + ... + |Xn – Yn|p) ¹/ₚ.
116
+ * ``'manhattan'`` ➜ The calculation of the distance is given by the expression: \
117
+ ( |x₁ – x₂| + |y₁ – y₂| + ... + |yn – yn|) .
115
118
 
116
119
  Defaults to ``'euclidean'``.
117
120
 
118
- * max_discards (``int``): This parameter indicates the maximum number of consecutive detector discards, aimed at preventing a
119
- possible infinite loop in case a radius is defined that cannot generate non-self detectors. Defaults to ``1000``.
120
- * seed (``int``): Seed for the random generation of values in the detectors. Defaults to ``None``.
121
+ * max_discards (``int``): This parameter indicates the maximum number of consecutive \
122
+ detector discards, aimed at preventing a possible infinite loop in case a radius is \
123
+ defined that cannot generate non-self detectors. Defaults to ``1000``.
124
+ * seed (``int``): Seed for the random generation of values in the detectors. Defaults \
125
+ to ``None``.
121
126
 
122
127
  * algorithm(``str``), Set the algorithm version:
123
128
 
124
129
  * ``'default-NSA'``: Default algorithm with fixed radius.
125
- * ``'V-detector'``: This algorithm is based on the article "[Real-Valued Negative Selection Algorithm with Variable-Sized Detectors](https://doi.org/10.1007/978-3-540-24854-5_30)", by Ji, Z., Dasgupta, D. (2004), and uses a variable radius for anomaly detection in feature spaces.
130
+ * ``'V-detector'``: This algorithm is based on the article \
131
+ "[Real-Valued Negative Selection Algorithm with Variable-Sized Detectors](https://doi.org/10.1007/978-3-540-24854-5_30)", \
132
+ by Ji, Z., Dasgupta, D. (2004), and uses a variable radius for anomaly \
133
+ detection in feature spaces.
126
134
 
127
135
  Defaults to ``'default-NSA'``.
128
136
 
129
137
  - ``**kwargs``:
130
- - non_self_label (``str``): This variable stores the label that will be assigned when the data has only one
131
- output class, and the sample is classified as not belonging to that class. Defaults to ``'non-self'``.
132
- - cell_bounds (``bool``): If set to ``True``, this option limits the generation of detectors to the space within
133
- the plane between 0 and 1. This means that any detector whose radius exceeds this limit is discarded,
134
- this variable is only used in the ``V-detector`` algorithm. Defaults to ``False``.
135
- - p (``float``): This parameter stores the value of ``p`` used in the Minkowski distance. The default is ``2``, which
136
- represents normalized Euclidean distance. Different values of p lead to different variants of the Minkowski
137
- distance [learn more](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.minkowski.html).
138
+ - non_self_label (``str``): This variable stores the label that will be assigned \
139
+ when the data has only one output class, and the sample is classified as not \
140
+ belonging to that class. Defaults to ``'non-self'``.
141
+ - cell_bounds (``bool``): If set to ``True``, this option limits the generation \
142
+ of detectors to the space within the plane between 0 and 1. This means that \
143
+ any detector whose radius exceeds this limit is discarded, this variable is \
144
+ only used in the ``V-detector`` algorithm. Defaults to ``False``.
145
+ - p (``float``): This parameter stores the value of ``p`` used in the Minkowski \
146
+ distance. The default is ``2``, which represents normalized Euclidean distance. \
147
+ Different values of p lead to different variants of the Minkowski distance \
148
+ [learn more](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.minkowski.html).
138
149
  ---
139
150
 
140
151
  Construtor da classe de Seleção negativa (``RNSA``).
141
152
 
142
153
  Details:
143
154
  ---
144
- Este método inicializa os atributos ``detectors``, ``classes``, ``k``, ``metric``, ``N``, ``r`` e ``seed``.
155
+ Este método inicializa os atributos ``detectors``, ``classes``, ``k``, ``metric``, ``N``, \
156
+ ``r`` e ``seed``.
145
157
 
146
158
  Parameters:
147
159
  ---
148
160
  * N (``int``): Quantidade de detectores. Defaults to ``100``.
149
161
  * r (``float``): Raio do detector. Defaults to ``0.05``.
150
- * r_s (``float``): O valor de ``rₛ`` é o raio das amostras próprias da matriz ``X``. Defaults to ``0.0001``.
151
- * k (``int``): Quantidade de vizinhos próximos dos detectores gerados aleatoriamente para efetuar o
152
- cálculo da média da distância. Defaults to ``1``.
162
+ * r_s (``float``): O valor de ``rₛ`` é o raio das amostras próprias da matriz ``X``. \
163
+ Defaults to ``0.0001``.
164
+ * k (``int``): Quantidade de vizinhos próximos dos detectores gerados aleatoriamente \
165
+ para efetuar o cálculo da média da distância. Defaults to ``1``.
153
166
  * metric (``str``): Forma para se calcular a distância entre o detector e a amostra:
154
167
 
155
- * ``'euclidiana'`` ➜ O cálculo da distância dá-se pela expressão: √( (x₁ – x₂)² + (y₁ – y₂)² + ... + (yn – yn)²).
156
- * ``'minkowski'`` ➜ O cálculo da distância dá-se pela expressão: ( |X₁ – Y₁|p + |X₂Y₂|p + ... + |XnYn|p) ¹/ₚ.
157
- * ``'manhattan'`` ➜ O cálculo da distância dá-se pela expressão: ( |x₁ – x₂| + |y₁ – y₂| + ... + |yn – yn|).
168
+ * ``'euclidiana'`` ➜ O cálculo da distância dá-se pela expressão: \
169
+ √( (x₁ – x₂)² + (y₁y₂)² + ... + (ynyn)²).
170
+ * ``'minkowski'`` ➜ O cálculo da distância dá-se pela expressão: \
171
+ ( |X₁ – Y₁|p + |X₂ – Y₂|p + ... + |Xn – Yn|p) ¹/ₚ.
172
+ * ``'manhattan'`` ➜ O cálculo da distância dá-se pela expressão: \
173
+ ( |x₁ – x₂| + |y₁ – y₂| + ... + |yn – yn|).
158
174
 
159
175
  Defaults to ``'euclidean'``.
160
176
 
161
- * max_discards (``int``): Este parâmetro indica o número máximo de descartes de detectores em sequência, que tem como objetivo evitar um
162
- possível loop infinito caso seja definido um raio que não seja possível gerar detectores do não-próprio. Defaults to ``1000``.
163
- * seed (``int``): Semente para a geração randômica dos valores nos detectores. Defaults to ``None``.
177
+ * max_discards (``int``): Este parâmetro indica o número máximo de descartes de detectores \
178
+ em sequência, que tem como objetivo evitar um possível loop infinito caso seja definido \
179
+ um raio que não seja possível gerar detectores do não-próprio. Defaults to ``1000``.
180
+ * seed (``int``): Semente para a geração randômica dos valores nos detectores. \
181
+ Defaults to ``None``.
164
182
  * algorithm (``str``), Definir a versão do algoritmo:
165
183
 
166
184
  * ``'default-NSA'``: Algoritmo padrão com raio fixo.
167
- * ``'V-detector'``: Este algoritmo é baseado no artigo "[Real-Valued Negative Selection Algorithm with Variable-Sized Detectors](https://doi.org/10.1007/978-3-540-24854-5_30)", de autoria de Ji, Z., Dasgupta, D. (2004), e utiliza um raio variável para a detecção de anomalias em espaços de características.
185
+ * ``'V-detector'``: Este algoritmo é baseado no artigo \
186
+ "[Real-Valued Negative Selection Algorithm with Variable-Sized Detectors](https://doi.org/10.1007/978-3-540-24854-5_30)", \
187
+ de autoria de Ji, Z., Dasgupta, D. (2004), e utiliza um raio variável para a \
188
+ detecção de anomalias em espaços de características.
168
189
 
169
190
  Defaults to ``'default-NSA'``.
170
191
 
171
192
  - ``**kwargs``:
172
- - non_self_label (``str``): Esta variável armazena o rótulo que será atribuído quando os dados possuírem
173
- apenas uma classe de saída, e a amostra for classificada como não pertencente a essa classe. Defaults to ``'non-self'``.
174
- - cell_bounds (``bool``): Se definido como ``True``, esta opção limita a geração dos detectores ao espaço do plano
175
- compreendido entre 0 e 1. Isso significa que qualquer detector cujo raio ultrapasse esse limite é descartado,
176
- e esta variável é usada exclusivamente no algoritmo ``V-detector``.
177
- - p (``float``): Este parâmetro armazena o valor de ``p`` utilizada na distância de Minkowski. O padrão é ``2``, o que significa
178
- distância euclidiana normalizada. Diferentes valores de p levam a diferentes variantes da distância de
179
- Minkowski [saiba mais](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.minkowski.html).
193
+ - non_self_label (``str``): Esta variável armazena o rótulo que será atribuído \
194
+ quando os dados possuírem apenas uma classe de saída, e a amostra for \
195
+ classificada como não pertencente a essa classe. Defaults to ``'non-self'``.
196
+ - cell_bounds (``bool``): Se definido como ``True``, esta opção limita a \
197
+ geração dos detectores ao espaço do plano compreendido entre 0 e 1. Isso \
198
+ significa que qualquer detector cujo raio ultrapasse esse limite é descartado, \
199
+ e esta variável é usada exclusivamente no algoritmo ``V-detector``.
200
+ - p (``float``): Este parâmetro armazena o valor de ``p`` utilizada na distância \
201
+ de Minkowski. O padrão é ``2``, o que significa distância euclidiana normalizada. \
202
+ Diferentes valores de p levam a diferentes variantes da distância de Minkowski \
203
+ [saiba mais](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.minkowski.html).
180
204
  """
181
-
182
- if metric == 'manhattan' or metric == 'minkowski' or metric == 'euclidean':
205
+
206
+ super().__init__(metric)
207
+ if metric == "manhattan" or metric == "minkowski":
183
208
  self.metric = metric
184
209
  else:
185
- self.metric = 'euclidean'
210
+ self.metric = "euclidean"
186
211
 
187
212
  if seed is not None and isinstance(seed, int):
188
213
  np.random.seed(seed)
@@ -204,18 +229,18 @@ class RNSA(Base):
204
229
  self.r: float = 0.05
205
230
  else:
206
231
  self.r: float = r
207
-
232
+
208
233
  if r_s > 0:
209
234
  self.r_s: float = r_s
210
235
  else:
211
236
  self.r_s: float = 0
212
237
 
213
- if algorithm == 'V-detector':
238
+ if algorithm == "V-detector":
214
239
  self._Detector = namedtuple("Detector", "position radius")
215
240
  self._algorithm: str = algorithm
216
241
  else:
217
242
  self._Detector = namedtuple("Detector", "position")
218
- self._algorithm: str = 'default-NSA'
243
+ self._algorithm: str = "default-NSA"
219
244
 
220
245
  if max_discards > 0:
221
246
  self.max_discards: int = max_discards
@@ -223,10 +248,11 @@ class RNSA(Base):
223
248
  self.max_discards: int = 1000
224
249
 
225
250
  # Obtém as variáveis do kwargs.
226
- self.p: float = kwargs.get('p', 2)
227
- self._cell_bounds: bool = kwargs.get('cell_bounds', False)
228
- self.non_self_label: str = kwargs.get('non_self_label', 'non-self')
229
-
251
+ self.p: float = kwargs.get("p", 2)
252
+ self._cell_bounds: bool = kwargs.get("cell_bounds", False)
253
+ self.non_self_label: str = kwargs.get("non_self_label", "non-self")
254
+
255
+ # Inicializa as demais variáveis da classe como None
230
256
  self.detectors: Union[dict, None] = None
231
257
  self.classes: npt.NDArray = None
232
258
 
@@ -237,8 +263,8 @@ class RNSA(Base):
237
263
 
238
264
  Parameters:
239
265
  ---
240
- * X (``npt.NDArray``): Training array, containing the samples and their characteristics,
241
- [``N samples`` (rows)][``N features`` (columns)].
266
+ * X (``npt.NDArray``): Training array, containing the samples and their characteristics, \
267
+ [``N samples`` (rows)][``N features`` (columns)].
242
268
  * y (``npt.NDArray``): Array of target classes of ``X`` with [``N samples`` (lines)].
243
269
  * verbose (``bool``): Feedback from detector generation to the user.
244
270
  returns:
@@ -247,13 +273,13 @@ class RNSA(Base):
247
273
 
248
274
  ----
249
275
 
250
- A função ``fit(...)``, realiza o treinamento de acordo com ``X`` e ``y``, usando o método
276
+ A função ``fit(...)``, realiza o treinamento de acordo com ``X`` e ``y``, usando o método
251
277
  de seleção negativa(``NegativeSelect``).
252
278
 
253
279
  Parameters:
254
280
  ---
255
- * X (``npt.NDArray``): Array de treinamento, contendo as amostras é suas características,
256
- [``N amostras`` (linhas)][``N características`` (colunas)].
281
+ * X (``npt.NDArray``): Array de treinamento, contendo as amostras é suas características, \
282
+ [``N amostras`` (linhas)][``N características`` (colunas)].
257
283
  * y (``npt.NDArray``): Array com as classes alvos de ``X`` com [``N amostras`` (linhas)].
258
284
  * verbose (``bool``): Feedback da geração de detectores para o usuário.
259
285
  Returns:
@@ -261,7 +287,7 @@ class RNSA(Base):
261
287
  (``self``): Retorna a própria instância.
262
288
  """
263
289
  super()._check_and_raise_exceptions_fit(X, y)
264
-
290
+
265
291
  # Identificando as classes possíveis, dentro do array de saídas ``y``.
266
292
  self.classes = np.unique(y)
267
293
  # Dict que armazenará os detectores com as classes como key.
@@ -271,7 +297,7 @@ class RNSA(Base):
271
297
  # Barra de progresso para a geração de todos os detectores.
272
298
  if verbose:
273
299
  progress = tqdm(total=int(self.N * (len(self.classes))),
274
- bar_format='{desc} ┇{bar}┇ {n}/{total} detectors', postfix='\n')
300
+ bar_format="{desc} ┇{bar}┇ {n}/{total} detectors", postfix="\n",)
275
301
  for _class_ in self.classes:
276
302
  # Inicia o conjunto vazio que conterá os detectores válidos.
277
303
  valid_detectors_set = []
@@ -279,19 +305,22 @@ class RNSA(Base):
279
305
  # Informando em qual classe o algoritmo está para a barra de progresso.
280
306
  if verbose:
281
307
  progress.set_description_str(
282
- f'Generating the detectors for the {_class_} class:')
308
+ f"Generating the detectors for the {_class_} class:"
309
+ )
283
310
  while len(valid_detectors_set) < self.N:
284
311
  # Gera um vetor candidato a detector aleatoriamente com valores entre 0 e 1.
285
312
  vector_x = np.random.random_sample(size=X.shape[1])
286
313
  # Verifica a validade do detector para o não-próprio com relação às amostras da classe.
287
314
  valid_detector = self.__checks_valid_detector(
288
- X=X, vector_x=vector_x, samples_index_class=sample_index[_class_])
289
-
315
+ X=X, vector_x=vector_x, samples_index_class=sample_index[_class_]
316
+ )
317
+
290
318
  # Se o detector for válido, adicione a lista dos válidos.
291
- if self._algorithm == 'V-detector' and valid_detector != False:
319
+ if self._algorithm == "V-detector" and valid_detector is not False:
292
320
  discard_count = 0
293
321
  valid_detectors_set.append(
294
- self._Detector(vector_x, valid_detector[1]))
322
+ self._Detector(vector_x, valid_detector[1])
323
+ )
295
324
  if verbose:
296
325
  progress.update(1)
297
326
  elif valid_detector:
@@ -302,21 +331,26 @@ class RNSA(Base):
302
331
  else:
303
332
  discard_count += 1
304
333
  if discard_count == self.max_discards:
305
- raise Exception('An error has been identified:\n'+
306
- f'the maximum number of discards of detectors for the {_class_} class has been reached.\n'+
307
- 'It is recommended to check the defined radius and consider reducing its value.')
308
-
334
+ raise Exception(
335
+ "An error has been identified:\n"
336
+ f"the maximum number of discards of detectors for the {_class_} class "
337
+ "has been reached.\nIt is recommended to check the defined radius and "
338
+ "consider reducing its value."
339
+ )
340
+
309
341
  # Adicionar detectores, com as classes como chave na dict.
310
342
  list_detectors_by_class[_class_] = valid_detectors_set
311
343
  # Informar a finalização da geração dos detectores para as classes.
312
344
  if verbose:
313
345
  progress.set_description(
314
- f'\033[92m✔ Non-self detectors for classes ({", ".join(map(str, self.classes))}) successfully generated\033[0m')
346
+ f'\033[92m✔ Non-self detectors for classes ({", ".join(map(str, self.classes))}) '
347
+ f'successfully generated\033[0m'
348
+ )
315
349
  # Armazena os detectores encontrados no atributo, para os detectores da classe.
316
350
  self.detectors = list_detectors_by_class
317
351
  return self
318
352
 
319
- def predict(self, X: npt.NDArray) -> npt.NDArray:
353
+ def predict(self, X: npt.NDArray) -> Optional[npt.NDArray]:
320
354
  """
321
355
  Function to perform the prediction of classes based on detectors
322
356
  created after training.
@@ -334,31 +368,34 @@ class RNSA(Base):
334
368
 
335
369
  ---
336
370
 
337
- Função para efetuar a previsão das classes com base nos detectores
371
+ Função para efetuar a previsão das classes com base nos detectores
338
372
  criados após o treinamento.
339
373
 
340
374
  Parameters:
341
375
  ---
342
- * X (``npt.NDArray``): Array com as amostras de entradas com [``N amostras`` (Linhas)] e
376
+ * X (``npt.NDArray``): Array com as amostras de entradas com [``N amostras`` (Linhas)] e
343
377
  [``N características``(Colunas)]
344
378
 
345
379
  Returns:
346
380
  ---
347
- * C – (``npt.NDArray``): um ndarray de forma ``C`` [``N amostras``],
381
+ * C – (``npt.NDArray``): um ndarray de forma ``C`` [``N amostras``],
348
382
  contendo as classes previstas para ``X``.
349
383
  * ``None``: Se não existir detectores para a previsão.
350
384
  """
351
385
  # se não houver detectores retorna None.
352
386
  if self.detectors is None:
353
387
  return None
354
- elif not isinstance(X, (np.ndarray, list)):
388
+ elif not isinstance(X, (np.ndarray, list)):
355
389
  raise TypeError("X is not an ndarray or list")
356
390
  elif len(self.detectors[self.classes[0]][0].position) != len(X[0]):
357
- raise Exception('X does not have {} features to make the prediction'.format(
358
- len(self.detectors[self.classes[0]][0])))
391
+ raise Exception(
392
+ "X does not have {} features to make the prediction".format(
393
+ len(self.detectors[self.classes[0]][0])
394
+ )
395
+ )
359
396
 
360
397
  # Inicia um array vazio.
361
- C = np.empty(shape=(0))
398
+ C = np.empty(shape=0)
362
399
  # Para cada linha de amostra em X.
363
400
  for line in X:
364
401
  class_found: bool
@@ -372,26 +409,32 @@ class RNSA(Base):
372
409
  # Se possuir apenas uma classe e não classificar a amostra define a saída como não-própria.
373
410
  if not class_found and len(self.classes) == 1:
374
411
  C = np.append(C, [self.non_self_label])
375
- # Se não identificar a classe com os detectores, coloca a classe com a maior distância da média dos seus detectores.
412
+ # Se não identificar a classe com os detectores, coloca a classe com a maior distância
413
+ # da média dos seus detectores.
376
414
  elif not class_found:
377
- average_distance = dict()
415
+ average_distance: dict = {}
378
416
  for _class_ in self.classes:
379
417
  detectores = list(
380
- map(lambda x: x.position, self.detectors[_class_]))
381
- average_distance[_class_] = self.__distance(
382
- np.average(detectores, axis=0), line)
418
+ map(lambda x: x.position, self.detectors[_class_])
419
+ )
420
+ average_distance[_class_] = np.average(
421
+ [self.__distance(detector, line)
422
+ for detector in detectores]
423
+ )
383
424
  C = np.append(
384
425
  C, [max(average_distance, key=average_distance.get)])
385
426
  return C
386
427
 
387
- def __checks_valid_detector(self, X: npt.NDArray = None, vector_x: npt.NDArray = None, samples_index_class: npt.NDArray = None):
428
+ def __checks_valid_detector(self, X: npt.NDArray = None, vector_x: npt.NDArray = None,
429
+ samples_index_class: npt.NDArray = None):
388
430
  """
389
431
  Function to check if the detector has a valid non-proper ``r`` radius for the class.
390
432
 
391
433
  Parameters:
392
434
  ---
393
435
  * X (``npt.NDArray``): Array ``X`` with the samples.
394
- * vector_x (``npt.NDArray``): Randomly generated vector x candidate detector with values ​​between [0, 1].
436
+ * vector_x (``npt.NDArray``): Randomly generated vector x candidate detector with values \
437
+ ​​between [0, 1].
395
438
  * samples_index_class (``npt.NDArray``): Sample positions of a class in ``X``.
396
439
 
397
440
  returns:
@@ -405,7 +448,8 @@ class RNSA(Base):
405
448
  Parameters:
406
449
  ---
407
450
  * X (``npt.NDArray``): Array ``X`` com as amostras.
408
- * vector_x (``npt.NDArray``): Vetor x candidato a detector gerado aleatoriamente com valores entre [0, 1].
451
+ * vector_x (``npt.NDArray``): Vetor x candidato a detector gerado aleatoriamente com valores \
452
+ entre [0, 1].
409
453
  * samples_index_class (``npt.NDArray``): Posições das amostras de uma classe em ``X``.
410
454
 
411
455
  Returns:
@@ -414,37 +458,41 @@ class RNSA(Base):
414
458
 
415
459
  """
416
460
  # Se um ou mais array de entrada possuir zero dados, retorna falso.
417
- if np.size(samples_index_class) == 0 or np.size(X) == 0 or np.size(vector_x) == 0:
461
+ if (np.size(samples_index_class) == 0 or np.size(X) == 0 or np.size(vector_x) == 0):
418
462
  return False
419
- # se self.k > 1 utiliza os k vizinhos mais próximos (knn), se não verifica o detector sem considerar os knn,.
463
+ # se self.k > 1 utiliza os k vizinhos mais próximos (knn), se não verifica o detector sem
464
+ # considerar os knn.
420
465
  if self.k > 1:
421
466
  # Iniciar a lista dos knn vazia.
422
- knn_list = np.empty(shape=(0))
467
+ knn_list = np.empty(shape=0)
423
468
  for i in samples_index_class:
424
- # Calcula a distância entre os dois vetores e adiciona a lista dos knn, se a distância for menor que a maior da lista.
469
+ # Calcula a distância entre os dois vetores e adiciona a lista dos knn, se a
470
+ # distância for menor que a maior da lista.
425
471
  knn_list = self.__compare_KnearestNeighbors_List(
426
- knn_list, self.__distance(X[i], vector_x))
472
+ knn_list, self.__distance(X[i], vector_x)
473
+ )
427
474
  # Se a média das distâncias na lista dos knn, for menor que o raio, retorna verdadeiro.
428
475
  distance_mean = np.mean(knn_list)
429
- if self._algorithm == 'V-detector':
476
+ if self._algorithm == "V-detector":
430
477
  return self.__detector_is_valid_to_Vdetector(distance_mean, vector_x)
431
478
  elif distance_mean > (self.r + self.r_s):
432
479
  return True # Detector é valido!
433
480
  else:
434
481
  distance: Union[float, None] = None
435
482
  for i in samples_index_class:
436
- if self._algorithm == 'V-detector':
483
+ if self._algorithm == "V-detector":
437
484
  new_distance = self.__distance(X[i], vector_x)
438
485
  if distance is None:
439
486
  distance = new_distance
440
487
  elif distance > new_distance:
441
488
  distance = new_distance
442
489
  else:
443
- # Calcula a distância entre os vetores, se menor ou igual ao raio + raio da amostra define a validade do detector como falso.
490
+ # Calcula a distância entre os vetores, se menor ou igual ao raio + raio da
491
+ # amostra define a validade do detector como falso.
444
492
  if (self.r + self.r_s) >= self.__distance(X[i], vector_x):
445
493
  return False # Detector não é valido!
446
-
447
- if self._algorithm == 'V-detector':
494
+
495
+ if self._algorithm == "V-detector":
448
496
  return self.__detector_is_valid_to_Vdetector(distance, vector_x)
449
497
  return True # Detector é valido!
450
498
 
@@ -467,26 +515,26 @@ class RNSA(Base):
467
515
 
468
516
  ---
469
517
 
470
- Compara a distância do k-vizinho mais próximo na posição ``k-1``da lista ``knn``,
518
+ Compara a distância do k-vizinho mais próximo na posição ``k-1``da lista ``knn``,
471
519
  se a distância da nova amostra for menor, substitui ela e ordena em ordem crescente.
472
520
 
473
521
 
474
522
  Parameters:
475
523
  ---
476
524
  knn (npt.NDArray): Lista de distâncias dos k-vizinhos mais próximos.
477
- distance (float): Distância a ser verificada.
525
+ distance (float): Distância a ser verificada.
478
526
 
479
527
  Returns:
480
528
  ---
481
529
  npt.NDArray: Lista de vizinhos mais próximos atualizada e ordenada.
482
530
  """
483
531
  # Se a quantidade de distâncias em knn, for menor que k, adiciona a distância.
484
- if (len(knn) < self.k):
532
+ if len(knn) < self.k:
485
533
  knn = np.append(knn, distance)
486
534
  knn.sort()
487
535
  else:
488
536
  # Se não, adicione a distância, se a nova distancia for menor que a maior distância da lista.
489
- if (knn[self.k - 1] > distance):
537
+ if knn[self.k - 1] > distance:
490
538
  knn[self.k - 1] = distance
491
539
  knn.sort()
492
540
 
@@ -498,7 +546,7 @@ class RNSA(Base):
498
546
 
499
547
  Details:
500
548
  ---
501
- In this function, when there is class ambiguity, it returns the class that has the greatest
549
+ In this function, when there is class ambiguity, it returns the class that has the greatest
502
550
  average distance between the detectors.
503
551
 
504
552
  Parameters:
@@ -507,7 +555,8 @@ class RNSA(Base):
507
555
 
508
556
  returns:
509
557
  ---
510
- * Returns the predicted class with the detectors or None if the sample does not qualify for any class.
558
+ * Returns the predicted class with the detectors or None if the sample does not qualify \
559
+ for any class.
511
560
 
512
561
  ---
513
562
 
@@ -515,8 +564,8 @@ class RNSA(Base):
515
564
 
516
565
  Details:
517
566
  ---
518
- Nesta função, quando possui ambiguidade de classes, retorna a classe que possuir a média de distância
519
- maior entre os detectores.
567
+ Nesta função, quando possui ambiguidade de classes, retorna a classe que possuir a média de \
568
+ distância maior entre os detectores.
520
569
 
521
570
  Parameters:
522
571
  ---
@@ -524,7 +573,8 @@ class RNSA(Base):
524
573
 
525
574
  Returns:
526
575
  ---
527
- * Retorna a classe prevista com os detectores ou None se a amostra não se qualificar a nenhuma classe.
576
+ * Retorna a classe prevista com os detectores ou None se a amostra não se qualificar \
577
+ a nenhuma classe.
528
578
  """
529
579
 
530
580
  # Lista para armazenar as classes e a distância média entre os detectores e a amostra.
@@ -538,7 +588,7 @@ class RNSA(Base):
538
588
  distance = self.__distance(detector.position, line)
539
589
  # Soma as distâncias para calcular a média.
540
590
  sum_distance += distance
541
- if self._algorithm == 'V-detector':
591
+ if self._algorithm == "V-detector":
542
592
  if distance <= detector.radius:
543
593
  class_found = False
544
594
  break
@@ -546,9 +596,10 @@ class RNSA(Base):
546
596
  class_found = False
547
597
  break
548
598
 
549
- # Se a amostra passar por todos os detectores de uma classe, adiciona a classe como possivel previsão.
599
+ # Se a amostra passar por todos os detectores de uma classe, adiciona a classe como
600
+ # possível previsão.
550
601
  if class_found:
551
- possible_classes.append([_class_, sum_distance/self.N])
602
+ possible_classes.append([_class_, sum_distance / self.N])
552
603
  # Se classificar como pertencentes a apenas uma classe, retorna a classe.
553
604
  if len(possible_classes) == 1:
554
605
  return possible_classes[0][0]
@@ -588,33 +639,37 @@ class RNSA(Base):
588
639
 
589
640
  def __detector_is_valid_to_Vdetector(self, distance: float, vector_x: npt.NDArray):
590
641
  """
591
- Check if the distance between the detector and the samples, minus the radius of the samples,
642
+ Check if the distance between the detector and the samples, minus the radius of the samples,
592
643
  is greater than the minimum radius.
593
644
 
594
645
  Parameters:
595
646
  ---
596
647
  distance (``float``): minimum distance calculated between all samples.
597
- vector_x (``numpy.ndarray``): randomly generated candidate detector vector x with values between 0 and 1.
648
+ vector_x (``numpy.ndarray``): randomly generated candidate detector vector x with values \
649
+ between 0 and 1.
650
+
598
651
  Returns:
599
652
  ---
600
- * ``False``: if the calculated radius is smaller than the minimum distance or exceeds the edge of the space,
601
- if this option is enabled.
653
+ * ``False``: if the calculated radius is smaller than the minimum distance or exceeds the \
654
+ edge of the space, if this option is enabled.
602
655
  * ``True`` and the distance minus the radius of the samples, if the radius is valid.`
603
656
 
604
657
  ----
605
658
 
606
- Verifique se a distância entre o detector e as amostras, descontando o raio das amostras, é maior do que o raio mínimo.
659
+ Verifique se a distância entre o detector e as amostras, descontando o raio das amostras, \
660
+ é maior do que o raio mínimo.
607
661
 
608
662
  Parameters:
609
663
  ---
610
664
  distance (``float``): distância mínima calculada entre todas as amostras.
611
- vector_x (``numpy.ndarray``): vetor x candidato do detector gerado aleatoriamente, com valores entre 0 e 1.
612
-
665
+ vector_x (``numpy.ndarray``): vetor x candidato do detector gerado aleatoriamente, com \
666
+ valores entre 0 e 1.
667
+
613
668
  Returns:
614
669
  ---
615
670
 
616
- * ``False``: caso o raio calculado seja menor do que a distância mínima ou ultrapasse a borda do espaço,
617
- caso essa opção esteja habilitada.
671
+ * ``False``: caso o raio calculado seja menor do que a distância mínima ou ultrapasse a \
672
+ borda do espaço, caso essa opção esteja habilitada.
618
673
  * ``True`` e a distância menos o raio das amostras, caso o raio seja válido.
619
674
  """
620
675
  new_detector_r = float(distance - self.r_s)
@@ -630,12 +685,14 @@ class RNSA(Base):
630
685
 
631
686
  def __slice_index_list_by_class(self, y: npt.NDArray) -> dict:
632
687
  """
633
- The function ``__slice_index_list_by_class(...)``, separates the indices of the lines according to the output class,
634
- to loop through the sample array, only in positions where the output is the class being trained.
688
+ The function ``__slice_index_list_by_class(...)``, separates the indices of the lines \
689
+ according to the output class, to loop through the sample array, only in positions where \
690
+ the output is the class being trained.
635
691
 
636
692
  Parameters:
637
693
  ---
638
- * y (npt.NDArray): Receives a ``y``[``N sample``] array with the output classes of the ``X`` sample array.
694
+ * y (npt.NDArray): Receives a ``y``[``N sample``] array with the output classes of the \
695
+ ``X`` sample array.
639
696
 
640
697
  returns:
641
698
  ---
@@ -643,35 +700,36 @@ class RNSA(Base):
643
700
 
644
701
  ---
645
702
 
646
- A função ``__slice_index_list_by_class(...)``, separa os índices das linhas conforme a classe de saída,
647
- para percorrer o array de amostra, apenas nas posições que a saída for a classe que está sendo treinada.
703
+ A função ``__slice_index_list_by_class(...)``, separa os índices das linhas conforme a classe \
704
+ de saída, para percorrer o array de amostra, apenas nas posições que a saída for a classe que \
705
+ está sendo treinada.
648
706
 
649
707
  Parameters:
650
708
  ---
651
- * y (npt.NDArray): Recebe um array ``y``[``N amostra``] com as classes de saida do array de amostra ``X``.
709
+ * y (npt.NDArray): Recebe um array ``y``[``N amostra``] com as classes de saída do array \
710
+ de amostra ``X``.
652
711
 
653
712
  Returns:
654
713
  ---
655
714
  * dict: Um dicionário com a lista de posições do array(``y``), com as classes como chave.
656
715
  """
657
716
  return super()._slice_index_list_by_class(y)
658
-
717
+
659
718
  def score(self, X: npt.NDArray, y: list) -> float:
660
719
  """
661
720
  Score function calculates forecast accuracy.
662
721
 
663
722
  Details:
664
723
  ---
665
- This function performs the prediction of X and checks how many elements are equal between vector y and y_predicted.
666
- This function was added for compatibility with some scikit-learn functions.
724
+ This function performs the prediction of X and checks how many elements are equal between \
725
+ vector y and y_predicted. This function was added for compatibility with some scikit-learn \
726
+ functions.
667
727
 
668
728
  Parameters:
669
729
  -----------
670
730
 
671
- X: np.ndarray
672
- Feature set with shape (n_samples, n_features).
673
- y: np.ndarray
674
- True values with shape (n_samples,).
731
+ * X (np.ndarray): Feature set with shape (n_samples, n_features).
732
+ * y (np.ndarray): True values with shape (n_samples,).
675
733
 
676
734
  Returns:
677
735
  -------
@@ -685,83 +743,88 @@ class RNSA(Base):
685
743
 
686
744
  Details:
687
745
  ---
688
- Esta função realiza a previsão de X e verifica quantos elementos são iguais entre o vetor y e y_previsto.
689
- Essa função foi adicionada para oferecer compatibilidade com algumas funções do scikit-learn.
746
+ Esta função realiza a previsão de X e verifica quantos elementos são iguais entre o vetor \
747
+ y e y_previsto. Essa função foi adicionada para oferecer compatibilidade com algumas \
748
+ funções do scikit-learn.
690
749
 
691
750
  Parameters:
692
751
  ---
693
752
 
694
- * X : np.ndarray
695
- Conjunto de características com shape (n_samples, n_features).
696
- * y : np.ndarray
697
- Valores verdadeiros com shape (n_samples,).
753
+ * X (np.ndarray): Conjunto de características com shape (n_samples, n_features).
754
+ * y (np.ndarray): Valores verdadeiros com shape (n_samples,).
698
755
 
699
756
  returns:
700
757
  ---
701
758
 
702
- accuracy : float
703
- A acurácia do modelo.
759
+ * accuracy (float): A acurácia do modelo.
760
+
704
761
  """
705
762
  return super()._score(X, y)
706
763
 
707
764
  def get_params(self, deep: bool = True) -> dict:
708
765
  return {
709
- 'N': self.N,
710
- 'r': self.r,
711
- 'k': self.k,
712
- 'metric': self.metric,
713
- 'seed': self.seed,
714
- 'algorithm': self._algorithm,
715
- 'r_s': self.r_s,
716
- 'cell_bounds': self._cell_bounds
766
+ "N": self.N,
767
+ "r": self.r,
768
+ "k": self.k,
769
+ "metric": self.metric,
770
+ "seed": self.seed,
771
+ "algorithm": self._algorithm,
772
+ "r_s": self.r_s,
773
+ "cell_bounds": self._cell_bounds,
774
+ "p": self.p,
717
775
  }
718
776
 
777
+
719
778
  class BNSA(Base):
720
779
  """
721
- The ``BNSA`` (Binary Negative Selection Algorithm) class is for classification and identification purposes.
722
- of anomalies through the self and not self method.
780
+ The ``BNSA`` (Binary Negative Selection Algorithm) class is for classification and identification \
781
+ purposes of anomalies through the self and not self method.
723
782
 
724
783
  Attributes:
725
784
  ---
726
-
785
+
727
786
  * N (``int``): Number of detectors.
728
- * aff_thresh (``float``): The variable represents the percentage of similarity between the T cell and the own samples.
729
- * max_discards (``int``): This parameter indicates the maximum number of detector discards in sequence, which aims to avoid a
730
- possible infinite loop if a radius is defined that it is not possible to generate non-self detectors.
787
+ * aff_thresh (``float``): The variable represents the percentage of similarity between the \
788
+ T cell and the own samples.
789
+ * max_discards (``int``): This parameter indicates the maximum number of detector discards \
790
+ in sequence, which aims to avoid a possible infinite loop if a radius is defined that \
791
+ it is not possible to generate non-self detectors.
731
792
  * seed (``int``): Seed for the random generation of values in the detectors.
732
-
793
+
733
794
  * detectors (``dict``): This variable stores a list of detectors by class.
734
795
  * classes (``npt.NDArray``): list of output classes.
735
-
796
+
736
797
 
737
798
  ---
738
799
 
739
- A classe ``BNSA`` (Algoritmo de Seleção Negativa Binária) tem a finalidade de classificação e identificação
740
- de anomalias através do método self e not self .
800
+ A classe ``BNSA`` (Algoritmo de Seleção Negativa Binária) tem a finalidade de classificação e \
801
+ identificação de anomalias através do método self e not self .
741
802
 
742
803
  Attributes:
743
804
  ---
744
805
  * N (``int``): Quantidade de detectores. Defaults to ``100``.
745
- * aff_thresh (``float``): A variável representa a porcentagem de similaridade entre a célula T e as amostras próprias.
746
- O valor padrão é de 10% (0,1), enquanto que o valor de 1,0 representa 100% de similaridade.
747
- * max_discards (``int``): Este parâmetro indica o número máximo de descartes de detectores em sequência, que tem como objetivo evitar um
748
- possível loop infinito caso seja definido um raio que não seja possível gerar detectores do não-próprio. Defaults to ``100``.
806
+ * aff_thresh (``float``): A variável representa a porcentagem de similaridade entre a célula \
807
+ T e as amostras próprias. O valor padrão é de 10% (0,1), enquanto que o valor de 1,0 \
808
+ representa 100% de similaridade.
809
+ * max_discards (``int``): Este parâmetro indica o número máximo de descartes de detectores \
810
+ em sequência, que tem como objetivo evitar um possível loop infinito caso seja definido \
811
+ um raio que não seja possível gerar detectores do não-próprio. Defaults to ``100``.
749
812
  * seed (``int``): Semente para a geração randômica dos valores nos detectores. Defaults to ``None``.
813
+ * no_label_sample_selection (``str``): Method for selecting labels for samples designated as \
814
+ non-members by all non-member detectors. Defaults to ``max_average_difference``.
815
+
750
816
 
751
817
  * detectors (``dict``): Essa variável armazena uma lista com detectores por classes.
752
818
  * classes (``npt.NDArray``): lista com as classes de saída.
753
819
 
754
820
  """
755
- def __init__(
756
- self,
757
- N: int = 100,
758
- aff_thresh: float = 0.1,
759
- max_discards: int = 1000,
760
- seed: int = None
761
- ):
821
+
822
+ def __init__(self, N: int = 100, aff_thresh: float = 0.1, max_discards: int = 1000, seed: int = None,
823
+ no_label_sample_selection: Literal["max_average_difference", "max_nearest_difference"] =
824
+ "max_average_difference"):
762
825
  """
763
826
  Constructor of the Negative Selection class (``BNSA``).
764
-
827
+
765
828
  Details:
766
829
  ---
767
830
  This method initializes the ``detectors``, ``classes``, ``N``, ``t`` and ``seed`` attributes.
@@ -769,16 +832,23 @@ class BNSA(Base):
769
832
  Parameters:
770
833
  ---
771
834
  * N (``int``): Number of detectors. Defaults to ``100``.
772
- * aff_thresh (``float``): The variable represents the percentage of similarity between the T cell and the own samples.
773
- The default value is 10% (0.1), while a value of 1.0 represents 100% similarity.
774
- * max_discards (``int``): This parameter indicates the maximum number of detector discards in sequence, which aims to avoid a
775
- possible infinite loop if a radius is defined that it is not possible to generate non-self detectors. Defaults to ``1000``.
835
+ * aff_thresh (``float``): The variable represents the percentage of similarity between \
836
+ the T cell and the own samples. The default value is 10% (0.1), while a value of 1.0 \
837
+ represents 100% similarity.
838
+ * max_discards (``int``): This parameter indicates the maximum number of detector \
839
+ discards in sequence, which aims to avoid a possible infinite loop if a radius is \
840
+ defined that it is not possible to generate non-self detectors. Defaults to ``1000``.
776
841
  * seed (``int``): Seed for the random generation of values in the detectors. Defaults to ``None``.
777
-
842
+ * no_label_sample_selection (``str``): Method for selecting labels for samples designated as \
843
+ non-members by all non-member detectors. Available method types:
844
+ - (``max_average_difference``): Selects the class with the highest average difference \
845
+ among the detectors.
846
+ - (``max_nearest_difference``): Selects the class with the highest difference between \
847
+ the nearest and farthest detector from the sample.
778
848
  ---
779
849
 
780
850
  Construtor da classe de Seleção negativa (``BNSA``).
781
-
851
+
782
852
  Details:
783
853
  ---
784
854
  Este método inicializa os atributos ``detectors``, ``classes``, ``N``, ``t`` e ``seed``.
@@ -786,31 +856,47 @@ class BNSA(Base):
786
856
  Parameters:
787
857
  ---
788
858
  * N (``int``): Quantidade de detectores. Defaults to ``100``.
789
- * aff_thresh (``float``): A variável representa a porcentagem de similaridade entre a célula T e as amostras próprias.
790
- O valor padrão é de 10% (0,1), enquanto que o valor de 1,0 representa 100% de similaridade.
791
- * max_discards (``int``): Este parâmetro indica o número máximo de descartes de detectores em sequência, que tem como objetivo evitar um
792
- possível loop infinito caso seja definido um raio que não seja possível gerar detectores do não-próprio. Defaults to ``1000``.
859
+ * aff_thresh (``float``): A variável representa a porcentagem de similaridade entre a \
860
+ célula T e as amostras próprias. O valor padrão é de 10% (0,1), enquanto que o valor \
861
+ de 1,0 representa 100% de similaridade.
862
+ * max_discards (``int``): Este parâmetro indica o número máximo de descartes de detectores \
863
+ em sequência, que tem como objetivo evitar um possível loop infinito caso seja definido \
864
+ um raio que não seja possível gerar detectores do não-próprio. Defaults to ``1000``.
793
865
  * seed (``int``): Semente para a geração randômica dos valores nos detectores. Defaults to ``None``.
866
+ * no_label_sample_selection (``str``): Método para a seleção de rótulos para amostras designadas \
867
+ como não pertencentes por todos os detectores não pertencentes. Tipos de métodos disponíveis:
868
+ - (``max_average_difference``): Seleciona a classe com a maior diferença média entre os \
869
+ detectores.
870
+ - (``max_nearest_difference``): Seleciona a classe com a maior diferença entre o detector \
871
+ mais próximo e mais distante da amostra.
872
+
794
873
  """
874
+ super().__init__()
795
875
  if N > 0:
796
876
  self.N: int = N
797
877
  else:
798
878
  self.N: int = 100
799
879
 
800
- if aff_thresh > 0 and aff_thresh < 1:
880
+ if 0 < aff_thresh < 1:
801
881
  self.aff_thresh: float = aff_thresh
802
882
  else:
803
883
  self.aff_thresh: float = 0.1
804
884
  if max_discards > 0:
805
885
  self.max_discards: int = max_discards
806
886
  else:
807
- self.max_discards: int = 0
808
-
887
+ self.max_discards: int = 1000
888
+
809
889
  if seed is not None and isinstance(seed, int):
810
890
  np.random.seed(seed)
811
891
  self.seed: int = seed
812
892
  else:
813
893
  self.seed = None
894
+
895
+ if no_label_sample_selection == 'nearest_difference':
896
+ self.no_label_sample_selection = 'nearest_difference'
897
+ else:
898
+ self.no_label_sample_selection = 'max_average_difference'
899
+
814
900
  self.classes: npt.NDArray = None
815
901
  self.detectors: npt.NDArray = None
816
902
 
@@ -831,24 +917,26 @@ class BNSA(Base):
831
917
 
832
918
  ----
833
919
 
834
- A função ``fit(...)``, realiza o treinamento de acordo com ``X`` e ``y``, usando o método
920
+ A função ``fit(...)``, realiza o treinamento de acordo com ``X`` e ``y``, usando o método
835
921
  de seleção negativa(``NegativeSelect``).
836
922
 
837
923
  Parameters:
838
924
  ---
839
- * X (``npt.NDArray``): Array de treinamento, contendo as amostras é suas características,
840
- [``N amostras`` (linhas)][``N características`` (colunas)].
925
+ * X (``npt.NDArray``): Array de treinamento, contendo as amostras é suas características, \
926
+ [``N amostras`` (linhas)][``N características`` (colunas)].
841
927
  * y (``npt.NDArray``): Array com as classes alvos de ``X`` com [``N amostras`` (linhas)].
842
928
  * verbose (``bool``): Feedback da geração de detectores para o usuário.
843
929
  Returns:
844
930
  ---
845
931
  (``self``): Retorna a própria instância.
846
932
  """
847
- super()._check_and_raise_exceptions_fit(X, y, 'BNSA')
933
+ super()._check_and_raise_exceptions_fit(X, y, "BNSA")
848
934
 
935
+ # Converte todo o array X para boolean
849
936
  if X.dtype != bool:
850
937
  X = X.astype(bool)
851
938
 
939
+ # Identificando as classes possíveis, dentro do array de saídas ``y``.
852
940
  self.classes = np.unique(y)
853
941
  # Dict que armazenará os detectores com as classes como key.
854
942
  list_detectors_by_class = dict()
@@ -858,7 +946,7 @@ class BNSA(Base):
858
946
  if verbose:
859
947
  progress = tqdm(total=int(self.N * (len(self.classes))),
860
948
  bar_format='{desc} ┇{bar}┇ {n}/{total} detectors', postfix='\n')
861
-
949
+
862
950
  for _class_ in self.classes:
863
951
  # Inicia o conjunto vazio que conterá os detectores válidos.
864
952
  valid_detectors_set: list = []
@@ -866,12 +954,12 @@ class BNSA(Base):
866
954
  # Informando em qual classe o algoritmo está para a barra de progresso.
867
955
  if verbose:
868
956
  progress.set_description_str(
869
- f'Generating the detectors for the {_class_} class:')
957
+ f"Generating the detectors for the {_class_} class:")
870
958
  while len(valid_detectors_set) < self.N:
871
-
959
+
872
960
  is_valid_detector: bool = True
873
961
  # Gera um vetor candidato a detector aleatoriamente com valores 0 e 1.
874
- vector_x = np.random.randint(0, 2, X.shape[1], dtype=bool)
962
+ vector_x = np.random.choice([False, True], size=X.shape[1])
875
963
  for i in sample_index[_class_]:
876
964
  # Verifica a validade do detector para o não-próprio com relação às amostras da classe.
877
965
  if hamming(X[i], vector_x) <= self.aff_thresh:
@@ -886,22 +974,26 @@ class BNSA(Base):
886
974
  else:
887
975
  discard_count += 1
888
976
  if discard_count == self.max_discards:
889
- raise Exception('An error has been identified:\n'+
890
- f'the maximum number of discards of detectors for the {_class_} class has been reached.\n'+
891
- 'It is recommended to check the defined radius and consider reducing its value.')
892
-
977
+ raise Exception(
978
+ "An error has been identified:\n"
979
+ f"the maximum number of discards of detectors for the {_class_} "
980
+ "class has been reached.\nIt is recommended to check the defined "
981
+ "radius and consider reducing its value."
982
+ )
983
+
893
984
  # Adicionar detectores, com as classes como chave na dict.
894
985
  list_detectors_by_class[_class_] = valid_detectors_set
895
986
 
896
987
  # Informar a finalização da geração dos detectores para as classes.
897
988
  if verbose:
898
989
  progress.set_description(
899
- f'\033[92m✔ Non-self detectors for classes ({", ".join(map(str, self.classes))}) successfully generated\033[0m')
990
+ f'\033[92m✔ Non-self detectors for classes ({", ".join(map(str, self.classes))}) '
991
+ f'successfully generated\033[0m')
900
992
  # Armazena os detectores encontrados no atributo, para os detectores da classe.
901
993
  self.detectors = list_detectors_by_class
902
994
  return self
903
995
 
904
- def predict(self, X: npt.NDArray) -> npt.NDArray:
996
+ def predict(self, X: npt.NDArray) -> Optional[npt.NDArray]:
905
997
  """
906
998
  Function to perform the prediction of classes based on detectors
907
999
  created after training.
@@ -919,87 +1011,107 @@ class BNSA(Base):
919
1011
 
920
1012
  ---
921
1013
 
922
- Função para efetuar a previsão das classes com base nos detectores
1014
+ Função para efetuar a previsão das classes com base nos detectores
923
1015
  criados após o treinamento.
924
1016
 
925
1017
  Parameters:
926
1018
  ---
927
- * X (``npt.NDArray``): Array com as amostras de entradas com [``N amostras`` (Linhas)] e
1019
+ * X (``npt.NDArray``): Array com as amostras de entradas com [``N amostras`` (Linhas)] e
928
1020
  [``N características``(Colunas)]
929
1021
 
930
1022
  Returns:
931
1023
  ---
932
- * C – (``npt.NDArray``): um ndarray de forma ``C`` [``N amostras``],
1024
+ * C – (``npt.NDArray``): um ndarray de forma ``C`` [``N amostras``],
933
1025
  contendo as classes previstas para ``X``.
934
1026
  * ``None``: Se não existir detectores para a previsão.
935
1027
  """
936
1028
  # se não houver detectores retorna None.
937
1029
  if self.detectors is None:
938
1030
  return None
939
- elif not isinstance(X, (np.ndarray, list)):
1031
+ elif not isinstance(X, (np.ndarray, list)):
940
1032
  raise TypeError("X is not an ndarray or list")
941
1033
  elif len(self.detectors[self.classes[0]][0]) != len(X[0]):
942
- raise Exception('X does not have {} features to make the prediction'.format(
943
- len(self.detectors[self.classes[0]][0])))
1034
+ raise Exception(
1035
+ "X does not have {} features to make the prediction".format(
1036
+ len(self.detectors[self.classes[0]][0])
1037
+ )
1038
+ )
944
1039
  # Verifica se a matriz X contém apenas amostras binárias. Caso contrário, lança uma exceção.
945
1040
  if not np.isin(X, [0, 1]).all():
946
1041
  raise ValueError(
947
- "The array X contains values that are not composed only of 0 and 1.")
1042
+ "The array X contains values that are not composed only of 0 and 1."
1043
+ )
948
1044
 
1045
+ # Converte todo o array X para boolean
949
1046
  if X.dtype != bool:
950
1047
  X = X.astype(bool)
951
-
1048
+
952
1049
  # Inicia um array vazio.
953
- C = np.empty(shape=(0))
1050
+ C = np.empty(shape=0)
954
1051
  # Para cada linha de amostra em X.
955
1052
  for line in X:
956
1053
  class_found: bool = True
957
- # Lista para armazenar as possíveis classes às quais a amostra se adequou ao self na comparação com os detectores non-self.
958
- possible_classes: list = []
1054
+ # Lista para armazenar as possíveis classes às quais a amostra se adequou ao self na
1055
+ # comparação com os detectores non-self.
1056
+ possible_classes: list = []
959
1057
  for _class_ in self.classes:
960
- # Lista para armzenar as taxas de similaridade entre a amostra e os detectores.
961
- similarity_list: list = []
1058
+ # Lista para armazenar as taxas de similaridade entre a amostra e os detectores.
1059
+ similarity_sum: float = 0
962
1060
  for detector in self.detectors[_class_]:
963
1061
  similarity = hamming(line, detector)
964
1062
  if similarity <= self.aff_thresh:
965
1063
  class_found = False
966
1064
  break
967
1065
  else:
968
- similarity_list.append(similarity)
969
- # Se a amostra passar por todos os detectores de uma classe, adiciona a classe como possivel previsão e sua media de similaridade.
1066
+ similarity_sum += similarity
1067
+ # Se a amostra passar por todos os detectores de uma classe, adiciona a classe como
1068
+ # possível previsão e sua media de similaridade.
970
1069
  if class_found:
971
- possible_classes.append([_class_, min(similarity_list)])
972
-
1070
+ possible_classes.append([_class_, similarity_sum / self.N])
1071
+
973
1072
  # Se, pertencer a uma ou mais classes, adiciona a classe com a distância média mais distante.
974
- if len(possible_classes) > 0 :
975
- C = np.append(C, [max(possible_classes, key=lambda x: x[1])[0]])
1073
+ if len(possible_classes) > 0:
1074
+ C = np.append(
1075
+ C, [max(possible_classes, key=lambda x: x[1])[0]])
976
1076
  class_found = True
977
1077
  else:
978
1078
  class_found = False
979
1079
 
980
1080
  # Se possuir apenas uma classe e não classificar a amostra define a saída como não-própria.
981
1081
  if not class_found and len(self.classes) == 1:
982
- C = np.append(C, ['non-self'])
983
- # Se não identificar a classe com os detectores, coloca a classe com a maior distância da média dos seus detectores.
1082
+ C = np.append(C, ["non-self"])
1083
+ # Se a classe não puder ser identificada pelos detectores
984
1084
  elif not class_found:
985
- class_differences = []
1085
+ class_differences: dict = {}
986
1086
  for _class_ in self.classes:
987
- differences = []
988
- for detector in self.detectors[_class_]:
989
- differences.append(hamming(line, detector))
990
- class_differences.append(min(differences))
991
- C = np.append(C, [self.classes[class_differences.index(max(class_differences))]])
992
-
1087
+ # Atribua-a o rotulo a classe com à maior distância em relação ao detector mais próximo.
1088
+ if self.no_label_sample_selection == 'nearest_difference':
1089
+ differences: list = []
1090
+ for detector in self.detectors[_class_]:
1091
+ differences.append(hamming(line, detector))
1092
+ class_differences[_class_] = min(differences)
1093
+ # Ou com base na maior distância com relação à média da distancias dos detectores
1094
+ else:
1095
+ difference_sum: float = 0
1096
+ for detector in self.detectors[_class_]:
1097
+ difference_sum += hamming(line, detector)
1098
+ class_differences[_class_] = difference_sum / self.N
1099
+
1100
+ C = np.append(
1101
+ C, [max(class_differences, key=class_differences.get)])
1102
+
993
1103
  return C
994
1104
 
995
1105
  def __slice_index_list_by_class(self, y: npt.NDArray) -> dict:
996
1106
  """
997
- The function ``__slice_index_list_by_class(...)``, separates the indices of the lines according to the output class,
998
- to loop through the sample array, only in positions where the output is the class being trained.
1107
+ The function ``__slice_index_list_by_class(...)``, separates the indices of the lines according \
1108
+ to the output class, to loop through the sample array, only in positions where the output is \
1109
+ the class being trained.
999
1110
 
1000
1111
  Parameters:
1001
1112
  ---
1002
- * y (npt.NDArray): Receives a ``y``[``N sample``] array with the output classes of the ``X`` sample array.
1113
+ * y (npt.NDArray): Receives a ``y``[``N sample``] array with the output classes of the \
1114
+ ``X`` sample array.
1003
1115
 
1004
1116
  returns:
1005
1117
  ---
@@ -1007,12 +1119,14 @@ class BNSA(Base):
1007
1119
 
1008
1120
  ---
1009
1121
 
1010
- A função ``__slice_index_list_by_class(...)``, separa os índices das linhas conforme a classe de saída,
1011
- para percorrer o array de amostra, apenas nas posições que a saída for a classe que está sendo treinada.
1122
+ A função ``__slice_index_list_by_class(...)``, separa os índices das linhas conforme a classe \
1123
+ de saída, para percorrer o array de amostra, apenas nas posições que a saída for a classe que \
1124
+ está sendo treinada.
1012
1125
 
1013
1126
  Parameters:
1014
1127
  ---
1015
- * y (npt.NDArray): Recebe um array ``y``[``N amostra``] com as classes de saida do array de amostra ``X``.
1128
+ * y (npt.NDArray): Recebe um array ``y``[``N amostra``] com as classes de saída do array \
1129
+ de amostra ``X``.
1016
1130
 
1017
1131
  Returns:
1018
1132
  ---
@@ -1026,8 +1140,8 @@ class BNSA(Base):
1026
1140
 
1027
1141
  Details:
1028
1142
  ---
1029
- This function performs the prediction of X and checks how many elements are equal between vector y and y_predicted.
1030
- This function was added for compatibility with some scikit-learn functions.
1143
+ This function performs the prediction of X and checks how many elements are equal between vector \
1144
+ y and y_predicted. This function was added for compatibility with some scikit-learn functions.
1031
1145
 
1032
1146
  Parameters:
1033
1147
  -----------
@@ -1049,7 +1163,8 @@ class BNSA(Base):
1049
1163
 
1050
1164
  Details:
1051
1165
  ---
1052
- Esta função realiza a previsão de X e verifica quantos elementos são iguais entre o vetor y e y_previsto.
1166
+ Esta função realiza a previsão de X e verifica quantos elementos são iguais entre o vetor y \
1167
+ e y_previsto.
1053
1168
  Essa função foi adicionada para oferecer compatibilidade com algumas funções do scikit-learn.
1054
1169
 
1055
1170
  Parameters:
@@ -1070,8 +1185,8 @@ class BNSA(Base):
1070
1185
 
1071
1186
  def get_params(self, deep: bool = True) -> dict:
1072
1187
  return {
1073
- 'N': self.N,
1074
- 'aff_thresh': self.aff_thresh,
1075
- 'max_discards': self.max_discards,
1076
- 'seed': self.seed,
1077
- }
1188
+ "N": self.N,
1189
+ "aff_thresh": self.aff_thresh,
1190
+ "max_discards": self.max_discards,
1191
+ "seed": self.seed,
1192
+ }