aisp 0.2.1__py3-none-any.whl → 0.3.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aisp/__init__.py +25 -3
- aisp/base/__init__.py +3 -1
- aisp/base/_base.py +65 -0
- aisp/base/_classifier.py +5 -16
- aisp/base/_clusterer.py +77 -0
- aisp/csa/__init__.py +1 -1
- aisp/csa/{_ai_immune_recognition_sys.py → _ai_recognition_sys.py} +27 -29
- aisp/csa/_base.py +0 -1
- aisp/ina/__init__.py +14 -0
- aisp/ina/_ai_network.py +552 -0
- aisp/ina/_base.py +124 -0
- aisp/nsa/__init__.py +2 -1
- aisp/nsa/_binary_negative_selection.py +239 -0
- aisp/nsa/_negative_selection.py +22 -253
- aisp/utils/distance.py +4 -4
- aisp/utils/validation.py +5 -5
- {aisp-0.2.1.dist-info → aisp-0.3.1.dist-info}/METADATA +6 -5
- aisp-0.3.1.dist-info/RECORD +31 -0
- aisp-0.2.1.dist-info/RECORD +0 -25
- {aisp-0.2.1.dist-info → aisp-0.3.1.dist-info}/WHEEL +0 -0
- {aisp-0.2.1.dist-info → aisp-0.3.1.dist-info}/licenses/LICENSE +0 -0
- {aisp-0.2.1.dist-info → aisp-0.3.1.dist-info}/top_level.txt +0 -0
aisp/__init__.py
CHANGED
@@ -1,4 +1,26 @@
|
|
1
|
-
"""Artificial Immune Systems Package.
|
1
|
+
"""AISP - Artificial Immune Systems Package.
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
AISP is a Python package of immunoinspired techniques that apply metaphors from the vertebrate
|
4
|
+
immune system to pattern recognition and optimization tasks.
|
5
|
+
|
6
|
+
The package is organized into specialized modules, each dedicated to a family of Artificial
|
7
|
+
Immune Systems algorithms:
|
8
|
+
- csa: Clonal Selection Algorithms
|
9
|
+
- nsa: Negative Selection Algorithms
|
10
|
+
- ina: Immune Network Algorithms
|
11
|
+
|
12
|
+
For detailed documentation and examples, visit:
|
13
|
+
https://ais-package.github.io/docs/intro
|
14
|
+
"""
|
15
|
+
|
16
|
+
from . import csa
|
17
|
+
from . import nsa
|
18
|
+
from . import ina
|
19
|
+
|
20
|
+
__author__ = "AISP Development Team"
|
21
|
+
__version__ = "0.3.1"
|
22
|
+
__all__ = [
|
23
|
+
'csa',
|
24
|
+
'nsa',
|
25
|
+
'ina'
|
26
|
+
]
|
aisp/base/__init__.py
CHANGED
aisp/base/_base.py
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
"""Base class for parameter introspection compatible with the scikit-learn API."""
|
2
|
+
import random
|
3
|
+
|
4
|
+
import numpy as np
|
5
|
+
from numba import njit
|
6
|
+
|
7
|
+
|
8
|
+
class Base:
|
9
|
+
"""
|
10
|
+
Generic base class for models with a common interface.
|
11
|
+
|
12
|
+
Provides the ``get_params`` and ``set_params`` method for compatibility with
|
13
|
+
the scikit-learn API, allowing access to the model's public parameters.
|
14
|
+
"""
|
15
|
+
|
16
|
+
def set_params(self, **params):
|
17
|
+
"""
|
18
|
+
Set the parameters of the instance.
|
19
|
+
|
20
|
+
This method is required to ensure compatibility with scikit-learn functions
|
21
|
+
|
22
|
+
Parameters
|
23
|
+
----------
|
24
|
+
**params
|
25
|
+
set as attributes on the instance.
|
26
|
+
|
27
|
+
Returns
|
28
|
+
-------
|
29
|
+
self
|
30
|
+
"""
|
31
|
+
for key, value in params.items():
|
32
|
+
if not key.startswith("_") and hasattr(self, key):
|
33
|
+
setattr(self, key, value)
|
34
|
+
return self
|
35
|
+
|
36
|
+
def get_params(self, deep: bool = True) -> dict: # pylint: disable=W0613
|
37
|
+
"""
|
38
|
+
Return a dictionary with the object's main parameters.
|
39
|
+
|
40
|
+
This method is required to ensure compatibility with scikit-learn functions.
|
41
|
+
|
42
|
+
Returns
|
43
|
+
-------
|
44
|
+
dict
|
45
|
+
Dictionary containing the object's attributes that do not start with "_".
|
46
|
+
"""
|
47
|
+
return {
|
48
|
+
key: value
|
49
|
+
for key, value in self.__dict__.items()
|
50
|
+
if not key.startswith("_")
|
51
|
+
}
|
52
|
+
|
53
|
+
|
54
|
+
@njit(cache=True)
|
55
|
+
def set_seed_numba(seed: int):
|
56
|
+
"""
|
57
|
+
Set the seed for random numbers used by functions compiled with Numba.
|
58
|
+
|
59
|
+
Parameters
|
60
|
+
----------
|
61
|
+
seed : int
|
62
|
+
Integer value used to initialize Numba's random number generator.
|
63
|
+
"""
|
64
|
+
np.random.seed(seed)
|
65
|
+
random.seed(seed)
|
aisp/base/_classifier.py
CHANGED
@@ -1,25 +1,26 @@
|
|
1
1
|
"""Base class for classification algorithm."""
|
2
2
|
|
3
|
+
from __future__ import annotations
|
3
4
|
from abc import ABC, abstractmethod
|
4
5
|
from typing import Optional, Union
|
5
6
|
|
6
7
|
import numpy.typing as npt
|
7
8
|
|
9
|
+
from ._base import Base
|
8
10
|
from ..utils import slice_index_list_by_class
|
9
11
|
from ..utils.metrics import accuracy_score
|
10
12
|
|
11
13
|
|
12
|
-
class BaseClassifier(ABC):
|
14
|
+
class BaseClassifier(ABC, Base):
|
13
15
|
"""Base class for classification algorithms.
|
14
16
|
|
15
|
-
Defines the abstract methods ``fit`` and ``predict``, and implements the ``score
|
16
|
-
``get_params`` method.
|
17
|
+
Defines the abstract methods ``fit`` and ``predict``, and implements the ``score`` method.
|
17
18
|
"""
|
18
19
|
|
19
20
|
classes: Union[npt.NDArray, list] = []
|
20
21
|
|
21
22
|
@abstractmethod
|
22
|
-
def fit(self, X: npt.NDArray, y: npt.NDArray, verbose: bool = True) ->
|
23
|
+
def fit(self, X: npt.NDArray, y: npt.NDArray, verbose: bool = True) -> BaseClassifier:
|
23
24
|
"""
|
24
25
|
Train the model using the input data X and corresponding labels y.
|
25
26
|
|
@@ -106,15 +107,3 @@ class BaseClassifier(ABC):
|
|
106
107
|
A dictionary with the list of array positions(``y``), with the classes as key.
|
107
108
|
"""
|
108
109
|
return slice_index_list_by_class(self.classes, y)
|
109
|
-
|
110
|
-
def get_params(self, deep: bool = True) -> dict: # pylint: disable=W0613
|
111
|
-
"""
|
112
|
-
Return a dictionary with the object's main parameters.
|
113
|
-
|
114
|
-
This method is required to ensure compatibility with scikit-learn functions.
|
115
|
-
"""
|
116
|
-
return {
|
117
|
-
key: value
|
118
|
-
for key, value in self.__dict__.items()
|
119
|
-
if not key.startswith("_")
|
120
|
-
}
|
aisp/base/_clusterer.py
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
"""Base class for clustering algorithms."""
|
2
|
+
|
3
|
+
from __future__ import annotations
|
4
|
+
from abc import ABC, abstractmethod
|
5
|
+
from typing import Optional
|
6
|
+
|
7
|
+
import numpy.typing as npt
|
8
|
+
|
9
|
+
from ._base import Base
|
10
|
+
|
11
|
+
|
12
|
+
class BaseClusterer(ABC, Base):
|
13
|
+
"""Abstract base class for clustering algorithms.
|
14
|
+
|
15
|
+
This class defines the core interface for clustering models. It enforces
|
16
|
+
the implementation of the `fit` and `predict` methods in all derived classes,
|
17
|
+
and provides a default implementation for `fit_predict` and `get_params`.
|
18
|
+
"""
|
19
|
+
|
20
|
+
@abstractmethod
|
21
|
+
def fit(self, X: npt.NDArray, verbose: bool = True) -> BaseClusterer:
|
22
|
+
"""
|
23
|
+
Train the model using the input data X.
|
24
|
+
|
25
|
+
This abstract method is implemented by the class that inherits it.
|
26
|
+
|
27
|
+
Parameters
|
28
|
+
----------
|
29
|
+
X : npt.NDArray
|
30
|
+
Input data used for training the model.
|
31
|
+
verbose : bool, default=True
|
32
|
+
Flag to enable or disable detailed output during training.
|
33
|
+
|
34
|
+
Returns
|
35
|
+
-------
|
36
|
+
self : BaseClusterer
|
37
|
+
Returns the instance of the class that implements this method.
|
38
|
+
"""
|
39
|
+
|
40
|
+
@abstractmethod
|
41
|
+
def predict(self, X: npt.NDArray) -> Optional[npt.NDArray]:
|
42
|
+
"""
|
43
|
+
Generate predictions based on the input data X.
|
44
|
+
|
45
|
+
This abstract method is implemented by the class that inherits it.
|
46
|
+
|
47
|
+
Parameters
|
48
|
+
----------
|
49
|
+
X : npt.NDArray
|
50
|
+
Input data for which predictions will be generated.
|
51
|
+
|
52
|
+
Returns
|
53
|
+
-------
|
54
|
+
predictions : Optional[npt.NDArray]
|
55
|
+
Predicted cluster labels for each input sample, or None if prediction is not possible.
|
56
|
+
"""
|
57
|
+
|
58
|
+
def fit_predict(self, X, verbose: bool = True):
|
59
|
+
"""Fit the clustering model to the data and return cluster labels.
|
60
|
+
|
61
|
+
This is a convenience method that combines `fit` and `predict`
|
62
|
+
into a single call.
|
63
|
+
|
64
|
+
Parameters
|
65
|
+
----------
|
66
|
+
X : npt.NDArray
|
67
|
+
Input data for which predictions will be generated.
|
68
|
+
verbose : bool, default=True
|
69
|
+
Flag to enable or disable detailed output during training.
|
70
|
+
|
71
|
+
Returns
|
72
|
+
-------
|
73
|
+
predictions : Optional[npt.NDArray]
|
74
|
+
Predicted cluster labels for each input sample, or None if prediction is not possible.
|
75
|
+
"""
|
76
|
+
self.fit(X, verbose)
|
77
|
+
return self.predict(X)
|
aisp/csa/__init__.py
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
CSAs are inspired by the process of antibody proliferation upon detecting an antigen, during which
|
4
4
|
the generated antibodies undergo mutations in an attempt to enhance pathogen recognition.
|
5
5
|
"""
|
6
|
-
from .
|
6
|
+
from ._ai_recognition_sys import AIRS
|
7
7
|
|
8
8
|
__author__ = 'João Paulo da Silva Barros'
|
9
9
|
__all__ = ['AIRS']
|
@@ -1,5 +1,6 @@
|
|
1
1
|
"""Artificial Immune Recognition System (AIRS)."""
|
2
2
|
|
3
|
+
from __future__ import annotations
|
3
4
|
import random
|
4
5
|
from collections import Counter
|
5
6
|
from heapq import nlargest
|
@@ -11,7 +12,7 @@ import numpy.typing as npt
|
|
11
12
|
from scipy.spatial.distance import pdist
|
12
13
|
from tqdm import tqdm
|
13
14
|
|
14
|
-
|
15
|
+
from ..base import set_seed_numba
|
15
16
|
from ._cell import Cell
|
16
17
|
from ..utils.sanitizers import sanitize_param, sanitize_seed, sanitize_choice
|
17
18
|
from ..utils.distance import hamming, compute_metric_distance, get_metric_code
|
@@ -178,6 +179,7 @@ class AIRS(BaseAIRS):
|
|
178
179
|
self.seed: Optional[int] = sanitize_seed(seed)
|
179
180
|
if self.seed is not None:
|
180
181
|
np.random.seed(self.seed)
|
182
|
+
set_seed_numba(self.seed)
|
181
183
|
|
182
184
|
self._feature_type: FeatureType = "continuous-features"
|
183
185
|
|
@@ -188,6 +190,7 @@ class AIRS(BaseAIRS):
|
|
188
190
|
self.p: np.float64 = np.float64(kwargs.get("p", 2.0))
|
189
191
|
|
190
192
|
self._cells_memory = None
|
193
|
+
self._all_class_cell_vectors = None
|
191
194
|
self.affinity_threshold = 0.0
|
192
195
|
self.classes = []
|
193
196
|
self._bounds: Optional[npt.NDArray[np.float64]] = None
|
@@ -197,7 +200,7 @@ class AIRS(BaseAIRS):
|
|
197
200
|
"""Returns the trained cells memory, organized by class."""
|
198
201
|
return self._cells_memory
|
199
202
|
|
200
|
-
def fit(self, X: npt.NDArray, y: npt.NDArray, verbose: bool = True) ->
|
203
|
+
def fit(self, X: npt.NDArray, y: npt.NDArray, verbose: bool = True) -> AIRS:
|
201
204
|
"""
|
202
205
|
Fit the model to the training data using the AIRS.
|
203
206
|
|
@@ -219,8 +222,6 @@ class AIRS(BaseAIRS):
|
|
219
222
|
AIRS
|
220
223
|
Returns the instance itself.
|
221
224
|
"""
|
222
|
-
progress = None
|
223
|
-
|
224
225
|
self._feature_type = detect_vector_data_type(X)
|
225
226
|
|
226
227
|
super()._check_and_raise_exceptions_fit(X, y)
|
@@ -234,18 +235,17 @@ class AIRS(BaseAIRS):
|
|
234
235
|
|
235
236
|
self.classes = np.unique(y)
|
236
237
|
sample_index = self._slice_index_list_by_class(y)
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
238
|
+
progress = tqdm(
|
239
|
+
total=len(y),
|
240
|
+
postfix="\n",
|
241
|
+
disable=not verbose,
|
242
|
+
bar_format="{desc} ┇{bar}┇ {n}/{total} memory cells for each aᵢ",
|
243
|
+
)
|
243
244
|
pool_cells_classes = {}
|
244
245
|
for _class_ in self.classes:
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
)
|
246
|
+
progress.set_description_str(
|
247
|
+
f"Generating the memory cells for the {_class_} class:"
|
248
|
+
)
|
249
249
|
|
250
250
|
x_class = X[sample_index[_class_]]
|
251
251
|
# Calculating the similarity threshold between antigens
|
@@ -294,16 +294,20 @@ class AIRS(BaseAIRS):
|
|
294
294
|
if self._affinity(c_candidate.vector, c_match.vector) < sufficiently_similar:
|
295
295
|
pool_c.remove(c_match)
|
296
296
|
|
297
|
-
|
298
|
-
progress.update(1)
|
297
|
+
progress.update(1)
|
299
298
|
pool_cells_classes[_class_] = pool_c
|
300
299
|
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
300
|
+
progress.set_description(
|
301
|
+
f"\033[92m✔ Set of memory cells for classes ({', '.join(map(str, self.classes))}) "
|
302
|
+
f"successfully generated\033[0m"
|
303
|
+
)
|
304
|
+
progress.close()
|
306
305
|
self._cells_memory = pool_cells_classes
|
306
|
+
self._all_class_cell_vectors = [
|
307
|
+
(class_name, cell.vector)
|
308
|
+
for class_name in self.classes
|
309
|
+
for cell in self._cells_memory[class_name]
|
310
|
+
]
|
307
311
|
return self
|
308
312
|
|
309
313
|
def predict(self, X: npt.NDArray) -> Optional[npt.NDArray]:
|
@@ -325,7 +329,7 @@ class AIRS(BaseAIRS):
|
|
325
329
|
An ndarray of the form ``C`` [``N samples``], containing the predicted classes for
|
326
330
|
``X``. or ``None``: If there are no detectors for the prediction.
|
327
331
|
"""
|
328
|
-
if self.
|
332
|
+
if self._all_class_cell_vectors is None:
|
329
333
|
return None
|
330
334
|
|
331
335
|
super()._check_and_raise_exceptions_predict(
|
@@ -334,16 +338,10 @@ class AIRS(BaseAIRS):
|
|
334
338
|
|
335
339
|
c: list = []
|
336
340
|
|
337
|
-
all_cells_memory = [
|
338
|
-
(class_name, cell.vector)
|
339
|
-
for class_name in self.classes
|
340
|
-
for cell in self._cells_memory[class_name]
|
341
|
-
]
|
342
|
-
|
343
341
|
for line in X:
|
344
342
|
label_stim_list = [
|
345
343
|
(class_name, self._affinity(memory, line))
|
346
|
-
for class_name, memory in
|
344
|
+
for class_name, memory in self._all_class_cell_vectors
|
347
345
|
]
|
348
346
|
# Create the list with the k nearest neighbors and select the class with the most votes
|
349
347
|
k_nearest = nlargest(self.k, label_stim_list, key=lambda x: x[1])
|
aisp/csa/_base.py
CHANGED
aisp/ina/__init__.py
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
"""Module (ina) Immune Network Algorithm.
|
2
|
+
|
3
|
+
This module implements algorithms based on Network Theory Algorithms proposed by Jerne.
|
4
|
+
|
5
|
+
Classes
|
6
|
+
-------
|
7
|
+
AiNet
|
8
|
+
Artificial Immune Network implementation for clustering.
|
9
|
+
"""
|
10
|
+
|
11
|
+
from ._ai_network import AiNet
|
12
|
+
|
13
|
+
__author__ = 'João Paulo da Silva Barros'
|
14
|
+
__all__ = ['AiNet']
|