1
0
Fork 0

Updated Docs

master
Luca Moretti 4 years ago
parent 2d476188b5
commit 5f1eac5765
  1. 173
      main_package/classes/estimators/fam_score_calculator.py
  2. 87
      main_package/classes/estimators/parameters_estimator.py
  3. 2
      main_package/classes/estimators/structure_constraint_based_estimator.py
  4. 10
      main_package/classes/estimators/structure_estimator.py
  5. 85
      main_package/classes/estimators/structure_score_based_estimator.py
  6. 23
      main_package/classes/optimizers/constraint_based_optimizer.py
  7. 34
      main_package/classes/optimizers/hill_climbing_search.py
  8. 12
      main_package/classes/optimizers/optimizer.py
  9. 40
      main_package/classes/optimizers/tabu_search.py
  10. 20
      main_package/classes/structure_graph/conditional_intensity_matrix.py
  11. 45
      main_package/classes/utility/cache.py

@ -27,7 +27,7 @@ import structure_graph.conditional_intensity_matrix as cim_class
class FamScoreCalculator: class FamScoreCalculator:
""" """
Has the task of calculating the FamScore of a node Has the task of calculating the FamScore of a node by using a Bayesian score function
""" """
def __init__(self): def __init__(self):
@ -38,16 +38,20 @@ class FamScoreCalculator:
def marginal_likelihood_theta(self, def marginal_likelihood_theta(self,
cims: cim_class.ConditionalIntensityMatrix, cims: cim_class.ConditionalIntensityMatrix,
alpha_xu: float = 1, alpha_xu: float,
alpha_xxu: float = 1): alpha_xxu: float):
""" """
calculate the FamScore value of the node identified by the label node_id Calculate the FamScore value of the node identified by the label node_id
Parameters:
cims: np.array with all the node's cims, :param cims: np.array with all the node's cims
alpha_xu: hyperparameter over the CTBNs q parameters :type cims: np.array
alpha_xxu: hyperparameter over the CTBNs theta parameters :param alpha_xu: hyperparameter over the CTBNs q parameters, default to 0.1
Returns: :type alpha_xu: float
the value of the marginal likelihood over theta :param alpha_xxu: distribuited hyperparameter over the CTBNs theta parameters
:type alpha_xxu: float
:return: the value of the marginal likelihood over theta
:rtype: float
""" """
return np.sum( return np.sum(
[self.variable_cim_xu_marginal_likelihood_theta(cim, [self.variable_cim_xu_marginal_likelihood_theta(cim,
@ -57,16 +61,20 @@ class FamScoreCalculator:
def variable_cim_xu_marginal_likelihood_theta(self, def variable_cim_xu_marginal_likelihood_theta(self,
cim: cim_class.ConditionalIntensityMatrix, cim: cim_class.ConditionalIntensityMatrix,
alpha_xu: float = 1, alpha_xu: float,
alpha_xxu: float = 1): alpha_xxu: float):
""" """
calculate the value of the marginal likelihood over theta given a cim Calculate the value of the marginal likelihood over theta given a cim
Parameters:
cim: A conditional_intensity_matrix object with the sufficient statistics, :param cim: A conditional_intensity_matrix object with the sufficient statistics
alpha_xu: hyperparameter over the CTBNs q parameters :type cim: class:'ConditionalIntensityMatrix'
alpha_xxu: hyperparameter over the CTBNs theta parameters :param alpha_xu: hyperparameter over the CTBNs q parameters, default to 0.1
Returns: :type alpha_xu: float
the value of the marginal likelihood over theta :param alpha_xxu: distribuited hyperparameter over the CTBNs theta parameters
:type alpha_xxu: float
:return: the value of the marginal likelihood over theta
:rtype: float
""" """
'get cim length' 'get cim length'
@ -84,18 +92,21 @@ class FamScoreCalculator:
def single_cim_xu_marginal_likelihood_theta(self, def single_cim_xu_marginal_likelihood_theta(self,
index: int, index: int,
cim: cim_class.ConditionalIntensityMatrix, cim: cim_class.ConditionalIntensityMatrix,
alpha_xu: float = 1, alpha_xu: float,
alpha_xxu: float = 1): alpha_xxu: float):
""" """
calculate the marginal likelihood on q of the node when assumes a specif value Calculate the marginal likelihood on q of the node when assumes a specif value
and a specif parents's assignment and a specif parents's assignment
Parameters:
index: current x instance's index :param cim: A conditional_intensity_matrix object with the sufficient statistics
cim: A conditional_intensity_matrix object with the sufficient statistics, :type cim: class:'ConditionalIntensityMatrix'
alpha_xu: hyperparameter over the CTBNs q parameters :param alpha_xu: hyperparameter over the CTBNs q parameters
alpha_xxu: hyperparameter over the CTBNs theta parameters :type alpha_xu: float
Returns: :param alpha_xxu: distribuited hyperparameter over the CTBNs theta parameters
the marginal likelihood of the node when assumes a specif value :type alpha_xxu: float
:return: the value of the marginal likelihood over theta when the node assumes a specif value
:rtype: float
""" """
values = list(range(len(cim._state_residence_times))) values = list(range(len(cim._state_residence_times)))
@ -118,12 +129,16 @@ class FamScoreCalculator:
M_xxu_suff_stats: float, M_xxu_suff_stats: float,
alpha_xxu: float=1): alpha_xxu: float=1):
""" """
calculate the second part of the marginal likelihood over theta formula Calculate the second part of the marginal likelihood over theta formula
Parameters:
M_xxu_suff_stats: value of the suffucient statistic M[xx'|u]
alpha_xxu: hyperparameter over the CTBNs theta parameters :param M_xxu_suff_stats: value of the suffucient statistic M[xx'|u]
Returns: :type M_xxu_suff_stats: float
the marginal likelihood of the node when assumes a specif value :param alpha_xxu: distribuited hyperparameter over the CTBNs theta parameters
:type alpha_xxu: float
:return: the value of the marginal likelihood over theta when the node assumes a specif value
:rtype: float
""" """
return loggamma(alpha_xxu+M_xxu_suff_stats) - loggamma(alpha_xxu) return loggamma(alpha_xxu+M_xxu_suff_stats) - loggamma(alpha_xxu)
@ -133,32 +148,42 @@ class FamScoreCalculator:
def marginal_likelihood_q(self, def marginal_likelihood_q(self,
cims: np.array, cims: np.array,
tau_xu: float=1, tau_xu: float=0.1,
alpha_xu: float=1): alpha_xu: float=1):
""" """
calculate the value of the marginal likelihood over q of the node identified by the label node_id Calculate the value of the marginal likelihood over q of the node identified by the label node_id
Parameters:
cims: np.array with all the node's cims, :param cims: np.array with all the node's cims
tau_xu: hyperparameter over the CTBNs q parameters :type cims: np.array
alpha_xu: hyperparameter over the CTBNs q parameters :param tau_xu: hyperparameter over the CTBNs q parameters
Returns: :type tau_xu: float
the value of the marginal likelihood over q :param alpha_xu: hyperparameter over the CTBNs q parameters
:type alpha_xu: float
:return: the value of the marginal likelihood over q
:rtype: float
""" """
return np.sum([self.variable_cim_xu_marginal_likelihood_q(cim, tau_xu, alpha_xu) for cim in cims]) return np.sum([self.variable_cim_xu_marginal_likelihood_q(cim, tau_xu, alpha_xu) for cim in cims])
def variable_cim_xu_marginal_likelihood_q(self, def variable_cim_xu_marginal_likelihood_q(self,
cim: cim_class.ConditionalIntensityMatrix, cim: cim_class.ConditionalIntensityMatrix,
tau_xu: float=1, tau_xu: float=0.1,
alpha_xu: float=1): alpha_xu: float=1):
""" """
calculate the value of the marginal likelihood over q given a cim Calculate the value of the marginal likelihood over q given a cim
Parameters:
cim: A conditional_intensity_matrix object with the sufficient statistics, :param cim: A conditional_intensity_matrix object with the sufficient statistics
tau_xu: hyperparameter over the CTBNs q parameters :type cim: class:'ConditionalIntensityMatrix'
alpha_xu: hyperparameter over the CTBNs q parameters :param tau_xu: hyperparameter over the CTBNs q parameters
Returns: :type tau_xu: float
the value of the marginal likelihood over q :param alpha_xu: hyperparameter over the CTBNs q parameters
:type alpha_xu: float
:return: the value of the marginal likelihood over q
:rtype: float
""" """
'get cim length' 'get cim length'
@ -177,18 +202,26 @@ class FamScoreCalculator:
def single_cim_xu_marginal_likelihood_q(self, def single_cim_xu_marginal_likelihood_q(self,
M_xu_suff_stats: float, M_xu_suff_stats: float,
T_xu_suff_stats: float, T_xu_suff_stats: float,
tau_xu: float=1, tau_xu: float=0.1,
alpha_xu: float=1): alpha_xu: float=1):
""" """
calculate the marginal likelihood on q of the node when assumes a specif value Calculate the marginal likelihood on q of the node when assumes a specif value
and a specif parents's assignment and a specif parents's assignment
Parameters:
M_xu_suff_stats: value of the suffucient statistic M[x|u] :param M_xu_suff_stats: value of the suffucient statistic M[x|u]
T_xu_suff_stats: value of the suffucient statistic T[x|u] :type M_xxu_suff_stats: float
tau_xu: hyperparameter over the CTBNs q parameters :param T_xu_suff_stats: value of the suffucient statistic T[x|u]
alpha_xu: hyperparameter over the CTBNs q parameters :type T_xu_suff_stats: float
Returns: :param cim: A conditional_intensity_matrix object with the sufficient statistics
the marginal likelihood of the node when assumes a specif value :type cim: class:'ConditionalIntensityMatrix'
:param tau_xu: hyperparameter over the CTBNs q parameters
:type tau_xu: float
:param alpha_xu: hyperparameter over the CTBNs q parameters
:type alpha_xu: float
:return: the value of the marginal likelihood of the node when assumes a specif value
:rtype: float
""" """
return ( return (
loggamma(alpha_xu + M_xu_suff_stats + 1) + loggamma(alpha_xu + M_xu_suff_stats + 1) +
@ -210,13 +243,19 @@ class FamScoreCalculator:
tau_xu: float=0.1, tau_xu: float=0.1,
alpha_xu: float=1): alpha_xu: float=1):
""" """
calculate the FamScore value of the node identified by the label node_id Calculate the FamScore value of the node
Parameters:
cims: np.array with all the node's cims,
tau_xu: hyperparameter over the CTBNs q parameters :param cims: np.array with all the node's cims
alpha_xu: hyperparameter over the CTBNs q parameters :type cims: np.array
Returns: :param tau_xu: hyperparameter over the CTBNs q parameters, default to 0.1
the FamScore value of the node :type tau_xu: float, optional
:param alpha_xu: hyperparameter over the CTBNs q parameters, default to 1
:type alpha_xu: float, optional
:return: the FamScore value of the node
:rtype: float
""" """
#print("------") #print("------")
#print(self.marginal_likelihood_q(cims, #print(self.marginal_likelihood_q(cims,

@ -9,42 +9,41 @@ import structure_graph.sets_of_cims_container as acims
class ParametersEstimator: class ParametersEstimator:
""" """Has the task of computing the cims of particular node given the trajectories and the net structure
Has the task of computing the cims of particular node given the trajectories in samplepath and the net structure in the graph ``_net_graph``.
in the graph net_graph
:param trajectories: the trajectories
:sample_path: the container of the trajectories :type trajectories: Trajectory
:net_graph: the net structure :param net_graph: the net structure
:single_set_of_cims: the set of cims object that will hold the cims of the node :type net_graph: NetworkGraph
:_single_set_of_cims: the set of cims object that will hold the cims of the node
""" """
def __init__(self, sample_path: sp.SamplePath, net_graph: ng.NetworkGraph): def __init__(self, sample_path: sp.SamplePath, net_graph: ng.NetworkGraph):
"""Constructor Method
"""
self.sample_path = sample_path self.sample_path = sample_path
self.net_graph = net_graph self.net_graph = net_graph
self.sets_of_cims_struct = None self.sets_of_cims_struct = None
self.single_set_of_cims = None self.single_set_of_cims = None
def fast_init(self, node_id: str): def fast_init(self, node_id: str):
""" """Initializes all the necessary structures for the parameters estimation for the node ``node_id``.
Initializes all the necessary structures for the parameters estimation.
Parameters: :param node_id: the node label
node_id: the node label :type node_id: string
Returns:
void
""" """
p_vals = self.net_graph.aggregated_info_about_nodes_parents[2] p_vals = self.net_graph.aggregated_info_about_nodes_parents[2]
node_states_number = self.net_graph.get_states_number(node_id) node_states_number = self.net_graph.get_states_number(node_id)
self.single_set_of_cims = sofc.SetOfCims(node_id, p_vals, node_states_number, self.net_graph.p_combs) self.single_set_of_cims = sofc.SetOfCims(node_id, p_vals, node_states_number, self.net_graph.p_combs)
def compute_parameters_for_node(self, node_id: str) -> sofc.SetOfCims: def compute_parameters_for_node(self, node_id: str) -> sofc.SetOfCims:
""" """Compute the CIMS of the node identified by the label ``node_id``.
Compute the CIMS of the node identified by the label node_id
Parameters: :param node_id: the node label
node_id: the node label :type node_id: string
Returns: :return: A SetOfCims object filled with the computed CIMS
A setOfCims object filled with the computed CIMS :rtype: SetOfCims
""" """
node_indx = self.net_graph.get_node_indx(node_id) node_indx = self.net_graph.get_node_indx(node_id)
state_res_times = self.single_set_of_cims._state_residence_times state_res_times = self.single_set_of_cims._state_residence_times
@ -65,18 +64,20 @@ class ParametersEstimator:
def compute_state_res_time_for_node(self, node_indx: int, times: np.ndarray, trajectory: np.ndarray, def compute_state_res_time_for_node(self, node_indx: int, times: np.ndarray, trajectory: np.ndarray,
cols_filter: np.ndarray, scalar_indexes_struct: np.ndarray, T: np.ndarray): cols_filter: np.ndarray, scalar_indexes_struct: np.ndarray, T: np.ndarray):
""" """Compute the state residence times for a node and fill the matrix ``T`` with the results
Compute the state residence times for a node and fill the matrix T with the results
:param node_indx: the index of the node
Parameters: :type node_indx: int
node_indx: the index of the node :param times: the times deltas vector
times: the times deltas vector :type times: numpy.array
trajectory: the trajectory :param trajectory: the trajectory
cols_filter: the columns filtering structure :type trajectory: numpy.ndArray
scalar_indexes_struct: the indexing structure :param cols_filter: the columns filtering structure
T: the state residence times vectors :type cols_filter: numpy.array
Returns: :param scalar_indexes_struct: the indexing structure
void :type scalar_indexes_struct: numpy.array
:param T: the state residence times vectors
:type T: numpy.ndArray
""" """
T[:] = np.bincount(np.sum(trajectory[:, cols_filter] * scalar_indexes_struct / scalar_indexes_struct[0], axis=1) T[:] = np.bincount(np.sum(trajectory[:, cols_filter] * scalar_indexes_struct / scalar_indexes_struct[0], axis=1)
.astype(np.int), \ .astype(np.int), \
@ -84,18 +85,18 @@ class ParametersEstimator:
minlength=scalar_indexes_struct[-1]).reshape(-1, T.shape[1]) minlength=scalar_indexes_struct[-1]).reshape(-1, T.shape[1])
def compute_state_transitions_for_a_node(self, node_indx, trajectory, cols_filter, scalar_indexing, M): def compute_state_transitions_for_a_node(self, node_indx, trajectory, cols_filter, scalar_indexing, M):
""" """Compute the state residence times for a node and fill the matrices ``M`` with the results.
Compute the state residence times for a node and fill the matrices M with the results
:param node_indx: the index of the node
Parameters: :type node_indx: int
node_indx: the index of the node :param trajectory: the trajectory
times: the times deltas vector :type trajectory: numpy.ndArray
trajectory: the trajectory :param cols_filter: the columns filtering structure
cols_filter: the columns filtering structure :type cols_filter: numpy.array
scalar_indexes: the indexing structure :param scalar_indexing: the indexing structure
M: the state transition matrices :type scalar_indexing: numpy.array
Returns: :param M: the state transitions matrices
void :type M: numpy.ndArray
""" """
diag_indices = np.array([x * M.shape[1] + x % M.shape[1] for x in range(M.shape[0] * M.shape[1])], diag_indices = np.array([x * M.shape[1] + x % M.shape[1] for x in range(M.shape[0] * M.shape[1])],
dtype=np.int64) dtype=np.int64)

@ -255,7 +255,7 @@ class StructureConstraintBasedEstimator(se.StructureEstimator):
return set(itertools.chain.from_iterable(list_edges_partial)) return set(itertools.chain.from_iterable(list_edges_partial))
@timing_write @timing
def estimate_structure(self,disable_multiprocessing:bool=False): def estimate_structure(self,disable_multiprocessing:bool=False):
return self.ctpc_algorithm(disable_multiprocessing=disable_multiprocessing) return self.ctpc_algorithm(disable_multiprocessing=disable_multiprocessing)

@ -24,13 +24,11 @@ class StructureEstimator(ABC):
""" """
Has the task of estimating the network structure given the trajectories in samplepath. Has the task of estimating the network structure given the trajectories in samplepath.
:sample_path: the sample_path object containing the trajectories and the real structure :param sample_path: the _sample_path object containing the trajectories and the real structure
:type sample_path: SamplePath
:param known_edges: List of known edges
:type known_edges: List
:nodes: the nodes labels
:nodes_vals: the nodes cardinalities
:nodes_indxs: the nodes indexes
:complete_graph: the complete directed graph built using the nodes labels in nodes
:cache: the cache object
""" """
def __init__(self, sample_path: sp.SamplePath, known_edges: typing.List = None): def __init__(self, sample_path: sp.SamplePath, known_edges: typing.List = None):

@ -42,6 +42,15 @@ class StructureScoreBasedEstimator(se.StructureEstimator):
Has the task of estimating the network structure given the trajectories in samplepath by Has the task of estimating the network structure given the trajectories in samplepath by
using a score based approach. using a score based approach.
:param sample_path: the _sample_path object containing the trajectories and the real structure
:type sample_path: SamplePath
:param tau_xu: hyperparameter over the CTBNs q parameters, default to 0.1
:type tau_xu: float, optional
:param alpha_xu: hyperparameter over the CTBNs q parameters, default to 1
:type alpha_xu: float, optional
:param known_edges: List of known edges, default to []
:type known_edges: List, optional
""" """
def __init__(self, sample_path: sp.SamplePath, tau_xu:int=0.1, alpha_xu:int = 1,known_edges: typing.List= []): def __init__(self, sample_path: sp.SamplePath, tau_xu:int=0.1, alpha_xu:int = 1,known_edges: typing.List= []):
@ -50,24 +59,27 @@ class StructureScoreBasedEstimator(se.StructureEstimator):
self.alpha_xu=alpha_xu self.alpha_xu=alpha_xu
@timing_write @timing
def estimate_structure(self, max_parents:int = None, iterations_number:int= 40, def estimate_structure(self, max_parents:int = None, iterations_number:int= 40,
patience:int = None, tabu_length:int = None, tabu_rules_duration:int = None, patience:int = None, tabu_length:int = None, tabu_rules_duration:int = None,
optimizer: str = 'hill',disable_multiprocessing:bool= False ): optimizer: str = 'tabu',disable_multiprocessing:bool= False ):
""" """
Compute the score-based algorithm to find the optimal structure Compute the score-based algorithm to find the optimal structure
Parameters: :param max_parents: maximum number of parents for each variable. If None, disabled, default to None
max_parents: maximum number of parents for each variable. If None, disabled :type max_parents: int, optional
iterations_number: maximum number of optimization algorithm's iteration :param iterations_number: maximum number of optimization algorithm's iteration, default to 40
patience: number of iteration without any improvement before to stop the search.If None, disabled :type iterations_number: int, optional
tabu_length: maximum lenght of the data structures used in the optimization process :param patience: number of iteration without any improvement before to stop the search.If None, disabled, default to None
tabu_rules_duration: number of iterations in which each rule keeps its value :type patience: int, optional
optimzer: name of the optimizer algorithm. Possible values: 'hill' (Hill climbing),'tabu' (tabu search) :param tabu_length: maximum lenght of the data structures used in the optimization process, default to None
disable_multiprocessing: true if you desire to disable the multiprocessing operations :type tabu_length: int, optional
Returns: :param tabu_rules_duration: number of iterations in which each rule keeps its value, default to None
void :type tabu_rules_duration: int, optional
:param optimizer: name of the optimizer algorithm. Possible values: 'hill' (Hill climbing),'tabu' (tabu search), defualt to 'tabu'
:type optimizer: string, optional
:param disable_multiprocessing: true if you desire to disable the multiprocessing operations, default to False
:type disable_multiprocessing: Boolean, optional
""" """
'Save the true edges structure in tuples' 'Save the true edges structure in tuples'
true_edges = copy.deepcopy(self._sample_path.structure.edges) true_edges = copy.deepcopy(self._sample_path.structure.edges)
@ -160,16 +172,24 @@ class StructureScoreBasedEstimator(se.StructureEstimator):
optimizer:str = 'hill' ): optimizer:str = 'hill' ):
""" """
Use the FamScore of a node in order to find the best parent nodes Use the FamScore of a node in order to find the best parent nodes
Parameters:
node_id: current node's id :param node_id: current node's id
max_parents: maximum number of parents for each variable. If None, disabled :type node_id: string
iterations_number: maximum number of optimization algorithm's iteration :param max_parents: maximum number of parents for each variable. If None, disabled, default to None
patience: number of iteration without any improvement before to stop the search.If None, disabled :type max_parents: int, optional
tabu_length: maximum lenght of the data structures used in the optimization process :param iterations_number: maximum number of optimization algorithm's iteration, default to 40
tabu_rules_duration: number of iterations in which each rule keeps its value :type iterations_number: int, optional
optimzer: name of the optimizer algorithm. Possible values: 'hill' (Hill climbing),'tabu' (tabu search) :param patience: number of iteration without any improvement before to stop the search.If None, disabled, default to None
Returns: :type patience: int, optional
A list of the best edges for the currente node :param tabu_length: maximum lenght of the data structures used in the optimization process, default to None
:type tabu_length: int, optional
:param tabu_rules_duration: number of iterations in which each rule keeps its value, default to None
:type tabu_rules_duration: int, optional
:param optimizer: name of the optimizer algorithm. Possible values: 'hill' (Hill climbing),'tabu' (tabu search), defualt to 'tabu'
:type optimizer: string, optional
:return: A list of the best edges for the currente node
:rtype: List
""" """
"choose the optimizer algotithm" "choose the optimizer algotithm"
@ -195,14 +215,19 @@ class StructureScoreBasedEstimator(se.StructureEstimator):
def get_score_from_graph(self, def get_score_from_graph(self,
graph: ng.NetworkGraph,node_id:str): graph: ng.NetworkGraph,
node_id:str):
""" """
Use the FamScore of a node in order to find the best parent nodes Get the FamScore of a node
Parameters:
node_id: current node's id :param node_id: current node's id
graph: current graph to be computed :type node_id: string
Returns: :param graph: current graph to be computed
The FamSCore for this graph structure :type graph: class:'NetworkGraph'
:return: The FamSCore for this graph structure
:rtype: float
""" """
'inizialize the graph for a single node' 'inizialize the graph for a single node'

@ -22,7 +22,16 @@ import structure_graph.network_graph as ng
class ConstraintBasedOptimizer(Optimizer): class ConstraintBasedOptimizer(Optimizer):
""" """
Optimizer class that implement Hill Climbing Search Optimizer class that implement a CTPC Algorithm
:param node_id: current node's id
:type node_id: string
:param structure_estimator: a structure estimator object with the information about the net
:type structure_estimator: class:'StructureEstimator'
:param tot_vars_count: number of variables in the dataset
:type tot_vars_count: int
""" """
def __init__(self, def __init__(self,
@ -31,8 +40,7 @@ class ConstraintBasedOptimizer(Optimizer):
tot_vars_count:int tot_vars_count:int
): ):
""" """
Compute Optimization process for a structure_estimator Constructor
""" """
super().__init__(node_id, structure_estimator) super().__init__(node_id, structure_estimator)
self.tot_vars_count = tot_vars_count self.tot_vars_count = tot_vars_count
@ -41,13 +49,10 @@ class ConstraintBasedOptimizer(Optimizer):
def optimize_structure(self): def optimize_structure(self):
""" """
Compute Optimization process for a structure_estimator Compute Optimization process for a structure_estimator by using a CTPC Algorithm
Parameters:
Returns:
the estimated structure for the node
:return: the estimated structure for the node
:rtype: List
""" """
print("##################TESTING VAR################", self.node_id) print("##################TESTING VAR################", self.node_id)

@ -22,6 +22,20 @@ class HillClimbing(Optimizer):
""" """
Optimizer class that implement Hill Climbing Search Optimizer class that implement Hill Climbing Search
:param node_id: current node's id
:type node_id: string
:param structure_estimator: a structure estimator object with the information about the net
:type structure_estimator: class:'StructureEstimator'
:param max_parents: maximum number of parents for each variable. If None, disabled, default to None
:type max_parents: int, optional
:param iterations_number: maximum number of optimization algorithm's iteration, default to 40
:type iterations_number: int, optional
:param patience: number of iteration without any improvement before to stop the search.If None, disabled, default to None
:type patience: int, optional
""" """
def __init__(self, def __init__(self,
node_id:str, node_id:str,
@ -31,16 +45,7 @@ class HillClimbing(Optimizer):
patience:int = None patience:int = None
): ):
""" """
Compute Optimization process for a structure_estimator Constructor
Parameters:
node_id: the node label
structure_estimator: a structure estimator object with the information about the net
max_parents: maximum number of parents for each variable. If None, disabled
iterations_number: maximum number of optimization algorithm's iteration
patience: number of iteration without any improvement before to stop the search.If None, disabled
""" """
super().__init__(node_id, structure_estimator) super().__init__(node_id, structure_estimator)
self.max_parents = max_parents self.max_parents = max_parents
@ -51,13 +56,10 @@ class HillClimbing(Optimizer):
def optimize_structure(self) -> typing.List: def optimize_structure(self) -> typing.List:
""" """
Compute Optimization process for a structure_estimator Compute Optimization process for a structure_estimator by using a Hill Climbing Algorithm
Parameters:
Returns:
the estimated structure for the node
:return: the estimated structure for the node
:rtype: List
""" """
#'Create the graph for the single node' #'Create the graph for the single node'

@ -17,6 +17,11 @@ from estimators import structure_estimator as se
class Optimizer(abc.ABC): class Optimizer(abc.ABC):
""" """
Interface class for all the optimizer's child classes Interface class for all the optimizer's child classes
:param node_id: the node label
:type node_id: string
:param structure_estimator: A structureEstimator Object to predict the structure
:type structure_estimator: class:'StructureEstimator'
""" """
@ -30,10 +35,7 @@ class Optimizer(abc.ABC):
""" """
Compute Optimization process for a structure_estimator Compute Optimization process for a structure_estimator
Parameters: :return: the estimated structure for the node
:rtype: List
Returns:
the estimated structure for the node
""" """
pass pass

@ -22,7 +22,24 @@ import queue
class TabuSearch(Optimizer): class TabuSearch(Optimizer):
""" """
Optimizer class that implement Hill Climbing Search Optimizer class that implement Tabu Search
:param node_id: current node's id
:type node_id: string
:param structure_estimator: a structure estimator object with the information about the net
:type structure_estimator: class:'StructureEstimator'
:param max_parents: maximum number of parents for each variable. If None, disabled, default to None
:type max_parents: int, optional
:param iterations_number: maximum number of optimization algorithm's iteration, default to 40
:type iterations_number: int, optional
:param patience: number of iteration without any improvement before to stop the search.If None, disabled, default to None
:type patience: int, optional
:param tabu_length: maximum lenght of the data structures used in the optimization process, default to None
:type tabu_length: int, optional
:param tabu_rules_duration: number of iterations in which each rule keeps its value, default to None
:type tabu_rules_duration: int, optional
""" """
def __init__(self, def __init__(self,
@ -35,17 +52,7 @@ class TabuSearch(Optimizer):
tabu_rules_duration = None tabu_rules_duration = None
): ):
""" """
Compute Optimization process for a structure_estimator Constructor
Parameters:
node_id: the node label
structure_estimator: a structure estimator object with the information about the net
max_parents: maximum number of parents for each variable. If None, disabled
iterations_number: maximum number of optimization algorithm's iteration
patience: number of iteration without any improvement before to stop the search.If None, disabled
tabu_length: maximum lenght of the data structures used in the optimization process
tabu_rules_duration: number of iterations in which each rule keeps its value
""" """
super().__init__(node_id, structure_estimator) super().__init__(node_id, structure_estimator)
self.max_parents = max_parents self.max_parents = max_parents
@ -57,13 +64,10 @@ class TabuSearch(Optimizer):
def optimize_structure(self) -> typing.List: def optimize_structure(self) -> typing.List:
""" """
Compute Optimization process for a structure_estimator Compute Optimization process for a structure_estimator by using a Hill Climbing Algorithm
Parameters:
Returns:
the estimated structure for the node
:return: the estimated structure for the node
:rtype: List
""" """
print(f"tabu search is processing the structure of {self.node_id}") print(f"tabu search is processing the structure of {self.node_id}")

@ -4,27 +4,25 @@ import sys
sys.path.append('../') sys.path.append('../')
class ConditionalIntensityMatrix: class ConditionalIntensityMatrix:
""" """Abstracts the Conditional Intesity matrix of a node as aggregation of the state residence times vector
Abstracts the Conditional Intesity matrix of a node as aggregation of the state residence times vector
and state transition matrix and the actual CIM matrix. and state transition matrix and the actual CIM matrix.
:_state_residence_times: state residence times vector :param state_residence_times: state residence times vector
:_state_transition_matrix: the transitions count matrix :type state_residence_times: numpy.array
:param state_transition_matrix: the transitions count matrix
:type state_transition_matrix: numpy.ndArray
:_cim: the actual cim of the node :_cim: the actual cim of the node
""" """
def __init__(self, state_residence_times: np.array, state_transition_matrix: np.array): def __init__(self, state_residence_times: np.array, state_transition_matrix: np.array):
"""Constructor Method
"""
self._state_residence_times = state_residence_times self._state_residence_times = state_residence_times
self._state_transition_matrix = state_transition_matrix self._state_transition_matrix = state_transition_matrix
self._cim = self.state_transition_matrix.astype(np.float64) self._cim = self.state_transition_matrix.astype(np.float64)
def compute_cim_coefficients(self): def compute_cim_coefficients(self):
""" """Compute the coefficients of the matrix _cim by using the following equality q_xx' = M[x, x'] / T[x].
Compute the coefficients of the matrix _cim by using the following equality q_xx' = M[x, x'] / T[x] The class member ``_cim`` will contain the computed cim
Parameters:
void
Returns:
void
""" """
np.fill_diagonal(self._cim, self._cim.diagonal() * -1) np.fill_diagonal(self._cim, self._cim.diagonal() * -1)
self._cim = ((self._cim.T + 1) / (self._state_residence_times + 1)).T self._cim = ((self._cim.T + 1) / (self._state_residence_times + 1)).T

@ -7,26 +7,29 @@ import structure_graph.set_of_cims as sofc
class Cache: class Cache:
""" """This class acts as a cache of ``SetOfCims`` objects for a node.
This class has the role of a cache for SetOfCIMS of a test node that have been already computed during the ctpc algorithm.
:list_of_sets_of_parents: a list of Sets of the parents to which the cim in cache at SAME index is related :_list_of_sets_of_parents: a list of ``Sets`` objects of the parents to which the cim in cache at SAME
:actual_cache: a list of setOfCims objects index is related
:_actual_cache: a list of setOfCims objects
""" """
def __init__(self): def __init__(self):
"""Constructor Method
"""
self.list_of_sets_of_parents = [] self.list_of_sets_of_parents = []
self.actual_cache = [] self.actual_cache = []
def find(self, parents_comb: typing.Set): #typing.Union[typing.Set, str] def find(self, parents_comb: typing.Set): #typing.Union[typing.Set, str]
""" """
Tries to find in cache given the symbolic parents combination parents_comb the SetOfCims related to that parents_comb. Tries to find in cache given the symbolic parents combination ``parents_comb`` the ``SetOfCims``
Parameters: related to that ``parents_comb``.
parents_comb: the parents related to that SetOfCims
Returns:
A SetOfCims object if the parents_comb index is found in list_of_sets_of_parents.
None otherwise.
:param parents_comb: the parents related to that ``SetOfCims``
:type parents_comb: Set
:return: A ``SetOfCims`` object if the ``parents_comb`` index is found in ``_list_of_sets_of_parents``.
None otherwise.
:rtype: SetOfCims
""" """
try: try:
#print("Cache State:", self.list_of_sets_of_indxs) #print("Cache State:", self.list_of_sets_of_indxs)
@ -38,28 +41,20 @@ class Cache:
return None return None
def put(self, parents_comb: typing.Union[typing.Set, str], socim: sofc.SetOfCims): def put(self, parents_comb: typing.Union[typing.Set, str], socim: sofc.SetOfCims):
""" """Place in cache the ``SetOfCims`` object, and the related symbolic index ``parents_comb`` in
Place in cache the SetOfCims object, and the related sybolyc index parents_comb in list_of_sets_of_parents ``_list_of_sets_of_parents``.
Parameters:
parents_comb: the symbolic set index
socim: the related SetOfCims object
Returns: :param parents_comb: the symbolic set index
void :type parents_comb: Set
:param socim: the related SetOfCims object
:type socim: SetOfCims
""" """
#print("Putting in cache:", parents_comb) #print("Putting in cache:", parents_comb)
self.list_of_sets_of_parents.append(parents_comb) self.list_of_sets_of_parents.append(parents_comb)
self.actual_cache.append(socim) self.actual_cache.append(socim)
def clear(self): def clear(self):
""" """Clear the contents both of ``_actual_cache`` and ``_list_of_sets_of_parents``.
Clear the contents of both caches.
Parameters:
void
Returns:
void
""" """
del self.list_of_sets_of_parents[:] del self.list_of_sets_of_parents[:]
del self.actual_cache[:] del self.actual_cache[:]