Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions aisp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,17 @@
https://ais-package.github.io/docs/intro
"""

from importlib.metadata import version
from importlib.metadata import version, PackageNotFoundError

from . import csa
from . import ina
from . import nsa

try:
__version__ = version('aisp')
except PackageNotFoundError:
__version__ = '0.dev'

__author__ = "AISP Development Team"
__version__ = version('aisp')

__all__ = ["csa", "nsa", "ina"]
56 changes: 34 additions & 22 deletions aisp/csa/_ai_recognition_sys.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from __future__ import annotations

import random
from numbers import Real
from operator import attrgetter
from typing import List, Optional, Dict, Tuple, Any, Union

Expand All @@ -18,14 +19,19 @@
from ..utils.distance import hamming, compute_metric_distance, get_metric_code
from ..utils.multiclass import predict_knn_affinity
from ..utils.random import set_seed_numba
from ..utils.sanitizers import sanitize_param, sanitize_seed, sanitize_choice
from ..utils.types import FeatureType, MetricType
from ..utils.validation import (
detect_vector_data_type,
check_array_type,
check_shape_match,
check_feature_dimension,
check_binary_array,
positive,
is_type,
between,
choice,
optional,
validate_parameters,
)


Expand Down Expand Up @@ -111,6 +117,22 @@ class AIRS(BaseClassifier):
[0 1]
"""

@validate_parameters(
n_resources=(is_type(Real), positive),
rate_clonal=(is_type(int), positive),
rate_mc_init=(is_type(Real), between(0, 1)),
rate_hypermutation=(is_type(Real), positive),
affinity_threshold_scalar=(is_type(Real), positive),
k=(is_type(int), positive),
max_iters=(is_type(int), positive),
resource_amplified=(is_type(Real), positive),
metric=(
is_type(str),
choice(["manhattan", "minkowski", "euclidean"])
),
seed=optional((is_type(int), positive)),
p=(is_type(Real), positive),
)
def __init__(
self,
n_resources: float = 10,
Expand All @@ -125,33 +147,23 @@ def __init__(
seed: Optional[int] = None,
p: float = 2.0,
) -> None:
self.n_resources: float = sanitize_param(n_resources, 10, lambda x: x >= 1)
self.rate_mc_init: float = sanitize_param(
rate_mc_init, 0.2, lambda x: 0 < x <= 1
)
self.rate_clonal: int = sanitize_param(rate_clonal, 10, lambda x: x > 0)
self.rate_hypermutation: float = sanitize_param(
rate_hypermutation, 0.75, lambda x: x > 0
)
self.affinity_threshold_scalar: float = sanitize_param(
affinity_threshold_scalar, 0.75, lambda x: x > 0
)
self.resource_amplified: float = sanitize_param(
resource_amplified, 1, lambda x: x > 1
)
self.k: int = sanitize_param(k, 3, lambda x: x > 0)
self.max_iters: int = sanitize_param(max_iters, 100, lambda x: x > 0)
self.seed: Optional[int] = sanitize_seed(seed)
self.n_resources: float = n_resources
self.rate_mc_init: float = rate_mc_init
self.rate_clonal: int = rate_clonal
self.rate_hypermutation: float = rate_hypermutation
self.affinity_threshold_scalar: float = affinity_threshold_scalar
self.resource_amplified: float = resource_amplified
self.k: int = k
self.max_iters: int = max_iters
self.metric = metric
self.seed: Optional[int] = seed
if self.seed is not None:
np.random.seed(self.seed)
set_seed_numba(self.seed)
self.p: float = p

self._feature_type: FeatureType = "continuous-features"

self.metric = sanitize_choice(metric, ["manhattan", "minkowski"], "euclidean")

self.p: float = p

self._cells_memory: Optional[Dict[str | int, list[BCell]]] = None
self._all_class_cell_vectors: Optional[List[Tuple[Any, np.ndarray]]] = None
self.affinity_threshold: float = 0.0
Expand Down
49 changes: 27 additions & 22 deletions aisp/csa/_clonalg.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from __future__ import annotations

import heapq
from numbers import Real
from typing import Optional, Callable, Dict, Literal, List

import numpy as np
Expand All @@ -19,8 +20,9 @@
from ..base.immune.populations import generate_random_antibodies
from ..utils.display import ProgressTable
from ..utils.random import set_seed_numba
from ..utils.sanitizers import sanitize_seed, sanitize_param, sanitize_bounds
from ..utils.sanitizers import sanitize_bounds
from ..utils.types import FeatureTypeAll
from ..utils.validation import validate_parameters, is_type, positive, choice, optional


class Clonalg(BaseOptimizer):
Expand Down Expand Up @@ -106,6 +108,22 @@ class Clonalg(BaseOptimizer):
Best cost: 0.02623036956750724
"""

@validate_parameters(
problem_size=(is_type(int), positive),
N=(is_type(int), positive),
rate_clonal=(is_type(int), positive),
rate_hypermutation=(is_type(Real), positive),
n_diversity_injection=(is_type(int), positive),
selection_size=(is_type(int), positive),
feature_type=(
is_type(str),
choice([
"binary-features", "continuous-features", "ranged-features", "permutation-features"
])
),
mode=(is_type(str), choice(["min", "max"])),
seed=optional((is_type(int), positive))
)
def __init__(
self,
problem_size: int,
Expand All @@ -121,34 +139,21 @@ def __init__(
seed: Optional[int] = None,
):
super().__init__()
self.problem_size = sanitize_param(problem_size, 1, lambda x: x > 0)
self.N: int = sanitize_param(N, 50, lambda x: x > 0)
self.rate_clonal: int = sanitize_param(rate_clonal, 10, lambda x: x > 0)
self.rate_hypermutation: np.float64 = np.float64(
sanitize_param(
rate_hypermutation, 1.0, lambda x: x > 0
)
)
self.n_diversity_injection: int = sanitize_param(
n_diversity_injection, 5, lambda x: x > 0
)
self.selection_size: int = sanitize_param(
selection_size, 5, lambda x: x > 0
)
self.problem_size = problem_size
self.N: int = N
self.rate_clonal: int = rate_clonal
self.rate_hypermutation: float = rate_hypermutation
self.n_diversity_injection: int = n_diversity_injection
self.selection_size: int = selection_size
self._affinity_function = affinity_function
self.feature_type: FeatureTypeAll = feature_type
self.mode: Literal["min", "max"] = mode
self.seed: Optional[int] = seed

self._bounds: Optional[Dict] = None
self._bounds_extend_cache: Optional[np.ndarray] = None
self.bounds = bounds

self.mode: Literal["min", "max"] = sanitize_param(
mode,
"min",
lambda x: x == "max"
)

self.seed: Optional[int] = sanitize_seed(seed)
if self.seed is not None:
np.random.seed(self.seed)
set_seed_numba(self.seed)
Expand Down
60 changes: 30 additions & 30 deletions aisp/ina/_ai_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from __future__ import annotations

from numbers import Real
from typing import Optional, Dict, List, Tuple, Union

import numpy as np
Expand All @@ -22,13 +23,12 @@
from ..utils.distance import hamming, compute_metric_distance, get_metric_code
from ..utils.multiclass import predict_knn_affinity
from ..utils.random import set_seed_numba
from ..utils.sanitizers import sanitize_choice, sanitize_param, sanitize_seed
from ..utils.types import FeatureType, MetricType
from ..utils.validation import (
detect_vector_data_type,
check_array_type,
check_feature_dimension,
check_binary_array,
check_binary_array, validate_parameters, is_type, positive, choice, optional, non_negative,
)


Expand Down Expand Up @@ -124,11 +124,27 @@ class AiNet(BaseClusterer):
[0 1]
"""

@validate_parameters(
N=(is_type(int), positive),
n_clone=(is_type(int), positive),
top_clonal_memory_size=optional((is_type(int), positive)),
affinity_threshold=(is_type(Real), positive),
suppression_threshold=(is_type(Real), positive),
mst_inconsistency_factor=(is_type(Real), non_negative),
max_iterations=(is_type(int), positive),
k=(is_type(int), positive),
metric=(
is_type(str),
choice(["manhattan", "minkowski", "euclidean"])
),
seed=optional((is_type(int), positive)),
p=(is_type(Real), positive),
)
def __init__(
self,
N: int = 50,
n_clone: int = 10,
top_clonal_memory_size: int = 5,
top_clonal_memory_size: Optional[int] = 5,
n_diversity_injection: int = 5,
affinity_threshold: float = 0.5,
suppression_threshold: float = 0.5,
Expand All @@ -140,39 +156,23 @@ def __init__(
use_mst_clustering: bool = True,
p: float = 2.0
):
self.N: int = sanitize_param(N, 50, lambda x: x > 0)
self.n_clone: int = sanitize_param(n_clone, 10, lambda x: x > 0)

self.top_clonal_memory_size: Optional[int] = None
if top_clonal_memory_size is not None:
self.top_clonal_memory_size = sanitize_param(
top_clonal_memory_size, 5, lambda x: x > 0
)

self.n_diversity_injection: int = sanitize_param(
n_diversity_injection, 5, lambda x: x > 0
)
self.affinity_threshold: float = sanitize_param(
affinity_threshold, 0.5, lambda x: x > 0
)
self.suppression_threshold: float = sanitize_param(
suppression_threshold, 0.5, lambda x: x > 0
)
self.mst_inconsistency_factor: float = sanitize_param(
mst_inconsistency_factor, 2, lambda x: x >= 0
)
self.max_iterations: int = sanitize_param(max_iterations, 10, lambda x: x > 0)
self.k: int = sanitize_param(k, 1, lambda x: x > 0)
self.seed: Optional[int] = sanitize_seed(seed)
self.N: int = N
self.n_clone: int = n_clone
self.top_clonal_memory_size: Optional[int] = top_clonal_memory_size
self.n_diversity_injection: int = n_diversity_injection
self.affinity_threshold: float = affinity_threshold
self.suppression_threshold: float = suppression_threshold
self.mst_inconsistency_factor: float = mst_inconsistency_factor
self.max_iterations: int = max_iterations
self.k: int = k
self.seed: Optional[int] = seed
self.use_mst_clustering: bool = use_mst_clustering
if self.seed is not None:
np.random.seed(self.seed)
set_seed_numba(self.seed)

self._feature_type: FeatureType = "continuous-features"
self.metric: str = sanitize_choice(
metric, ["euclidean", "manhattan", "minkowski"], "euclidean"
)
self.metric: str = metric

self.p: float = p
self._metric_params = {}
Expand Down
36 changes: 22 additions & 14 deletions aisp/nsa/_binary_negative_selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from __future__ import annotations

from numbers import Real
from typing import Dict, Literal, Optional, Union

import numpy as np
Expand All @@ -11,12 +12,12 @@
from ..base import BaseClassifier
from ..exceptions import MaxDiscardsReachedError, ModelNotFittedError
from ..utils.display import ProgressBar
from ..utils.sanitizers import sanitize_seed, sanitize_param
from ..utils.random import set_seed_numba
from ..utils.validation import (
check_array_type,
check_shape_match,
check_binary_array,
check_feature_dimension,
check_feature_dimension, validate_parameters, positive, choice, between, optional, is_type,
)


Expand Down Expand Up @@ -96,6 +97,16 @@ class BNSA(BaseClassifier):
['non-self' 'self']
"""

@validate_parameters(
N=(is_type(int), positive),
aff_thresh=(is_type(Real), between(0, 1)),
max_discards=(is_type(int), positive),
seed=optional((is_type(int), positive)),
no_label_sample_selection=(
is_type(str),
choice(["max_average_difference", "max_nearest_difference"])
),
)
def __init__(
self,
N: int = 100,
Expand All @@ -106,25 +117,22 @@ def __init__(
"max_average_difference", "max_nearest_difference"
] = "max_average_difference",
):
self.N: int = sanitize_param(N, 100, lambda x: x > 0)
self.aff_thresh: float = sanitize_param(aff_thresh, 0.1, lambda x: 0 < x < 1)
self.max_discards: int = sanitize_param(max_discards, 1000, lambda x: x > 0)
self.N: int = N
self.aff_thresh: float = aff_thresh
self.max_discards: int = max_discards

self.seed: Optional[int] = sanitize_seed(seed)
self.seed: Optional[int] = seed

if self.seed is not None:
np.random.seed(seed)

self.no_label_sample_selection: str = sanitize_param(
no_label_sample_selection,
"max_average_difference",
lambda x: x == "max_nearest_difference",
)
self.no_label_sample_selection: str = no_label_sample_selection

self.classes: Optional[npt.NDArray] = None
self._detectors: Optional[dict] = None
self._detectors_stack: Optional[npt.NDArray] = None

if self.seed is not None:
np.random.seed(seed)
set_seed_numba(self.seed)

@property
def detectors(self) -> Optional[Dict[str | int, npt.NDArray[np.bool_]]]:
"""Return the trained detectors, organized by class."""
Expand Down
Loading
Loading