1
0
Fork 0
master
Pietro 3 years ago
parent e32b7c94bc
commit c546e9fcc6
  1. 1
      .gitignore
  2. 18
      PyCTBN/PyCTBN/structure_graph/network_generator.py
  3. 16
      PyCTBN/PyCTBN/structure_graph/trajectory_generator.py
  4. 2
      PyCTBN/PyCTBN/utility/abstract_exporter.py
  5. 6
      PyCTBN/PyCTBN/utility/json_importer.py
  6. 64
      example.py

1
.gitignore vendored

@ -14,3 +14,4 @@ test2.json
test3.json
result0.png
example.json
test_time.py

@ -4,8 +4,7 @@ from .conditional_intensity_matrix import ConditionalIntensityMatrix
from .set_of_cims import SetOfCims
import numpy as np
import pandas as pd
import os
import json
import random
class NetworkGenerator(object):
"""Provides the methods to generate a network graph and the CIMs related to it
@ -30,15 +29,28 @@ class NetworkGenerator(object):
self._graph = None
self._cims = None
def generate_graph(self, density):
def generate_graph(self, density, fixed: bool = False):
"""Generate the edges according to specified density, and then instantiate the NetworkGraph object
to represent the network
:param density: Probability of an edge between two nodes to exist
:type density: float
:param fixed: Specifies whether the required density is mandatory or it's just a probability
:type fixed: bool
"""
if fixed:
n_edges = density * len(self._labels) * (len(self._labels) - 1)
if not float.is_integer(n_edges):
raise RuntimeError("Invalid Density")
else:
n_edges = int(n_edges)
edges = [(i, j) for i in self._labels for j in self._labels if i != j]
random.shuffle(edges)
edges = edges[:n_edges]
else:
edges = [(i, j) for i in self._labels for j in self._labels if np.random.binomial(1, density) == 1 and i != j]
s = Structure(self._labels, self._indxs, self._vals, edges, len(self._labels))
self._graph = NetworkGraph(s)
self._graph.add_nodes(s.nodes_labels)

@ -25,7 +25,7 @@ class TrajectoryGenerator(object):
:type _generated_trajectory: pandas.DataFrame
"""
def __init__(self, importer: AbstractImporter = None, variables: list = None, dyn_str: list = None, dyn_cims: dict = None):
def __init__(self, importer: AbstractImporter = None, variables: pd.DataFrame = None, dyn_str: pd.DataFrame = None, dyn_cims: dict = None):
"""Constructor Method
It parses and elaborates the data fetched from importer (if defined, otherwise variables, dyn_str and dyn_cims are used)
in order to make the objects structure more suitable for the forthcoming trajectory generation
@ -43,7 +43,9 @@ class TrajectoryGenerator(object):
self._parents[v] = dyn_str.where(dyn_str["To"] == v).dropna()["From"].tolist()
self._cims = {}
sampled_cims = self._importer._raw_data[0]["dyn.cims"] if importer is not None else dyn_cims
if importer is not None:
sampled_cims = self._importer._cims
for v in sampled_cims.keys():
p_combs = []
v_cims = []
@ -59,6 +61,8 @@ class TrajectoryGenerator(object):
sof = SetOfCims(node_id = v, parents_states_number = [variables.where(variables["Name"] == p)["Value"] for p in self._parents[v]],
node_states_number = variables.where(variables["Name"] == v)["Value"], p_combs = np.array(p_combs), cims = v_cims)
self._cims[v] = sof
else:
self._cims = dyn_cims
def CTBN_Sample(self, t_end = -1, max_tr = -1):
"""This method implements the generation of a trajectory, basing on the network structure and
@ -97,7 +101,6 @@ class TrajectoryGenerator(object):
time[i] = t + random.exponential(scale = param)
# next = index of the variable that will transition first
next = time.argmin()
t = time[next]
@ -174,10 +177,3 @@ class TrajectoryGenerator(object):
p.join()
return trajectories
def to_json(self):
"""Convert the last generated trajectory from pandas.DataFrame object type to JSON format
(suitable to do input/output of the trajectory with file)
"""
return json.loads(self._generated_trajectory.to_json(orient="records"))

@ -4,7 +4,7 @@ import os
from abc import ABC, abstractmethod
class AbstractExporter(ABC):
"""Provides the methods to save in json format a network information
"""Abstract class that exposes the methods to save in json format a network information
along with one or more trajectories generated basing on it
:param _variables: Dataframe containing the nodes labels and cardinalities

@ -31,7 +31,7 @@ class JsonImporter(AbstractImporter):
"""
def __init__(self, file_path: str, samples_label: str, structure_label: str, variables_label: str, time_key: str,
variables_key: str):
variables_key: str, cims_label: str = None):
"""Constructor method
.. note::
@ -42,6 +42,7 @@ class JsonImporter(AbstractImporter):
self._samples_label = samples_label
self._structure_label = structure_label
self._variables_label = variables_label
self._cims_label = cims_label
self._time_key = time_key
self._variables_key = variables_key
self._df_samples_list = None
@ -63,6 +64,9 @@ class JsonImporter(AbstractImporter):
self._df_structure = self.import_structure(self._raw_data)
self._df_variables = self.import_variables(self._raw_data)
if self._cims_label != None:
self._cims = self._raw_data[indx][self._cims_label]
def import_trajectories(self, raw_data: typing.List) -> typing.List:
"""Imports the trajectories from the list of dicts ``raw_data``.

@ -6,40 +6,36 @@ 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
"""
if __name__ == "__main__":
trajectories = tg.multi_trajectory(t_ends = [100, 100, 100])
"""
def main():
# 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)
# 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
e1 = JsonExporter(ng.variables, ng.dyn_str, ng.cims)
tg = TrajectoryGenerator(variables = ng.variables, dyn_str = ng.dyn_str, dyn_cims = ng.cims)
sigma = tg.CTBN_Sample(max_tr = 30000)
e1.add_trajectory(sigma)
e1.out_file("example.json")
# Trajectory Generation
print(ng.dyn_str)
e1 = JsonExporter(ng.variables, ng.dyn_str, ng.cims)
tg = TrajectoryGenerator(variables = ng.variables, dyn_str = ng.dyn_str, dyn_cims = e1.cims_to_json())
sigma = tg.CTBN_Sample(max_tr = 30000)
e1.add_trajectory(sigma)
e1.out_file("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,
# Network Estimation (Constraint Based)
importer = JsonImporter(file_path = "example.json", samples_label = "samples",
structure_label = "dyn.str", variables_label = "variables",
cims_label = "dyn.cims", 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('./result1.png')
print(se1.adjacency_matrix())
print(edges)
edges = se1.estimate_structure(True)
if __name__ == "__main__":
main()