1
0
Fork 0

Full Execution Example

master
Pietro 4 years ago
parent 59de299053
commit c6a19ea86a
  1. 1
      .gitignore
  2. 62
      PyCTBN/PyCTBN/structure_graph/network_generator.py
  3. 2
      PyCTBN/PyCTBN/structure_graph/set_of_cims.py
  4. 23
      PyCTBN/PyCTBN/structure_graph/trajectory_generator.py
  5. 41
      example.py

1
.gitignore vendored

@ -13,3 +13,4 @@ test1.json
test2.json test2.json
test3.json test3.json
result0.png result0.png
example.json

@ -3,6 +3,8 @@ from .network_graph import NetworkGraph
from .conditional_intensity_matrix import ConditionalIntensityMatrix from .conditional_intensity_matrix import ConditionalIntensityMatrix
from .set_of_cims import SetOfCims from .set_of_cims import SetOfCims
import numpy as np import numpy as np
import os
import json
class NetworkGenerator(object): class NetworkGenerator(object):
"""Provides the methods to generate a network graph and the CIMs related to it """Provides the methods to generate a network graph and the CIMs related to it
@ -94,20 +96,30 @@ class NetworkGenerator(object):
row /= (sum(row) - row[i]) row /= (sum(row) - row[i])
row *= diag row *= diag
row[i] = -1 * diag row[i] = -1 * diag
cim[i] = row cim[i] = np.around(row, 4)
return cim return cim
def out_json(self, filename): @property
"""Create a file in current directory and write on it the generated network and the CIMs, def graph(self) -> NetworkGraph:
after having restructured the objects in order to respect the standard JSON file structure. return self._graph
:param filename: Name of the output file (it must include json extension) @property
:type filename: string def cims(self) -> NetworkGraph:
""" return self._cims
dyn_str = [{"From": edge[0], "To": edge[1]} for edge in self._graph.edges] @property
variables = [{"Name": l, "Value": self._vals[i]} for i, l in enumerate(self._labels)] def dyn_str(self) -> list:
return [{"From": edge[0], "To": edge[1]} for edge in self._graph.edges]
@property
def variables(self) -> list:
return [{"Name": l, "Value": self._vals[i]} for i, l in enumerate(self._labels)]
"""Restructure the CIMs object in order to fit the standard JSON file structure
"""
@property
def dyn_cims(self) -> dict:
dyn_cims = {} dyn_cims = {}
for i, l in enumerate(self._labels): for i, l in enumerate(self._labels):
@ -115,10 +127,13 @@ class NetworkGenerator(object):
parents = self._graph.get_ordered_by_indx_set_of_parents(l)[0] parents = self._graph.get_ordered_by_indx_set_of_parents(l)[0]
for j, comb in enumerate(self._cims[l].p_combs): for j, comb in enumerate(self._cims[l].p_combs):
comb_key = "" comb_key = ""
for k, val in enumerate(comb): if len(parents) != 0:
comb_key += parents[k] + "=" + str(val) for k, val in enumerate(comb):
if k < len(comb) - 1: comb_key += parents[k] + "=" + str(val)
comb_key += "," if k < len(comb) - 1:
comb_key += ","
else:
comb_key = l
cim = self._cims[l].filter_cims_with_mask(np.array([True for p in parents]), comb) cim = self._cims[l].filter_cims_with_mask(np.array([True for p in parents]), comb)
if len(parents) == 1: if len(parents) == 1:
@ -126,25 +141,8 @@ class NetworkGenerator(object):
elif len(parents) == 0: elif len(parents) == 0:
cim = cim[0].cim cim = cim[0].cim
else: else:
cim = cim.cim cim = cim[0].cim
dyn_cims[l][comb_key] = [dict([(str(i), val) for i, val in enumerate(row)]) for row in cim] dyn_cims[l][comb_key] = [dict([(str(i), val) for i, val in enumerate(row)]) for row in cim]
data = { return dyn_cims
"dyn.str": dyn_str,
"variables": variables,
"dyn.cims": dyn_cims,
"samples": []
}
path = os.getcwd()
with open(path + "/" + filename, "w") as json_file:
json.dump(data, json_file)
@property
def graph(self) -> NetworkGraph:
return self._graph
@property
def cims(self) -> NetworkGraph:
return self._cims

@ -84,7 +84,7 @@ class SetOfCims(object):
return self._actual_cims return self._actual_cims
else: else:
flat_indxs = np.argwhere(np.all(self._p_combs[:, mask_arr] == comb, axis=1)).ravel() flat_indxs = np.argwhere(np.all(self._p_combs[:, mask_arr] == comb, axis=1)).ravel()
return self._actual_cims[flat_indxs] return np.array(self._actual_cims)[flat_indxs.astype(int)]
@property @property
def actual_cims(self) -> np.ndarray: def actual_cims(self) -> np.ndarray:

@ -24,22 +24,25 @@ class TrajectoryGenerator(object):
:type _generated_trajectory: pandas.DataFrame :type _generated_trajectory: pandas.DataFrame
""" """
def __init__(self, importer: AbstractImporter): def __init__(self, importer: AbstractImporter = None, variables: list = None, dyn_str: list = None, dyn_cims: dict = None):
"""Constructor Method """Constructor Method
It parses and elaborates the data fetched from importer in order to make the objects structure It parses and elaborates the data fetched from importer in order to make the objects structure
more suitable for the forthcoming trajectory generation more suitable for the forthcoming trajectory generation
""" """
self._importer = importer self._importer = importer
self._vnames = self._importer._df_variables.iloc[:, 0].to_list() self._vnames = self._importer._df_variables.iloc[:, 0].to_list() if importer is not None else [v["Name"] for v in variables]
self._parents = {} self._parents = {}
for v in self._vnames: for v in self._vnames:
self._parents[v] = self._importer._df_structure.where(self._importer._df_structure["To"] == v).dropna()["From"].tolist() if importer is not None:
self._parents[v] = self._importer._df_structure.where(self._importer._df_structure["To"] == v).dropna()["From"].tolist()
else:
self._parents[v] = [edge["From"] for edge in dyn_str if edge["To"] == v]
self._cims = {} self._cims = {}
sampled_cims = self._importer._raw_data[0]["dyn.cims"] sampled_cims = self._importer._raw_data[0]["dyn.cims"] if importer is not None else dyn_cims
for v in sampled_cims.keys(): for v in sampled_cims.keys():
p_combs = [] p_combs = []
v_cims = [] v_cims = []
@ -47,9 +50,13 @@ class TrajectoryGenerator(object):
p_combs.append(np.array(re.findall(r"=(\d)", comb)).astype("int")) p_combs.append(np.array(re.findall(r"=(\d)", comb)).astype("int"))
cim = pd.DataFrame(sampled_cims[v][comb]).to_numpy() cim = pd.DataFrame(sampled_cims[v][comb]).to_numpy()
v_cims.append(ConditionalIntensityMatrix(cim = cim)) v_cims.append(ConditionalIntensityMatrix(cim = cim))
sof = SetOfCims(node_id = v, parents_states_number = [self._importer._df_variables.where(self._importer._df_variables["Name"] == p)["Value"] for p in self._parents[v]], if importer is not None:
node_states_number = self._importer._df_variables.where(self._importer._df_variables["Name"] == v)["Value"], p_combs = p_combs, cims = v_cims) sof = SetOfCims(node_id = v, parents_states_number = [self._importer._df_variables.where(self._importer._df_variables["Name"] == p)["Value"] for p in self._parents[v]],
node_states_number = self._importer._df_variables.where(self._importer._df_variables["Name"] == v)["Value"], p_combs = np.array(p_combs), cims = v_cims)
else:
sof = SetOfCims(node_id = v, parents_states_number = [[variable["Value"] for variable in variables if variable["Name"] == p][0] for p in self._parents[v]],
node_states_number = [variable for variable in variables if variable["Name"] == v][0]["Value"], p_combs = np.array(p_combs), cims = v_cims)
self._cims[v] = sof self._cims[v] = sof
def CTBN_Sample(self, t_end = -1, max_tr = -1): def CTBN_Sample(self, t_end = -1, max_tr = -1):

@ -0,0 +1,41 @@
from PyCTBN.PyCTBN.structure_graph.trajectory_generator import TrajectoryGenerator
from PyCTBN.PyCTBN.structure_graph.network_generator import NetworkGenerator
from PyCTBN.PyCTBN.utility.json_importer import JsonImporter
from PyCTBN.PyCTBN.utility.json_exporter import JsonExporter
from PyCTBN.PyCTBN.structure_graph.structure import Structure
from PyCTBN.PyCTBN.structure_graph.sample_path import SamplePath
from PyCTBN.PyCTBN.estimators.structure_constraint_based_estimator import StructureConstraintBasedEstimator
# Network Generation
labels = ["X", "Y", "Z"]
card = 3
vals = [card for l in labels]
cim_min = 1
cim_max = 3
ng = NetworkGenerator(labels, vals)
ng.generate_graph(0.3)
ng.generate_cims(cim_min, cim_max)
# Trajectory Generation
print(ng.dyn_str)
e1 = JsonExporter(ng.variables, ng.dyn_str, ng.dyn_cims)
tg = TrajectoryGenerator(variables = ng.variables, dyn_str = ng.dyn_str, dyn_cims = ng.dyn_cims)
sigma = tg.CTBN_Sample(max_tr = 10)
e1.add_trajectory(tg.to_json())
e1.out_json("example.json")
# Network Estimation (Constraint Based)
importer = JsonImporter(file_path="example.json", samples_label='samples',
structure_label='dyn.str', variables_label='variables',
time_key='Time', variables_key='Name')
importer.import_data(0)
s1 = SamplePath(importer=importer)
s1.build_trajectories()
s1.build_structure()
se1 = StructureConstraintBasedEstimator(sample_path=s1, exp_test_alfa=0.1, chi_test_alfa=0.1,
known_edges=[], thumb_threshold=25)
edges = se1.estimate_structure(True)
se1.save_plot_estimated_structure_graph('./result.png')
print(se1.adjacency_matrix())
print(edges)