aisp 0.1.32__py3-none-any.whl → 0.1.33__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/NSA/__init__.py +1 -1
- aisp/NSA/_base.py +82 -41
- aisp/NSA/_negative_selection.py +117 -122
- aisp/utils/__init__.py +5 -0
- aisp/utils/_multiclass.py +43 -0
- aisp/utils/metrics.py +61 -0
- {aisp-0.1.32.dist-info → aisp-0.1.33.dist-info}/METADATA +3 -26
- aisp-0.1.33.dist-info/RECORD +11 -0
- {aisp-0.1.32.dist-info → aisp-0.1.33.dist-info}/WHEEL +1 -1
- aisp-0.1.32.dist-info/RECORD +0 -8
- {aisp-0.1.32.dist-info → aisp-0.1.33.dist-info}/LICENSE +0 -0
- {aisp-0.1.32.dist-info → aisp-0.1.33.dist-info}/top_level.txt +0 -0
    
        aisp/NSA/__init__.py
    CHANGED
    
    
    
        aisp/NSA/_base.py
    CHANGED
    
    | @@ -1,8 +1,12 @@ | |
| 1 | 
            +
            from abc import abstractmethod
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            import numpy as np
         | 
| 2 4 | 
             
            import numpy.typing as npt
         | 
| 3 | 
            -
            from typing import Literal
         | 
| 5 | 
            +
            from typing import Literal, Optional
         | 
| 4 6 | 
             
            from scipy.spatial.distance import euclidean, cityblock, minkowski
         | 
| 5 7 |  | 
| 8 | 
            +
            from ..utils.metrics import accuracy_score
         | 
| 9 | 
            +
             | 
| 6 10 |  | 
| 7 11 | 
             
            class Base:
         | 
| 8 12 | 
             
                """
         | 
| @@ -93,8 +97,11 @@ class Base: | |
| 93 97 | 
             
                    else:
         | 
| 94 98 | 
             
                        return euclidean(u, v)
         | 
| 95 99 |  | 
| 96 | 
            -
                 | 
| 97 | 
            -
             | 
| 100 | 
            +
                @staticmethod
         | 
| 101 | 
            +
                def _check_and_raise_exceptions_fit(
         | 
| 102 | 
            +
                        X: npt.NDArray = None,
         | 
| 103 | 
            +
                        y: npt.NDArray = None,
         | 
| 104 | 
            +
                        _class_: Literal["RNSA", "BNSA"] = "RNSA",
         | 
| 98 105 | 
             
                ):
         | 
| 99 106 | 
             
                    """
         | 
| 100 107 | 
             
                    Function responsible for verifying fit function parameters and throwing exceptions if the \
         | 
| @@ -149,43 +156,6 @@ class Base: | |
| 149 156 | 
             
                            "The array X contains values that are not composed only of 0 and 1."
         | 
| 150 157 | 
             
                        )
         | 
| 151 158 |  | 
| 152 | 
            -
                def _slice_index_list_by_class(self, y: npt.NDArray) -> dict:
         | 
| 153 | 
            -
                    """
         | 
| 154 | 
            -
                    The function ``__slice_index_list_by_class(...)``, separates the indices of the lines \
         | 
| 155 | 
            -
                    according to the output class, to loop through the sample array, only in positions where \
         | 
| 156 | 
            -
                    the output is the class being trained.
         | 
| 157 | 
            -
             | 
| 158 | 
            -
                    Parameters:
         | 
| 159 | 
            -
                    ---
         | 
| 160 | 
            -
                        * y (npt.NDArray): Receives a ``y``[``N sample``] array with the output classes of the \
         | 
| 161 | 
            -
                            ``X`` sample array.
         | 
| 162 | 
            -
             | 
| 163 | 
            -
                    returns:
         | 
| 164 | 
            -
                    ---
         | 
| 165 | 
            -
                        * dict: A dictionary with the list of array positions(``y``), with the classes as key.
         | 
| 166 | 
            -
             | 
| 167 | 
            -
                    ---
         | 
| 168 | 
            -
             | 
| 169 | 
            -
                    A função ``__slice_index_list_by_class(...)``, separa os índices das linhas conforme a \
         | 
| 170 | 
            -
                    classe de saída, para percorrer o array de amostra, apenas nas posições que a saída for \
         | 
| 171 | 
            -
                    a classe que está sendo treinada.
         | 
| 172 | 
            -
             | 
| 173 | 
            -
                    Parameters:
         | 
| 174 | 
            -
                    ---
         | 
| 175 | 
            -
                        * y (npt.NDArray): Recebe um array ``y``[``N amostra``] com as classes de saída do \
         | 
| 176 | 
            -
                            array de amostra ``X``.
         | 
| 177 | 
            -
             | 
| 178 | 
            -
                    Returns:
         | 
| 179 | 
            -
                    ---
         | 
| 180 | 
            -
                        * dict: Um dicionário com a lista de posições do array(``y``), com as classes como chave.
         | 
| 181 | 
            -
                    """
         | 
| 182 | 
            -
                    position_samples = dict()
         | 
| 183 | 
            -
                    for _class_ in self.classes:
         | 
| 184 | 
            -
                        # Pega as posições das amostras por classes a partir do y.
         | 
| 185 | 
            -
                        position_samples[_class_] = list(np.where(y == _class_)[0])
         | 
| 186 | 
            -
             | 
| 187 | 
            -
                    return position_samples
         | 
| 188 | 
            -
             | 
| 189 159 | 
             
                def _score(self, X: npt.NDArray, y: list) -> float:
         | 
| 190 160 | 
             
                    """
         | 
| 191 161 | 
             
                    Score function calculates forecast accuracy.
         | 
| @@ -237,4 +207,75 @@ class Base: | |
| 237 207 | 
             
                    if len(y) == 0:
         | 
| 238 208 | 
             
                        return 0
         | 
| 239 209 | 
             
                    y_pred = self.predict(X)
         | 
| 240 | 
            -
                    return  | 
| 210 | 
            +
                    return accuracy_score(y, y_pred)
         | 
| 211 | 
            +
             | 
| 212 | 
            +
                @abstractmethod
         | 
| 213 | 
            +
                def fit(self, X: npt.NDArray, y: npt.NDArray, verbose: bool = True):
         | 
| 214 | 
            +
                    """
         | 
| 215 | 
            +
                    Function to train the model using the input data ``X`` and corresponding labels ``y``.
         | 
| 216 | 
            +
             | 
| 217 | 
            +
                    This abstract method is implemented by the class that inherits it.
         | 
| 218 | 
            +
             | 
| 219 | 
            +
                    Parameters:
         | 
| 220 | 
            +
                    ---
         | 
| 221 | 
            +
                        * X (``npt.NDArray``): Input data used for training the model, previously normalized to the range [0, 1].
         | 
| 222 | 
            +
                        * y (``npt.NDArray``): Corresponding labels or target values for the input data.
         | 
| 223 | 
            +
                        * verbose (``bool``, optional): Flag to enable or disable detailed output during \
         | 
| 224 | 
            +
                            training. Default is ``True``.
         | 
| 225 | 
            +
             | 
| 226 | 
            +
                    Returns:
         | 
| 227 | 
            +
                    ---
         | 
| 228 | 
            +
                        * self: Returns the instance of the class that implements this method.
         | 
| 229 | 
            +
             | 
| 230 | 
            +
                    ---
         | 
| 231 | 
            +
             | 
| 232 | 
            +
                    Função para treinar o modelo usando os dados de entrada ``X`` e os classes correspondentes ``y``.
         | 
| 233 | 
            +
             | 
| 234 | 
            +
                    Este método abstrato é implementado pela classe que o herdar.
         | 
| 235 | 
            +
             | 
| 236 | 
            +
                    Parâmetros:
         | 
| 237 | 
            +
                    ---
         | 
| 238 | 
            +
                        * X (``npt.NDArray``): Dados de entrada utilizados para o treinamento do modelo, previamente \
         | 
| 239 | 
            +
                            normalizados no intervalo [0, 1].
         | 
| 240 | 
            +
                        * y (``npt.NDArray``): Rótulos ou valores-alvo correspondentes aos dados de entrada.
         | 
| 241 | 
            +
                        * verbose (``bool``, opcional): Flag para ativar ou desativar a saída detalhada durante o \
         | 
| 242 | 
            +
                            treinamento. O padrão é ``True``.
         | 
| 243 | 
            +
             | 
| 244 | 
            +
                    Retornos:
         | 
| 245 | 
            +
                    ---
         | 
| 246 | 
            +
                        * self: Retorna a instância da classe que implementa este método.
         | 
| 247 | 
            +
                    """
         | 
| 248 | 
            +
                    pass
         | 
| 249 | 
            +
             | 
| 250 | 
            +
                @abstractmethod
         | 
| 251 | 
            +
                def predict(self, X) -> Optional[npt.NDArray]:
         | 
| 252 | 
            +
                    """
         | 
| 253 | 
            +
                    Function to generate predictions based on the input data ``X``.
         | 
| 254 | 
            +
             | 
| 255 | 
            +
                    This abstract method is implemented by the class that inherits it.
         | 
| 256 | 
            +
             | 
| 257 | 
            +
                    Parameters:
         | 
| 258 | 
            +
                    ---
         | 
| 259 | 
            +
                        * X (``npt.NDArray``): Input data for which predictions will be generated.
         | 
| 260 | 
            +
             | 
| 261 | 
            +
                    Returns:
         | 
| 262 | 
            +
                    ---
         | 
| 263 | 
            +
                        * Predictions (``Optional[npt.NDArray]``): Predicted values for each input sample, or ``None``
         | 
| 264 | 
            +
                            if the prediction fails.
         | 
| 265 | 
            +
             | 
| 266 | 
            +
                    ---
         | 
| 267 | 
            +
             | 
| 268 | 
            +
                    Função para gerar previsões com base nos dados de entrada ``X``.
         | 
| 269 | 
            +
             | 
| 270 | 
            +
                    Este método abstrato é implementado pela classe que o herdar.
         | 
| 271 | 
            +
             | 
| 272 | 
            +
                    Parâmetros:
         | 
| 273 | 
            +
                    ---
         | 
| 274 | 
            +
                        * X (``npt.NDArray``): Dados de entrada para os quais as previsões serão geradas.
         | 
| 275 | 
            +
             | 
| 276 | 
            +
                    Retornos:
         | 
| 277 | 
            +
                    ---
         | 
| 278 | 
            +
                        * Previsões (``Optional[npt.NDArray]``): Valores previstos para cada amostra de entrada,
         | 
| 279 | 
            +
                            ou ``None`` se a previsão falhar.
         | 
| 280 | 
            +
                    """
         | 
| 281 | 
            +
                    pass
         | 
    
        aisp/NSA/_negative_selection.py
    CHANGED
    
    | @@ -6,6 +6,7 @@ from collections import namedtuple | |
| 6 6 | 
             
            from scipy.spatial.distance import cdist
         | 
| 7 7 |  | 
| 8 8 | 
             
            from ._base import Base
         | 
| 9 | 
            +
            from ..utils import slice_index_list_by_class
         | 
| 9 10 |  | 
| 10 11 |  | 
| 11 12 | 
             
            class RNSA(Base):
         | 
| @@ -236,7 +237,7 @@ class RNSA(Base): | |
| 236 237 | 
             
                        self.r_s: float = 0
         | 
| 237 238 |  | 
| 238 239 | 
             
                    if algorithm == "V-detector":
         | 
| 239 | 
            -
                        self._Detector = namedtuple("Detector", "position radius")
         | 
| 240 | 
            +
                        self._Detector = namedtuple("Detector", ["position", "radius"])
         | 
| 240 241 | 
             
                        self._algorithm: str = algorithm
         | 
| 241 242 | 
             
                    else:
         | 
| 242 243 | 
             
                        self._Detector = namedtuple("Detector", "position")
         | 
| @@ -247,12 +248,12 @@ class RNSA(Base): | |
| 247 248 | 
             
                    else:
         | 
| 248 249 | 
             
                        self.max_discards: int = 1000
         | 
| 249 250 |  | 
| 250 | 
            -
                    #  | 
| 251 | 
            +
                    # Retrieves the variables from kwargs.
         | 
| 251 252 | 
             
                    self.p: float = kwargs.get("p", 2)
         | 
| 252 253 | 
             
                    self._cell_bounds: bool = kwargs.get("cell_bounds", False)
         | 
| 253 254 | 
             
                    self.non_self_label: str = kwargs.get("non_self_label", "non-self")
         | 
| 254 255 |  | 
| 255 | 
            -
                    #  | 
| 256 | 
            +
                    # Initializes the other class variables as None.
         | 
| 256 257 | 
             
                    self.detectors: Union[dict, None] = None
         | 
| 257 258 | 
             
                    self.classes: npt.NDArray = None
         | 
| 258 259 |  | 
| @@ -286,36 +287,37 @@ class RNSA(Base): | |
| 286 287 | 
             
                    ---
         | 
| 287 288 | 
             
                        (``self``): Retorna a própria instância.
         | 
| 288 289 | 
             
                    """
         | 
| 290 | 
            +
                    progress = None
         | 
| 289 291 | 
             
                    super()._check_and_raise_exceptions_fit(X, y)
         | 
| 290 292 |  | 
| 291 | 
            -
                    #  | 
| 293 | 
            +
                    # Identifying the possible classes within the output array `y`.
         | 
| 292 294 | 
             
                    self.classes = np.unique(y)
         | 
| 293 | 
            -
                    #  | 
| 295 | 
            +
                    # Dictionary that will store detectors with classes as keys.
         | 
| 294 296 | 
             
                    list_detectors_by_class = dict()
         | 
| 295 | 
            -
                    #  | 
| 297 | 
            +
                    # Separates the classes for training.
         | 
| 296 298 | 
             
                    sample_index = self.__slice_index_list_by_class(y)
         | 
| 297 | 
            -
                    #  | 
| 299 | 
            +
                    # Progress bar for generating all detectors.
         | 
| 298 300 | 
             
                    if verbose:
         | 
| 299 301 | 
             
                        progress = tqdm(total=int(self.N * (len(self.classes))),
         | 
| 300 | 
            -
                                        bar_format="{desc} ┇{bar}┇ {n}/{total} detectors", postfix="\n",)
         | 
| 302 | 
            +
                                        bar_format="{desc} ┇{bar}┇ {n}/{total} detectors", postfix="\n", )
         | 
| 301 303 | 
             
                    for _class_ in self.classes:
         | 
| 302 | 
            -
                        #  | 
| 304 | 
            +
                        # Initializes the empty set that will contain the valid detectors.
         | 
| 303 305 | 
             
                        valid_detectors_set = []
         | 
| 304 306 | 
             
                        discard_count = 0
         | 
| 305 | 
            -
                        #  | 
| 307 | 
            +
                        # Indicating which class the algorithm is currently processing for the progress bar.
         | 
| 306 308 | 
             
                        if verbose:
         | 
| 307 309 | 
             
                            progress.set_description_str(
         | 
| 308 310 | 
             
                                f"Generating the detectors for the {_class_} class:"
         | 
| 309 311 | 
             
                            )
         | 
| 310 312 | 
             
                        while len(valid_detectors_set) < self.N:
         | 
| 311 | 
            -
                            #  | 
| 313 | 
            +
                            # Generates a candidate detector vector randomly with values between 0 and 1.
         | 
| 312 314 | 
             
                            vector_x = np.random.random_sample(size=X.shape[1])
         | 
| 313 | 
            -
                            #  | 
| 315 | 
            +
                            # Checks the validity of the detector for non-self with respect to the class samples.
         | 
| 314 316 | 
             
                            valid_detector = self.__checks_valid_detector(
         | 
| 315 317 | 
             
                                X=X, vector_x=vector_x, samples_index_class=sample_index[_class_]
         | 
| 316 318 | 
             
                            )
         | 
| 317 319 |  | 
| 318 | 
            -
                            #  | 
| 320 | 
            +
                            # If the detector is valid, add it to the list of valid detectors.
         | 
| 319 321 | 
             
                            if self._algorithm == "V-detector" and valid_detector is not False:
         | 
| 320 322 | 
             
                                discard_count = 0
         | 
| 321 323 | 
             
                                valid_detectors_set.append(
         | 
| @@ -338,15 +340,15 @@ class RNSA(Base): | |
| 338 340 | 
             
                                        "consider reducing its value."
         | 
| 339 341 | 
             
                                    )
         | 
| 340 342 |  | 
| 341 | 
            -
                        #  | 
| 343 | 
            +
                        # Add detectors, with classes as keys in the dictionary.
         | 
| 342 344 | 
             
                        list_detectors_by_class[_class_] = valid_detectors_set
         | 
| 343 | 
            -
                    #  | 
| 345 | 
            +
                    # Notify completion of detector generation for the classes.
         | 
| 344 346 | 
             
                    if verbose:
         | 
| 345 347 | 
             
                        progress.set_description(
         | 
| 346 348 | 
             
                            f'\033[92m✔ Non-self detectors for classes ({", ".join(map(str, self.classes))}) '
         | 
| 347 349 | 
             
                            f'successfully generated\033[0m'
         | 
| 348 350 | 
             
                        )
         | 
| 349 | 
            -
                    #  | 
| 351 | 
            +
                    # Saves the found detectors in the attribute for the non-self detectors of the trained model.
         | 
| 350 352 | 
             
                    self.detectors = list_detectors_by_class
         | 
| 351 353 | 
             
                    return self
         | 
| 352 354 |  | 
| @@ -382,7 +384,7 @@ class RNSA(Base): | |
| 382 384 | 
             
                        contendo as classes previstas para ``X``.
         | 
| 383 385 | 
             
                        * ``None``: Se não existir detectores para a previsão.
         | 
| 384 386 | 
             
                    """
         | 
| 385 | 
            -
                    #  | 
| 387 | 
            +
                    # If there are no detectors, returns None.
         | 
| 386 388 | 
             
                    if self.detectors is None:
         | 
| 387 389 | 
             
                        return None
         | 
| 388 390 | 
             
                    elif not isinstance(X, (np.ndarray, list)):
         | 
| @@ -394,9 +396,9 @@ class RNSA(Base): | |
| 394 396 | 
             
                            )
         | 
| 395 397 | 
             
                        )
         | 
| 396 398 |  | 
| 397 | 
            -
                    #  | 
| 399 | 
            +
                    # Initializes an empty array that will store the predictions.
         | 
| 398 400 | 
             
                    C = np.empty(shape=0)
         | 
| 399 | 
            -
                    #  | 
| 401 | 
            +
                    # For each sample row in X.
         | 
| 400 402 | 
             
                    for line in X:
         | 
| 401 403 | 
             
                        class_found: bool
         | 
| 402 404 | 
             
                        _class_ = self.__compare_sample_to_detectors(line)
         | 
| @@ -406,11 +408,11 @@ class RNSA(Base): | |
| 406 408 | 
             
                            C = np.append(C, [_class_])
         | 
| 407 409 | 
             
                            class_found = True
         | 
| 408 410 |  | 
| 409 | 
            -
                        #  | 
| 411 | 
            +
                        # If there is only one class and the sample is not classified, set the output as non-self.
         | 
| 410 412 | 
             
                        if not class_found and len(self.classes) == 1:
         | 
| 411 413 | 
             
                            C = np.append(C, [self.non_self_label])
         | 
| 412 | 
            -
                        #  | 
| 413 | 
            -
                        #  | 
| 414 | 
            +
                        # If the class is not identified with the detectors, assign the class with the greatest distance
         | 
| 415 | 
            +
                        # from the mean of its detectors.
         | 
| 414 416 | 
             
                        elif not class_found:
         | 
| 415 417 | 
             
                            average_distance: dict = {}
         | 
| 416 418 | 
             
                            for _class_ in self.classes:
         | 
| @@ -424,8 +426,40 @@ class RNSA(Base): | |
| 424 426 | 
             
                            C = np.append(C, [max(average_distance, key=average_distance.get)])
         | 
| 425 427 | 
             
                    return C
         | 
| 426 428 |  | 
| 429 | 
            +
                def __slice_index_list_by_class(self, y: npt.NDArray) -> dict:
         | 
| 430 | 
            +
                    """
         | 
| 431 | 
            +
                    The function ``__slice_index_list_by_class(...)``, separates the indices of the lines according \
         | 
| 432 | 
            +
                    to the output class, to loop through the sample array, only in positions where the output is \
         | 
| 433 | 
            +
                    the class being trained.
         | 
| 434 | 
            +
             | 
| 435 | 
            +
                    Parameters:
         | 
| 436 | 
            +
                    ---
         | 
| 437 | 
            +
                        * y (npt.NDArray): Receives a ``y``[``N sample``] array with the output classes of the \
         | 
| 438 | 
            +
                            ``X`` sample array.
         | 
| 439 | 
            +
             | 
| 440 | 
            +
                    returns:
         | 
| 441 | 
            +
                    ---
         | 
| 442 | 
            +
                        * dict: A dictionary with the list of array positions(``y``), with the classes as key.
         | 
| 443 | 
            +
             | 
| 444 | 
            +
                    ---
         | 
| 445 | 
            +
             | 
| 446 | 
            +
                    A função ``__slice_index_list_by_class(...)``, separa os índices das linhas conforme a classe \
         | 
| 447 | 
            +
                    de saída, para percorrer o array de amostra, apenas nas posições que a saída for a classe que \
         | 
| 448 | 
            +
                    está sendo treinada.
         | 
| 449 | 
            +
             | 
| 450 | 
            +
                    Parameters:
         | 
| 451 | 
            +
                    ---
         | 
| 452 | 
            +
                        * y (npt.NDArray): Recebe um array ``y``[``N amostra``] com as classes de saída do array \
         | 
| 453 | 
            +
                            de amostra ``X``.
         | 
| 454 | 
            +
             | 
| 455 | 
            +
                    Returns:
         | 
| 456 | 
            +
                    ---
         | 
| 457 | 
            +
                        * dict: Um dicionário com a lista de posições do array(``y``), com as classes como chave.
         | 
| 458 | 
            +
                    """
         | 
| 459 | 
            +
                    return slice_index_list_by_class(self.classes, y)
         | 
| 460 | 
            +
             | 
| 427 461 | 
             
                def __checks_valid_detector(self, X: npt.NDArray = None, vector_x: npt.NDArray = None,
         | 
| 428 | 
            -
             | 
| 462 | 
            +
                                            samples_index_class: npt.NDArray = None):
         | 
| 429 463 | 
             
                    """
         | 
| 430 464 | 
             
                    Function to check if the detector has a valid non-proper ``r`` radius for the class.
         | 
| 431 465 |  | 
| @@ -456,26 +490,25 @@ class RNSA(Base): | |
| 456 490 | 
             
                        * Validade (``bool``): Retorna se o detector é válido ou não.
         | 
| 457 491 |  | 
| 458 492 | 
             
                    """
         | 
| 459 | 
            -
                    #  | 
| 493 | 
            +
                    # If any of the input arrays have zero size, returns false.
         | 
| 460 494 | 
             
                    if (np.size(samples_index_class) == 0 or np.size(X) == 0 or np.size(vector_x) == 0):
         | 
| 461 495 | 
             
                        return False
         | 
| 462 | 
            -
                    #  | 
| 463 | 
            -
                    #  | 
| 496 | 
            +
                    # If self.k > 1, uses the k nearest neighbors (kNN); otherwise, checks the detector
         | 
| 497 | 
            +
                    # without considering kNN.
         | 
| 464 498 | 
             
                    if self.k > 1:
         | 
| 465 | 
            -
                        # Iniciar a lista dos knn vazia.
         | 
| 466 499 | 
             
                        knn_list = np.empty(shape=0)
         | 
| 467 500 | 
             
                        for i in samples_index_class:
         | 
| 468 | 
            -
                            #  | 
| 469 | 
            -
                            #  | 
| 501 | 
            +
                            # Calculates the distance between the two vectors and adds it to the kNN list if the
         | 
| 502 | 
            +
                            # distance is smaller than the largest distance in the list.
         | 
| 470 503 | 
             
                            knn_list = self.__compare_KnearestNeighbors_List(
         | 
| 471 504 | 
             
                                knn_list, self.__distance(X[i], vector_x)
         | 
| 472 505 | 
             
                            )
         | 
| 473 | 
            -
                        #  | 
| 506 | 
            +
                        # If the average of the distances in the kNN list is less than the radius, returns true.
         | 
| 474 507 | 
             
                        distance_mean = np.mean(knn_list)
         | 
| 475 508 | 
             
                        if self._algorithm == "V-detector":
         | 
| 476 509 | 
             
                            return self.__detector_is_valid_to_Vdetector(distance_mean, vector_x)
         | 
| 477 510 | 
             
                        elif distance_mean > (self.r + self.r_s):
         | 
| 478 | 
            -
                            return True | 
| 511 | 
            +
                            return True
         | 
| 479 512 | 
             
                    else:
         | 
| 480 513 | 
             
                        distance: Union[float, None] = None
         | 
| 481 514 | 
             
                        for i in samples_index_class:
         | 
| @@ -486,16 +519,16 @@ class RNSA(Base): | |
| 486 519 | 
             
                                elif distance > new_distance:
         | 
| 487 520 | 
             
                                    distance = new_distance
         | 
| 488 521 | 
             
                            else:
         | 
| 489 | 
            -
                                #  | 
| 490 | 
            -
                                #  | 
| 522 | 
            +
                                # Calculates the distance between the vectors; if it is less than or equal to the radius
         | 
| 523 | 
            +
                                # plus the sample's radius, sets the validity of the detector to false.
         | 
| 491 524 | 
             
                                if (self.r + self.r_s) >= self.__distance(X[i], vector_x):
         | 
| 492 525 | 
             
                                    return False  # Detector não é valido!
         | 
| 493 526 |  | 
| 494 527 | 
             
                        if self._algorithm == "V-detector":
         | 
| 495 528 | 
             
                            return self.__detector_is_valid_to_Vdetector(distance, vector_x)
         | 
| 496 | 
            -
                        return True | 
| 529 | 
            +
                        return True
         | 
| 497 530 |  | 
| 498 | 
            -
                    return False  # Detector  | 
| 531 | 
            +
                    return False  # Detector is not valid!
         | 
| 499 532 |  | 
| 500 533 | 
             
                def __compare_KnearestNeighbors_List(self, knn: npt.NDArray, distance: float) -> npt.NDArray:
         | 
| 501 534 | 
             
                    """
         | 
| @@ -527,12 +560,12 @@ class RNSA(Base): | |
| 527 560 | 
             
                    ---
         | 
| 528 561 | 
             
                        npt.NDArray: Lista de vizinhos mais próximos atualizada e ordenada.
         | 
| 529 562 | 
             
                    """
         | 
| 530 | 
            -
                    #  | 
| 563 | 
            +
                    # If the number of distances in kNN is less than k, adds the distance.
         | 
| 531 564 | 
             
                    if len(knn) < self.k:
         | 
| 532 565 | 
             
                        knn = np.append(knn, distance)
         | 
| 533 566 | 
             
                        knn.sort()
         | 
| 534 567 | 
             
                    else:
         | 
| 535 | 
            -
                        #  | 
| 568 | 
            +
                        # Otherwise, add the distance if the new distance is smaller than the largest distance in the list.
         | 
| 536 569 | 
             
                        if knn[self.k - 1] > distance:
         | 
| 537 570 | 
             
                            knn[self.k - 1] = distance
         | 
| 538 571 | 
             
                            knn.sort()
         | 
| @@ -576,16 +609,14 @@ class RNSA(Base): | |
| 576 609 | 
             
                            a nenhuma classe.
         | 
| 577 610 | 
             
                    """
         | 
| 578 611 |  | 
| 579 | 
            -
                    #  | 
| 612 | 
            +
                    # List to store the classes and the average distance between the detectors and the sample.
         | 
| 580 613 | 
             
                    possible_classes = []
         | 
| 581 614 | 
             
                    for _class_ in self.classes:
         | 
| 582 | 
            -
                        #  | 
| 615 | 
            +
                        # Variable to indicate if the class was found with the detectors.
         | 
| 583 616 | 
             
                        class_found: bool = True
         | 
| 584 | 
            -
                        sum_distance = 0 | 
| 617 | 
            +
                        sum_distance = 0
         | 
| 585 618 | 
             
                        for detector in self.detectors[_class_]:
         | 
| 586 | 
            -
                            # Calcula a distância entre a amostra e os detectores.
         | 
| 587 619 | 
             
                            distance = self.__distance(detector.position, line)
         | 
| 588 | 
            -
                            # Soma as distâncias para calcular a média.
         | 
| 589 620 | 
             
                            sum_distance += distance
         | 
| 590 621 | 
             
                            if self._algorithm == "V-detector":
         | 
| 591 622 | 
             
                                if distance <= detector.radius:
         | 
| @@ -595,17 +626,16 @@ class RNSA(Base): | |
| 595 626 | 
             
                                class_found = False
         | 
| 596 627 | 
             
                                break
         | 
| 597 628 |  | 
| 598 | 
            -
                        #  | 
| 599 | 
            -
                        # possível previsão.
         | 
| 629 | 
            +
                        # If the sample passes through all the detectors of a class, adds the class as a possible prediction.
         | 
| 600 630 | 
             
                        if class_found:
         | 
| 601 631 | 
             
                            possible_classes.append([_class_, sum_distance / self.N])
         | 
| 602 | 
            -
                    #  | 
| 632 | 
            +
                    # If classified as belonging to only one class, returns the class.
         | 
| 603 633 | 
             
                    if len(possible_classes) == 1:
         | 
| 604 634 | 
             
                        return possible_classes[0][0]
         | 
| 605 | 
            -
                    #  | 
| 635 | 
            +
                    # If belonging to more than one class, returns the class with the greatest average distance.
         | 
| 606 636 | 
             
                    elif len(possible_classes) > 1:
         | 
| 607 637 | 
             
                        return max(possible_classes, key=lambda x: x[1])[0]
         | 
| 608 | 
            -
                    else: | 
| 638 | 
            +
                    else:
         | 
| 609 639 | 
             
                        return None
         | 
| 610 640 |  | 
| 611 641 | 
             
                def __distance(self, u: npt.NDArray, v: npt.NDArray):
         | 
| @@ -673,47 +703,15 @@ class RNSA(Base): | |
| 673 703 | 
             
                    """
         | 
| 674 704 | 
             
                    new_detector_r = float(distance - self.r_s)
         | 
| 675 705 | 
             
                    if self.r >= new_detector_r:
         | 
| 676 | 
            -
                        return False | 
| 706 | 
            +
                        return False
         | 
| 677 707 | 
             
                    else:
         | 
| 678 | 
            -
                        #  | 
| 708 | 
            +
                        # If _cell_bounds is True, considers the detector to be within the plane bounds.
         | 
| 679 709 | 
             
                        if self._cell_bounds:
         | 
| 680 710 | 
             
                            for p in vector_x:
         | 
| 681 711 | 
             
                                if (p - new_detector_r) < 0 or (p + new_detector_r) > 1:
         | 
| 682 712 | 
             
                                    return False
         | 
| 683 713 | 
             
                        return True, new_detector_r
         | 
| 684 714 |  | 
| 685 | 
            -
                def __slice_index_list_by_class(self, y: npt.NDArray) -> dict:
         | 
| 686 | 
            -
                    """
         | 
| 687 | 
            -
                    The function ``__slice_index_list_by_class(...)``, separates the indices of the lines \
         | 
| 688 | 
            -
                    according to the output class, to loop through the sample array, only in positions where \
         | 
| 689 | 
            -
                    the output is the class being trained.
         | 
| 690 | 
            -
             | 
| 691 | 
            -
                    Parameters:
         | 
| 692 | 
            -
                    ---
         | 
| 693 | 
            -
                        * y (npt.NDArray): Receives a ``y``[``N sample``] array with the output classes of the \
         | 
| 694 | 
            -
                            ``X`` sample array.
         | 
| 695 | 
            -
             | 
| 696 | 
            -
                    returns:
         | 
| 697 | 
            -
                    ---
         | 
| 698 | 
            -
                        * dict: A dictionary with the list of array positions(``y``), with the classes as key.
         | 
| 699 | 
            -
             | 
| 700 | 
            -
                    ---
         | 
| 701 | 
            -
             | 
| 702 | 
            -
                    A função ``__slice_index_list_by_class(...)``, separa os índices das linhas conforme a classe \
         | 
| 703 | 
            -
                    de saída, para percorrer o array de amostra, apenas nas posições que a saída for a classe que \
         | 
| 704 | 
            -
                    está sendo treinada.
         | 
| 705 | 
            -
             | 
| 706 | 
            -
                    Parameters:
         | 
| 707 | 
            -
                    ---
         | 
| 708 | 
            -
                        * y (npt.NDArray): Recebe um array ``y``[``N amostra``] com as classes de saída do array \
         | 
| 709 | 
            -
                            de amostra ``X``.
         | 
| 710 | 
            -
             | 
| 711 | 
            -
                    Returns:
         | 
| 712 | 
            -
                    ---
         | 
| 713 | 
            -
                        * dict: Um dicionário com a lista de posições do array(``y``), com as classes como chave.
         | 
| 714 | 
            -
                    """
         | 
| 715 | 
            -
                    return super()._slice_index_list_by_class(y)
         | 
| 716 | 
            -
             | 
| 717 715 | 
             
                def score(self, X: npt.NDArray, y: list) -> float:
         | 
| 718 716 | 
             
                    """
         | 
| 719 717 | 
             
                    Score function calculates forecast accuracy.
         | 
| @@ -931,41 +929,41 @@ class BNSA(Base): | |
| 931 929 | 
             
                    """
         | 
| 932 930 | 
             
                    super()._check_and_raise_exceptions_fit(X, y, "BNSA")
         | 
| 933 931 |  | 
| 934 | 
            -
                    #  | 
| 932 | 
            +
                    # Converts the entire array X to boolean
         | 
| 935 933 | 
             
                    if X.dtype != bool:
         | 
| 936 934 | 
             
                        X = X.astype(bool)
         | 
| 937 935 |  | 
| 938 | 
            -
                    #  | 
| 936 | 
            +
                    # Identifying the possible classes within the output array `y`.
         | 
| 939 937 | 
             
                    self.classes = np.unique(y)
         | 
| 940 | 
            -
                    #  | 
| 938 | 
            +
                    # Dictionary that will store detectors with classes as keys.
         | 
| 941 939 | 
             
                    list_detectors_by_class = dict()
         | 
| 942 | 
            -
                    #  | 
| 940 | 
            +
                    # Separates the classes for training.
         | 
| 943 941 | 
             
                    sample_index: dict = self.__slice_index_list_by_class(y)
         | 
| 944 | 
            -
                    #  | 
| 942 | 
            +
                    # Progress bar for generating all detectors.
         | 
| 945 943 | 
             
                    if verbose:
         | 
| 946 944 | 
             
                        progress = tqdm(total=int(self.N * (len(self.classes))),
         | 
| 947 945 | 
             
                                        bar_format='{desc} ┇{bar}┇ {n}/{total} detectors', postfix='\n')
         | 
| 948 946 |  | 
| 949 947 | 
             
                    for _class_ in self.classes:
         | 
| 950 | 
            -
                        #  | 
| 948 | 
            +
                        # Initializes the empty set that will contain the valid detectors.
         | 
| 951 949 | 
             
                        valid_detectors_set: list = []
         | 
| 952 950 | 
             
                        discard_count: int = 0
         | 
| 953 | 
            -
                        #  | 
| 951 | 
            +
                        # Updating the progress bar with the current class the algorithm is processing.
         | 
| 954 952 | 
             
                        if verbose:
         | 
| 955 953 | 
             
                            progress.set_description_str(
         | 
| 956 954 | 
             
                                f"Generating the detectors for the {_class_} class:")
         | 
| 957 955 | 
             
                        while len(valid_detectors_set) < self.N:
         | 
| 958 956 |  | 
| 959 957 | 
             
                            is_valid_detector: bool = True
         | 
| 960 | 
            -
                            #  | 
| 958 | 
            +
                            # Generates a candidate detector vector randomly with values 0 and 1.
         | 
| 961 959 | 
             
                            vector_x = np.random.choice([False, True], size=X.shape[1])
         | 
| 962 | 
            -
                            #  | 
| 963 | 
            -
                            distances = cdist(np.expand_dims(vector_x, axis=0), | 
| 960 | 
            +
                            # Calculates the distance between the candidate and the class samples.
         | 
| 961 | 
            +
                            distances = cdist(np.expand_dims(vector_x, axis=0),
         | 
| 964 962 | 
             
                                              X[sample_index[_class_]], metric='hamming')
         | 
| 965 | 
            -
                            #  | 
| 963 | 
            +
                            # Checks if any of the distances is below or equal to the threshold.
         | 
| 966 964 | 
             
                            is_valid_detector = not np.any(distances <= self.aff_thresh)
         | 
| 967 965 |  | 
| 968 | 
            -
                            #  | 
| 966 | 
            +
                            # If the detector is valid, add it to the list of valid detectors.
         | 
| 969 967 | 
             
                            if is_valid_detector:
         | 
| 970 968 | 
             
                                discard_count = 0
         | 
| 971 969 | 
             
                                valid_detectors_set.append(vector_x)
         | 
| @@ -981,15 +979,15 @@ class BNSA(Base): | |
| 981 979 | 
             
                                        "radius and consider reducing its value."
         | 
| 982 980 | 
             
                                    )
         | 
| 983 981 |  | 
| 984 | 
            -
                        #  | 
| 982 | 
            +
                        # Add detectors to the dictionary with classes as keys.
         | 
| 985 983 | 
             
                        list_detectors_by_class[_class_] = valid_detectors_set
         | 
| 986 984 |  | 
| 987 | 
            -
                    #  | 
| 985 | 
            +
                    # Notify the completion of detector generation for the classes.
         | 
| 988 986 | 
             
                    if verbose:
         | 
| 989 987 | 
             
                        progress.set_description(
         | 
| 990 988 | 
             
                            f'\033[92m✔ Non-self detectors for classes ({", ".join(map(str, self.classes))}) '
         | 
| 991 989 | 
             
                            f'successfully generated\033[0m')
         | 
| 992 | 
            -
                    #  | 
| 990 | 
            +
                    # Saves the found detectors in the attribute for the class detectors.
         | 
| 993 991 | 
             
                    self.detectors = list_detectors_by_class
         | 
| 994 992 | 
             
                    return self
         | 
| 995 993 |  | 
| @@ -1025,7 +1023,7 @@ class BNSA(Base): | |
| 1025 1023 | 
             
                        contendo as classes previstas para ``X``.
         | 
| 1026 1024 | 
             
                        * ``None``: Se não existir detectores para a previsão.
         | 
| 1027 1025 | 
             
                    """
         | 
| 1028 | 
            -
                    #  | 
| 1026 | 
            +
                    # If there are no detectors, returns None.
         | 
| 1029 1027 | 
             
                    if self.detectors is None:
         | 
| 1030 1028 | 
             
                        return None
         | 
| 1031 1029 | 
             
                    elif not isinstance(X, (np.ndarray, list)):
         | 
| @@ -1036,45 +1034,42 @@ class BNSA(Base): | |
| 1036 1034 | 
             
                                len(self.detectors[self.classes[0]][0])
         | 
| 1037 1035 | 
             
                            )
         | 
| 1038 1036 | 
             
                        )
         | 
| 1039 | 
            -
                    #  | 
| 1037 | 
            +
                    # Checks if matrix X contains only binary samples. Otherwise, raises an exception.
         | 
| 1040 1038 | 
             
                    if not np.isin(X, [0, 1]).all():
         | 
| 1041 1039 | 
             
                        raise ValueError(
         | 
| 1042 1040 | 
             
                            "The array X contains values that are not composed only of 0 and 1."
         | 
| 1043 1041 | 
             
                        )
         | 
| 1044 1042 |  | 
| 1045 | 
            -
                    #  | 
| 1043 | 
            +
                    # Converts the entire array X to boolean.
         | 
| 1046 1044 | 
             
                    if X.dtype != bool:
         | 
| 1047 1045 | 
             
                        X = X.astype(bool)
         | 
| 1048 1046 |  | 
| 1049 | 
            -
                    #  | 
| 1047 | 
            +
                    # Initializes an empty array that will store the predictions.
         | 
| 1050 1048 | 
             
                    C = np.empty(shape=0)
         | 
| 1051 | 
            -
                    #  | 
| 1049 | 
            +
                    # For each sample row in X.
         | 
| 1052 1050 | 
             
                    for line in X:
         | 
| 1053 1051 | 
             
                        class_found: bool = True
         | 
| 1054 | 
            -
                        #  | 
| 1055 | 
            -
                        #  | 
| 1052 | 
            +
                        # List to store the possible classes to which the sample matches with self
         | 
| 1053 | 
            +
                        # when compared to the non-self detectors.
         | 
| 1056 1054 | 
             
                        possible_classes: list = []
         | 
| 1057 1055 | 
             
                        for _class_ in self.classes:
         | 
| 1058 | 
            -
                            # Lista para armazenar as taxas de similaridade entre a amostra e os detectores.
         | 
| 1059 1056 | 
             
                            similarity_sum: float = 0
         | 
| 1060 | 
            -
             | 
| 1061 | 
            -
                            # Calcula a distância de Hamming entre a linha e todos os detectores
         | 
| 1057 | 
            +
                            # Calculates the Hamming distance between the row and all detectors.
         | 
| 1062 1058 | 
             
                            distances = cdist(np.expand_dims(line, axis=0),
         | 
| 1063 1059 | 
             
                                              self.detectors[_class_], metric='hamming')
         | 
| 1064 1060 |  | 
| 1065 | 
            -
                            #  | 
| 1061 | 
            +
                            # Check if any distance is below or equal to the threshold.
         | 
| 1066 1062 | 
             
                            if np.any(distances <= self.aff_thresh):
         | 
| 1067 1063 | 
             
                                class_found = False
         | 
| 1068 1064 | 
             
                            else:
         | 
| 1069 | 
            -
                                # Somar todas as distâncias
         | 
| 1070 1065 | 
             
                                similarity_sum = np.sum(distances)
         | 
| 1071 1066 |  | 
| 1072 | 
            -
                            #  | 
| 1073 | 
            -
                            #  | 
| 1067 | 
            +
                            # If the sample passes through all detectors of a class, adds the class as a possible prediction
         | 
| 1068 | 
            +
                            # and its average similarity.
         | 
| 1074 1069 | 
             
                            if class_found:
         | 
| 1075 1070 | 
             
                                possible_classes.append([_class_, similarity_sum / self.N])
         | 
| 1076 1071 |  | 
| 1077 | 
            -
                        #  | 
| 1072 | 
            +
                        # If belonging to one or more classes, adds the class with the greatest average distance.
         | 
| 1078 1073 | 
             
                        if len(possible_classes) > 0:
         | 
| 1079 1074 | 
             
                            C = np.append(
         | 
| 1080 1075 | 
             
                                C, [max(possible_classes, key=lambda x: x[1])[0]])
         | 
| @@ -1082,24 +1077,24 @@ class BNSA(Base): | |
| 1082 1077 | 
             
                        else:
         | 
| 1083 1078 | 
             
                            class_found = False
         | 
| 1084 1079 |  | 
| 1085 | 
            -
                        #  | 
| 1080 | 
            +
                        # If there is only one class and the sample is not classified, sets the output as non-self.
         | 
| 1086 1081 | 
             
                        if not class_found and len(self.classes) == 1:
         | 
| 1087 1082 | 
             
                            C = np.append(C, ["non-self"])
         | 
| 1088 | 
            -
                        #  | 
| 1083 | 
            +
                        # If the class cannot be identified by the detectors
         | 
| 1089 1084 | 
             
                        elif not class_found:
         | 
| 1090 1085 | 
             
                            class_differences: dict = {}
         | 
| 1091 1086 | 
             
                            for _class_ in self.classes:
         | 
| 1092 | 
            -
                                #  | 
| 1087 | 
            +
                                # Assign the label to the class with the greatest distance from the nearest detector.
         | 
| 1093 1088 | 
             
                                if self.no_label_sample_selection == 'nearest_difference':
         | 
| 1094 | 
            -
                                    difference_min: float = cdist( | 
| 1095 | 
            -
             | 
| 1096 | 
            -
             | 
| 1089 | 
            +
                                    difference_min: float = cdist(np.expand_dims(line, axis=0),
         | 
| 1090 | 
            +
                                                                  self.detectors[_class_], metric='hamming'
         | 
| 1091 | 
            +
                                                                  ).min()
         | 
| 1097 1092 | 
             
                                    class_differences[_class_] = difference_min
         | 
| 1098 | 
            -
                                #  | 
| 1093 | 
            +
                                # Or based on the greatest distance from the average distances of the detectors.
         | 
| 1099 1094 | 
             
                                else:
         | 
| 1100 | 
            -
                                    difference_sum: float = cdist( | 
| 1101 | 
            -
             | 
| 1102 | 
            -
             | 
| 1095 | 
            +
                                    difference_sum: float = cdist(np.expand_dims(line, axis=0),
         | 
| 1096 | 
            +
                                                                  self.detectors[_class_], metric='hamming'
         | 
| 1097 | 
            +
                                                                  ).sum()
         | 
| 1103 1098 | 
             
                                    class_differences[_class_] = difference_sum / self.N
         | 
| 1104 1099 |  | 
| 1105 1100 | 
             
                            C = np.append(C, [max(class_differences, key=class_differences.get)])
         | 
| @@ -1136,7 +1131,7 @@ class BNSA(Base): | |
| 1136 1131 | 
             
                    ---
         | 
| 1137 1132 | 
             
                        * dict: Um dicionário com a lista de posições do array(``y``), com as classes como chave.
         | 
| 1138 1133 | 
             
                    """
         | 
| 1139 | 
            -
                    return  | 
| 1134 | 
            +
                    return slice_index_list_by_class(self.classes, y)
         | 
| 1140 1135 |  | 
| 1141 1136 | 
             
                def score(self, X: npt.NDArray, y: list) -> float:
         | 
| 1142 1137 | 
             
                    """
         | 
    
        aisp/utils/__init__.py
    ADDED
    
    
| @@ -0,0 +1,43 @@ | |
| 1 | 
            +
            from typing import Union
         | 
| 2 | 
            +
            import numpy as np
         | 
| 3 | 
            +
            import numpy.typing as npt
         | 
| 4 | 
            +
             | 
| 5 | 
            +
             | 
| 6 | 
            +
            def slice_index_list_by_class(classes: Union[npt.NDArray, list], y: npt.NDArray) -> dict:
         | 
| 7 | 
            +
                """
         | 
| 8 | 
            +
                The function ``__slice_index_list_by_class(...)``, separates the indices of the lines \
         | 
| 9 | 
            +
                according to the output class, to loop through the sample array, only in positions where \
         | 
| 10 | 
            +
                the output is the class being trained.
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                Parameters:
         | 
| 13 | 
            +
                ---
         | 
| 14 | 
            +
                    * classes (``list or npt.NDArray``): list with unique classes.
         | 
| 15 | 
            +
                    * y (npt.NDArray): Receives a ``y``[``N sample``] array with the output classes of the \
         | 
| 16 | 
            +
                        ``X`` sample array.
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                returns:
         | 
| 19 | 
            +
                ---
         | 
| 20 | 
            +
                    * dict: A dictionary with the list of array positions(``y``), with the classes as key.
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                ---
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                A função ``__slice_index_list_by_class(...)``, separa os índices das linhas conforme a \
         | 
| 25 | 
            +
                classe de saída, para percorrer o array de amostra, apenas nas posições que a saída for \
         | 
| 26 | 
            +
                a classe que está sendo treinada.
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                Parameters:
         | 
| 29 | 
            +
                ---
         | 
| 30 | 
            +
                    * classes (``list or npt.NDArray``): lista com classes únicas.
         | 
| 31 | 
            +
                    * y (npt.NDArray): Recebe um array ``y``[``N amostra``] com as classes de saída do \
         | 
| 32 | 
            +
                        array de amostra ``X``.
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                Returns:
         | 
| 35 | 
            +
                ---
         | 
| 36 | 
            +
                    * dict: Um dicionário com a lista de posições do array(``y``), com as classes como chave.
         | 
| 37 | 
            +
                """
         | 
| 38 | 
            +
                position_samples = dict()
         | 
| 39 | 
            +
                for _class_ in classes:
         | 
| 40 | 
            +
                    # Gets the sample positions by class from y.
         | 
| 41 | 
            +
                    position_samples[_class_] = list(np.nonzero(y == _class_)[0])
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                return position_samples
         | 
    
        aisp/utils/metrics.py
    ADDED
    
    | @@ -0,0 +1,61 @@ | |
| 1 | 
            +
            from typing import Union
         | 
| 2 | 
            +
            import numpy as np
         | 
| 3 | 
            +
            import numpy.typing as npt
         | 
| 4 | 
            +
             | 
| 5 | 
            +
             | 
| 6 | 
            +
            def accuracy_score(
         | 
| 7 | 
            +
                    y_true: Union[npt.NDArray, list],
         | 
| 8 | 
            +
                    y_pred: Union[npt.NDArray, list]
         | 
| 9 | 
            +
            ) -> float:
         | 
| 10 | 
            +
                """
         | 
| 11 | 
            +
                Function to calculate precision accuracy based on lists of true labels and
         | 
| 12 | 
            +
                predicted labels.
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                Parameters:
         | 
| 15 | 
            +
                ---
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                    * y_true (``Union[npt.NDArray, list]``): Ground truth (correct) labels. \
         | 
| 18 | 
            +
                        Expected to be of the same length as `y_pred`.
         | 
| 19 | 
            +
                    * y_pred (``Union[npt.NDArray, list]``): Predicted labels. Expected to \
         | 
| 20 | 
            +
                        be of the same length as `y_true`.
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                Returns:
         | 
| 23 | 
            +
                ---
         | 
| 24 | 
            +
                    * Accuracy (``float``): The ratio of correct predictions to the total \
         | 
| 25 | 
            +
                    number of predictions.
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                Raises:
         | 
| 28 | 
            +
                ---
         | 
| 29 | 
            +
                    * ValueError: If `y_true` or `y_pred` are empty or if they do not have the same length.
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                ---
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                Função para calcular a acurácia de precisão com base em listas de rótulos
         | 
| 34 | 
            +
                verdadeiros e nos rótulos previstos.
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                Parâmetros:
         | 
| 37 | 
            +
                ---
         | 
| 38 | 
            +
                    * y_true (``Union[npt.NDArray, list]``): Rótulos verdadeiros (corretos)..
         | 
| 39 | 
            +
                    * y_pred (``Union[npt.NDArray, list]``): Rótulos previstos.
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                Retornos:
         | 
| 42 | 
            +
                ---
         | 
| 43 | 
            +
                    * Precisão (``float``): A proporção de previsões corretas em relação
         | 
| 44 | 
            +
                    ao número total de previsões.
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                Lança:
         | 
| 47 | 
            +
                ---
         | 
| 48 | 
            +
                    * ValueError: Se `y_true` ou `y_pred` estiverem vazios ou se não
         | 
| 49 | 
            +
                    tiverem o mesmo tamanho.
         | 
| 50 | 
            +
                """
         | 
| 51 | 
            +
                n = len(y_true)
         | 
| 52 | 
            +
                if n == 0:
         | 
| 53 | 
            +
                    raise ValueError(
         | 
| 54 | 
            +
                        "Division by zero: y_true cannot be an empty list or array."
         | 
| 55 | 
            +
                    )
         | 
| 56 | 
            +
                elif n != len(y_pred):
         | 
| 57 | 
            +
                    raise ValueError(
         | 
| 58 | 
            +
                        f"Error: The arrays must have the same size. Size of y_true: "
         | 
| 59 | 
            +
                        f"{len(y_true)}, Size of y_pred: {len(y_pred)}"
         | 
| 60 | 
            +
                    )
         | 
| 61 | 
            +
                return np.sum(np.sum(np.array(y_true) == np.array(y_pred))) / n
         | 
| @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            Metadata-Version: 2.1
         | 
| 2 2 | 
             
            Name: aisp
         | 
| 3 | 
            -
            Version: 0.1. | 
| 3 | 
            +
            Version: 0.1.33
         | 
| 4 4 | 
             
            Summary: Package with techniques of artificial immune systems.
         | 
| 5 5 | 
             
            Author-email: João Paulo da Silva Barros <jpsilvabarr@gmail.com>
         | 
| 6 6 | 
             
            Maintainer-email: Alison Zille Lopes <alisonzille@gmail.com>
         | 
| @@ -63,7 +63,6 @@ Requires-Dist: tqdm >=4.64.1 | |
| 63 63 | 
             
            > 2. [Installation.](#installation)
         | 
| 64 64 | 
             
            >    1. [Dependencies](#dependencies)
         | 
| 65 65 | 
             
            >    2. [User installation](#user-installation)
         | 
| 66 | 
            -
            >    3. [How to import the Techniques](#how-to-import-the-techniques)
         | 
| 67 66 | 
             
            > 3. [Examples.](#examples)
         | 
| 68 67 |  | 
| 69 68 | 
             
            ---
         | 
| @@ -81,8 +80,8 @@ Artificial Immune Systems (AIS) are inspired by the vertebrate immune system, cr | |
| 81 80 | 
             
            ##### Algorithms implemented:
         | 
| 82 81 |  | 
| 83 82 | 
             
            > - [x] [**Negative Selection.**](https://ais-package.github.io/docs/aisp-techniques/Negative%20Selection/)
         | 
| 83 | 
            +
            > - [ ] *Clonal Selection Algorithms.*
         | 
| 84 84 | 
             
            > - [ ] *Dendritic Cells.*
         | 
| 85 | 
            -
            > - [ ] *Clonalg.*
         | 
| 86 85 | 
             
            > - [ ] *Immune Network Theory.*
         | 
| 87 86 |  | 
| 88 87 | 
             
            </section>
         | 
| @@ -119,17 +118,7 @@ pip install aisp | |
| 119 118 | 
             
            ```
         | 
| 120 119 |  | 
| 121 120 | 
             
            </section>
         | 
| 122 | 
            -
            <section id='how-to-import-the-techniques'>
         | 
| 123 121 |  | 
| 124 | 
            -
            ##### **How to import the Techniques**
         | 
| 125 | 
            -
             | 
| 126 | 
            -
            ``` Python
         | 
| 127 | 
            -
            from aisp.NSA import RNSA
         | 
| 128 | 
            -
             | 
| 129 | 
            -
            nsa = RNSA(N=300, r=0.05)
         | 
| 130 | 
            -
            ```
         | 
| 131 | 
            -
             | 
| 132 | 
            -
            </section>
         | 
| 133 122 | 
             
            </section>
         | 
| 134 123 | 
             
            <section id='examples'>
         | 
| 135 124 |  | 
| @@ -173,7 +162,6 @@ Below are some examples that use a database for classification with the [Jupyter | |
| 173 162 | 
             
            > 2. [Instalação.](#instalação)
         | 
| 174 163 | 
             
            >    1. [Dependências](#dependências)
         | 
| 175 164 | 
             
            >    2. [Instalação do usuário](#instalação-do-usuário)
         | 
| 176 | 
            -
            >    3. [Como importar as Tecnicas](#como-importar-as-tecnicas)
         | 
| 177 165 | 
             
            > 3. [Exemplos.](#exemplos)
         | 
| 178 166 |  | 
| 179 167 | 
             
            ---
         | 
| @@ -190,8 +178,8 @@ Os sistemas imunológicos artificiais (SIA) inspiram-se no sistema imunológico | |
| 190 178 | 
             
            ##### Algoritmos implementados:
         | 
| 191 179 |  | 
| 192 180 | 
             
            > - [x] [**Seleção Negativa.**](https://ais-package.github.io/docs/aisp-techniques/Negative%20Selection/)
         | 
| 181 | 
            +
            > - [ ] *Algoritmos de Seleção Clonal.*
         | 
| 193 182 | 
             
            > - [ ] *Células Dendríticas.*
         | 
| 194 | 
            -
            > - [ ] *Clonalg.*
         | 
| 195 183 | 
             
            > - [ ] *Teoria da Rede Imune.*
         | 
| 196 184 |  | 
| 197 185 | 
             
            </section>
         | 
| @@ -229,17 +217,6 @@ pip install aisp | |
| 229 217 |  | 
| 230 218 | 
             
            </section>
         | 
| 231 219 |  | 
| 232 | 
            -
            <section id='como-importar-as-tecnicas'>
         | 
| 233 | 
            -
             | 
| 234 | 
            -
            ##### **Como importar as Tecnicas**
         | 
| 235 | 
            -
             | 
| 236 | 
            -
            ``` Python
         | 
| 237 | 
            -
            from aisp.NSA import RNSA
         | 
| 238 | 
            -
             | 
| 239 | 
            -
            nsa = RNSA(N=300, r=0.05)
         | 
| 240 | 
            -
            ```
         | 
| 241 | 
            -
             | 
| 242 | 
            -
            </section>
         | 
| 243 220 | 
             
            </section>
         | 
| 244 221 | 
             
            <section id='exemplos'>
         | 
| 245 222 |  | 
| @@ -0,0 +1,11 @@ | |
| 1 | 
            +
            aisp/NSA/__init__.py,sha256=b0KSfocc9p4s4AQatyEBDfQuVmMqZ18rCieTUpWnQ7c,143
         | 
| 2 | 
            +
            aisp/NSA/_base.py,sha256=iqmsLoM7yBC_EPFZXvdsQjI1bidz1A87ZFyht0P--fI,10861
         | 
| 3 | 
            +
            aisp/NSA/_negative_selection.py,sha256=AqsOJYkZlb2kP48b35FFIwU_fGedLpZw5JY9hpnzkXM,54897
         | 
| 4 | 
            +
            aisp/utils/__init__.py,sha256=c8OCaR9IAQ21vpxWqtLplB84W_UKdWceI--yw7sBMi0,163
         | 
| 5 | 
            +
            aisp/utils/_multiclass.py,sha256=aoxSqnemNjs5uJAk7a1GumNDa-q-LOw6TWluwQ10tR4,1597
         | 
| 6 | 
            +
            aisp/utils/metrics.py,sha256=xp9A52-QsP0cJGIlYprrI7BrVwQN6gqCLINVJumlIDI,1908
         | 
| 7 | 
            +
            aisp-0.1.33.dist-info/LICENSE,sha256=fTqV5eBpeAZO0_jit8j4Ref9ikBSlHJ8xwj5TLg7gFk,7817
         | 
| 8 | 
            +
            aisp-0.1.33.dist-info/METADATA,sha256=M2czdHGPXbXXVOKUckfYMwwPpnj_Lt49dU5PRfLd_jw,7562
         | 
| 9 | 
            +
            aisp-0.1.33.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
         | 
| 10 | 
            +
            aisp-0.1.33.dist-info/top_level.txt,sha256=Q5aJi_rAVT5UNS1As0ZafoyS5dwNibnoyOYV7RWUB9s,5
         | 
| 11 | 
            +
            aisp-0.1.33.dist-info/RECORD,,
         | 
    
        aisp-0.1.32.dist-info/RECORD
    DELETED
    
    | @@ -1,8 +0,0 @@ | |
| 1 | 
            -
            aisp/NSA/__init__.py,sha256=cmHx6ydTfhFAOfgCjDcKDJRfH5Sz41LHqVRlDZgVL58,141
         | 
| 2 | 
            -
            aisp/NSA/_base.py,sha256=HjdF4ZnophMY_Ooj2ERjhVoWwqe8Q4rPQ-UxHlfIeNY,9557
         | 
| 3 | 
            -
            aisp/NSA/_negative_selection.py,sha256=bYbkorRTY3V7_gS0L1QnYxpoy-KGsGDxwhza0RjhcKM,55330
         | 
| 4 | 
            -
            aisp-0.1.32.dist-info/LICENSE,sha256=fTqV5eBpeAZO0_jit8j4Ref9ikBSlHJ8xwj5TLg7gFk,7817
         | 
| 5 | 
            -
            aisp-0.1.32.dist-info/METADATA,sha256=0SxlcxhAKPH1XSkIENEp2zIxu_YKvq-yqSLu-dISNsI,7999
         | 
| 6 | 
            -
            aisp-0.1.32.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
         | 
| 7 | 
            -
            aisp-0.1.32.dist-info/top_level.txt,sha256=Q5aJi_rAVT5UNS1As0ZafoyS5dwNibnoyOYV7RWUB9s,5
         | 
| 8 | 
            -
            aisp-0.1.32.dist-info/RECORD,,
         | 
| 
            File without changes
         | 
| 
            File without changes
         |