commit
e52d98b32e
@ -0,0 +1,3 @@ |
|||||||
|
[run] |
||||||
|
omit = |
||||||
|
*/tests/* |
Binary file not shown.
@ -0,0 +1,9 @@ |
|||||||
|
include MANIFEST.in |
||||||
|
include setup.py |
||||||
|
include README.rst |
||||||
|
prune PyCTBN/test_data |
||||||
|
prune PyCTBN/tests |
||||||
|
prune tests |
||||||
|
prune test_data |
||||||
|
prune *tests* |
||||||
|
prune *test* |
@ -1,8 +1,8 @@ |
|||||||
import PyCTBN.estimators |
import PyCTBN.PyCTBN.estimators |
||||||
from PyCTBN.estimators import * |
from PyCTBN.PyCTBN.estimators import * |
||||||
import PyCTBN.optimizers |
import PyCTBN.PyCTBN.optimizers |
||||||
from PyCTBN.optimizers import * |
from PyCTBN.PyCTBN.optimizers import * |
||||||
import PyCTBN.structure_graph |
import PyCTBN.PyCTBN.structure_graph |
||||||
from PyCTBN.structure_graph import * |
from PyCTBN.PyCTBN.structure_graph import * |
||||||
import PyCTBN.utility |
import PyCTBN.PyCTBN.utility |
||||||
from PyCTBN.utility import * |
from PyCTBN.PyCTBN.utility import * |
@ -0,0 +1,2 @@ |
|||||||
|
import PyCTBN.PyCTBN |
||||||
|
from PyCTBN.PyCTBN import * |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,118 @@ |
|||||||
|
|
||||||
|
import glob |
||||||
|
import math |
||||||
|
import os |
||||||
|
import unittest |
||||||
|
import json |
||||||
|
import networkx as nx |
||||||
|
import numpy as np |
||||||
|
import timeit |
||||||
|
|
||||||
|
from ...PyCTBN.utility.cache import Cache |
||||||
|
from ...PyCTBN.structure_graph.sample_path import SamplePath |
||||||
|
from ...PyCTBN.estimators.structure_constraint_based_estimator import StructureConstraintBasedEstimator |
||||||
|
from ...PyCTBN.utility.json_importer import JsonImporter |
||||||
|
|
||||||
|
|
||||||
|
class TestStructureEstimator(unittest.TestCase): |
||||||
|
|
||||||
|
@classmethod |
||||||
|
def setUpClass(cls): |
||||||
|
cls.read_files = glob.glob(os.path.join('./PyCTBN/test_data', "*.json")) |
||||||
|
cls.importer = JsonImporter('./PyCTBN/test_data/networks_and_trajectories_binary_data_01_3.json', 'samples', 'dyn.str', 'variables', 'Time', 'Name') |
||||||
|
cls.importer.import_data(0) |
||||||
|
cls.s1 = SamplePath(cls.importer) |
||||||
|
cls.s1.build_trajectories() |
||||||
|
cls.s1.build_structure() |
||||||
|
|
||||||
|
def test_init(self): |
||||||
|
exp_alfa = 0.1 |
||||||
|
chi_alfa = 0.1 |
||||||
|
se1 = StructureConstraintBasedEstimator(self.s1, exp_alfa, chi_alfa) |
||||||
|
self.assertEqual(self.s1, se1._sample_path) |
||||||
|
self.assertTrue(np.array_equal(se1._nodes, np.array(self.s1.structure.nodes_labels))) |
||||||
|
self.assertTrue(np.array_equal(se1._nodes_indxs, self.s1.structure.nodes_indexes)) |
||||||
|
self.assertTrue(np.array_equal(se1._nodes_vals, self.s1.structure.nodes_values)) |
||||||
|
self.assertEqual(se1._exp_test_sign, exp_alfa) |
||||||
|
self.assertEqual(se1._chi_test_alfa, chi_alfa) |
||||||
|
self.assertIsInstance(se1._complete_graph, nx.DiGraph) |
||||||
|
self.assertIsInstance(se1._cache, Cache) |
||||||
|
|
||||||
|
def test_build_complete_graph(self): |
||||||
|
exp_alfa = 0.1 |
||||||
|
chi_alfa = 0.1 |
||||||
|
nodes_numb = len(self.s1.structure.nodes_labels) |
||||||
|
se1 = StructureConstraintBasedEstimator(self.s1, exp_alfa, chi_alfa) |
||||||
|
cg = se1.build_complete_graph(self.s1.structure.nodes_labels) |
||||||
|
self.assertEqual(len(cg.edges), nodes_numb*(nodes_numb - 1)) |
||||||
|
for node in self.s1.structure.nodes_labels: |
||||||
|
no_self_loops = self.s1.structure.nodes_labels[:] |
||||||
|
no_self_loops.remove(node) |
||||||
|
for n2 in no_self_loops: |
||||||
|
self.assertIn((node, n2), cg.edges) |
||||||
|
#se1.save_plot_estimated_structure_graph() |
||||||
|
|
||||||
|
def test_build_removable_edges_matrix(self): |
||||||
|
exp_alfa = 0.1 |
||||||
|
chi_alfa = 0.1 |
||||||
|
known_edges = self.s1.structure.edges[0:2] |
||||||
|
se1 = StructureConstraintBasedEstimator(self.s1, exp_alfa, chi_alfa, known_edges) |
||||||
|
for edge in known_edges: |
||||||
|
i = self.s1.structure.get_node_indx(edge[0]) |
||||||
|
j = self.s1.structure.get_node_indx(edge[1]) |
||||||
|
self.assertFalse(se1._removable_edges_matrix[i][j]) |
||||||
|
|
||||||
|
def test_generate_possible_sub_sets_of_size(self): |
||||||
|
exp_alfa = 0.1 |
||||||
|
chi_alfa = 0.1 |
||||||
|
nodes_numb = len(self.s1.structure.nodes_labels) |
||||||
|
se1 = StructureConstraintBasedEstimator(self.s1, exp_alfa, chi_alfa) |
||||||
|
|
||||||
|
for node in self.s1.structure.nodes_labels: |
||||||
|
for b in range(nodes_numb): |
||||||
|
sets = StructureConstraintBasedEstimator.generate_possible_sub_sets_of_size(self.s1.structure.nodes_labels, b, node) |
||||||
|
sets2 = StructureConstraintBasedEstimator.generate_possible_sub_sets_of_size(self.s1.structure.nodes_labels, b, node) |
||||||
|
self.assertEqual(len(list(sets)), math.floor(math.factorial(nodes_numb - 1) / |
||||||
|
(math.factorial(b)*math.factorial(nodes_numb -1 - b)))) |
||||||
|
for sset in sets2: |
||||||
|
self.assertFalse(node in sset) |
||||||
|
|
||||||
|
def test_time(self): |
||||||
|
known_edges = [] |
||||||
|
se1 = StructureConstraintBasedEstimator(self.s1, 0.1, 0.1, known_edges,25) |
||||||
|
exec_time = timeit.timeit(se1.ctpc_algorithm, number=1) |
||||||
|
print("Execution Time: ", exec_time) |
||||||
|
for ed in self.s1.structure.edges: |
||||||
|
self.assertIn(tuple(ed), se1._complete_graph.edges) |
||||||
|
#print("Spurious Edges:", se1.spurious_edges()) |
||||||
|
#se1.save_plot_estimated_structure_graph() |
||||||
|
|
||||||
|
def test_save_results(self): |
||||||
|
se1 = StructureConstraintBasedEstimator(self.s1, 0.1, 0.1) |
||||||
|
se1.ctpc_algorithm() |
||||||
|
se1.save_results() |
||||||
|
name = self.s1._importer.file_path.rsplit('/', 1)[-1] |
||||||
|
name = name.split('.', 1)[0] |
||||||
|
name += '_' + str(self.s1._importer.dataset_id()) |
||||||
|
name += '.json' |
||||||
|
file_name = 'results_' + name |
||||||
|
with open(file_name) as f: |
||||||
|
js_graph = json.load(f) |
||||||
|
result_graph = nx.json_graph.node_link_graph(js_graph) |
||||||
|
self.assertFalse(nx.difference(se1._complete_graph, result_graph).edges) |
||||||
|
os.remove(file_name) |
||||||
|
|
||||||
|
def test_adjacency_matrix(self): |
||||||
|
se1 = StructureConstraintBasedEstimator(self.s1, 0.1, 0.1) |
||||||
|
se1.ctpc_algorithm() |
||||||
|
adj_matrix = nx.adj_matrix(se1._complete_graph).toarray().astype(bool) |
||||||
|
self.assertTrue(np.array_equal(adj_matrix, se1.adjacency_matrix())) |
||||||
|
|
||||||
|
def test_save_plot_estimated_graph(self): |
||||||
|
se1 = StructureConstraintBasedEstimator(self.s1, 0.1, 0.1) |
||||||
|
edges = se1.estimate_structure(disable_multiprocessing=True) |
||||||
|
se1.save_plot_estimated_structure_graph('./networks_and_trajectories_ternary_data_3.png') |
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__': |
||||||
|
unittest.main() |
@ -0,0 +1,125 @@ |
|||||||
|
PyCTBN |
||||||
|
====== |
||||||
|
|
||||||
|
A Continuous Time Bayesian Networks Library |
||||||
|
|
||||||
|
Installation/Usage |
||||||
|
******************* |
||||||
|
Download the release in .tar.gz or .whl format and simply use pip install to install it:: |
||||||
|
|
||||||
|
$ pip install PyCTBN-1.0.tar.gz |
||||||
|
|
||||||
|
Documentation |
||||||
|
************* |
||||||
|
Please refer to https://philipmartini.github.io/PyCTBN/ for the full project documentation. |
||||||
|
|
||||||
|
Implementing your own data importer |
||||||
|
*********************************** |
||||||
|
.. code-block:: python |
||||||
|
|
||||||
|
"""This example demonstrates the implementation of a simple data importer the extends the class abstract importer to import data in csv format. |
||||||
|
The net in exam has three ternary nodes and no prior net structure. |
||||||
|
""" |
||||||
|
|
||||||
|
from PyCTBN import AbstractImporter |
||||||
|
|
||||||
|
class CSVImporter(AbstractImporter): |
||||||
|
|
||||||
|
def __init__(self, file_path): |
||||||
|
self._df_samples_list = None |
||||||
|
super(CSVImporter, self).__init__(file_path) |
||||||
|
|
||||||
|
def import_data(self): |
||||||
|
self.read_csv_file() |
||||||
|
self._sorter = self.build_sorter(self._df_samples_list[0]) |
||||||
|
self.import_variables() |
||||||
|
self.compute_row_delta_in_all_samples_frames(self._df_samples_list) |
||||||
|
|
||||||
|
def read_csv_file(self): |
||||||
|
df = pd.read_csv(self._file_path) |
||||||
|
df.drop(df.columns[[0]], axis=1, inplace=True) |
||||||
|
self._df_samples_list = [df] |
||||||
|
|
||||||
|
def import_variables(self): |
||||||
|
values_list = [3 for var in self._sorter] |
||||||
|
# initialize dict of lists |
||||||
|
data = {'Name':self._sorter, 'Value':values_list} |
||||||
|
# Create the pandas DataFrame |
||||||
|
self._df_variables = pd.DataFrame(data) |
||||||
|
|
||||||
|
def build_sorter(self, sample_frame: pd.DataFrame) -> typing.List: |
||||||
|
return list(sample_frame.columns)[1:] |
||||||
|
|
||||||
|
def dataset_id(self) -> object: |
||||||
|
pass |
||||||
|
|
||||||
|
Parameters Estimation Example |
||||||
|
***************************** |
||||||
|
|
||||||
|
.. code-block:: python |
||||||
|
|
||||||
|
from PyCTBN import JsonImporter |
||||||
|
from PyCTBN import SamplePath |
||||||
|
from PyCTBN import NetworkGraph |
||||||
|
from PyCTBN import ParametersEstimator |
||||||
|
|
||||||
|
|
||||||
|
def main(): |
||||||
|
read_files = glob.glob(os.path.join('./data', "*.json")) #Take all json files in this dir |
||||||
|
#import data |
||||||
|
importer = JsonImporter(read_files[0], 'samples', 'dyn.str', 'variables', 'Time', 'Name') |
||||||
|
importer.import_data(0) |
||||||
|
#Create a SamplePath Obj passing an already filled AbstractImporter object |
||||||
|
s1 = SamplePath(importer) |
||||||
|
#Build The trajectries and the structural infos |
||||||
|
s1.build_trajectories() |
||||||
|
s1.build_structure() |
||||||
|
print(s1.structure.edges) |
||||||
|
print(s1.structure.nodes_values) |
||||||
|
#From The Structure Object build the Graph |
||||||
|
g = NetworkGraph(s1.structure) |
||||||
|
#Select a node you want to estimate the parameters |
||||||
|
node = g.nodes[2] |
||||||
|
print("Node", node) |
||||||
|
#Init the _graph specifically for THIS node |
||||||
|
g.fast_init(node) |
||||||
|
#Use SamplePath and Grpah to create a ParametersEstimator Object |
||||||
|
p1 = ParametersEstimator(s1.trajectories, g) |
||||||
|
#Init the peEst specifically for THIS node |
||||||
|
p1.fast_init(node) |
||||||
|
#Compute the parameters |
||||||
|
sofc1 = p1.compute_parameters_for_node(node) |
||||||
|
#The est CIMS are inside the resultant SetOfCIms Obj |
||||||
|
print(sofc1.actual_cims) |
||||||
|
|
||||||
|
Structure Estimation Example |
||||||
|
**************************** |
||||||
|
|
||||||
|
.. code-block:: python |
||||||
|
|
||||||
|
from PyCTBN import JsonImporter |
||||||
|
from PyCTBN import SamplePath |
||||||
|
from PyCTBN import StructureEstimator |
||||||
|
|
||||||
|
def structure_estimation_example(): |
||||||
|
|
||||||
|
# read the json files in ./data path |
||||||
|
read_files = glob.glob(os.path.join('./data', "*.json")) |
||||||
|
# initialize a JsonImporter object for the first file |
||||||
|
importer = JsonImporter(read_files[0], 'samples', 'dyn.str', 'variables', 'Time', 'Name') |
||||||
|
# import the data at index 0 of the outer json array |
||||||
|
importer.import_data(0) |
||||||
|
# construct a SamplePath Object passing a filled AbstractImporter |
||||||
|
s1 = SamplePath(importer) |
||||||
|
# build the trajectories |
||||||
|
s1.build_trajectories() |
||||||
|
# build the real structure |
||||||
|
s1.build_structure() |
||||||
|
# construct a StructureEstimator object |
||||||
|
se1 = StructureEstimator(s1, 0.1, 0.1) |
||||||
|
# call the ctpc algorithm |
||||||
|
se1.ctpc_algorithm() |
||||||
|
# the adjacency matrix of the estimated structure |
||||||
|
print(se1.adjacency_matrix()) |
||||||
|
# save results to a json file |
||||||
|
se1.save_results() |
@ -0,0 +1,41 @@ |
|||||||
|
import glob |
||||||
|
import os |
||||||
|
|
||||||
|
import sys |
||||||
|
sys.path.append("./PyCTBN/") |
||||||
|
|
||||||
|
import structure_graph.network_graph as ng |
||||||
|
import structure_graph.sample_path as sp |
||||||
|
import structure_graph.set_of_cims as sofc |
||||||
|
import estimators.parameters_estimator as pe |
||||||
|
import utility.json_importer as ji |
||||||
|
|
||||||
|
|
||||||
|
def main(): |
||||||
|
read_files = glob.glob(os.path.join('./data', "*.json")) #Take all json files in this dir |
||||||
|
#import data |
||||||
|
importer = ji.JsonImporter(read_files[0], 'samples', 'dyn.str', 'variables', 'Time', 'Name') |
||||||
|
#Create a SamplePath Obj |
||||||
|
s1 = sp.SamplePath(importer) |
||||||
|
#Build The trajectries and the structural infos |
||||||
|
s1.build_trajectories() |
||||||
|
s1.build_structure() |
||||||
|
#From The Structure Object build the Graph |
||||||
|
g = ng.NetworkGraph(s1.structure) |
||||||
|
#Select a node you want to estimate the parameters |
||||||
|
node = g.nodes[1] |
||||||
|
#Init the graph specifically for THIS node |
||||||
|
g.fast_init(node) |
||||||
|
#Use SamplePath and Grpah to create a ParametersEstimator Object |
||||||
|
p1 = pe.ParametersEstimator(s1, g) |
||||||
|
#Init the peEst specifically for THIS node |
||||||
|
p1.fast_init(node) |
||||||
|
#Compute the parameters |
||||||
|
sofc1 = p1.compute_parameters_for_node(node) |
||||||
|
#The est CIMS are inside the resultant SetOfCIms Obj |
||||||
|
print(sofc1.actual_cims) |
||||||
|
|
||||||
|
if __name__ == "__main__": |
||||||
|
main() |
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -1,35 +1,35 @@ |
|||||||
@ECHO OFF |
@ECHO OFF |
||||||
|
|
||||||
pushd %~dp0 |
pushd %~dp0 |
||||||
|
|
||||||
REM Command file for Sphinx documentation |
REM Command file for Sphinx documentation |
||||||
|
|
||||||
if "%SPHINXBUILD%" == "" ( |
if "%SPHINXBUILD%" == "" ( |
||||||
set SPHINXBUILD=sphinx-build |
set SPHINXBUILD=sphinx-build |
||||||
) |
) |
||||||
set SOURCEDIR=. |
set SOURCEDIR=. |
||||||
set BUILDDIR=_build |
set BUILDDIR=_build |
||||||
|
|
||||||
if "%1" == "" goto help |
if "%1" == "" goto help |
||||||
|
|
||||||
%SPHINXBUILD% >NUL 2>NUL |
%SPHINXBUILD% >NUL 2>NUL |
||||||
if errorlevel 9009 ( |
if errorlevel 9009 ( |
||||||
echo. |
echo. |
||||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx |
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx |
||||||
echo.installed, then set the SPHINXBUILD environment variable to point |
echo.installed, then set the SPHINXBUILD environment variable to point |
||||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you |
echo.to the full path of the 'sphinx-build' executable. Alternatively you |
||||||
echo.may add the Sphinx directory to PATH. |
echo.may add the Sphinx directory to PATH. |
||||||
echo. |
echo. |
||||||
echo.If you don't have Sphinx installed, grab it from |
echo.If you don't have Sphinx installed, grab it from |
||||||
echo.http://sphinx-doc.org/ |
echo.http://sphinx-doc.org/ |
||||||
exit /b 1 |
exit /b 1 |
||||||
) |
) |
||||||
|
|
||||||
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% |
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% |
||||||
goto end |
goto end |
||||||
|
|
||||||
:help |
:help |
||||||
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% |
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% |
||||||
|
|
||||||
:end |
:end |
||||||
popd |
popd |
||||||
|
@ -0,0 +1,22 @@ |
|||||||
|
from setuptools import setup, find_packages |
||||||
|
|
||||||
|
|
||||||
|
setup(name='PyCTBN', |
||||||
|
version='1.0', |
||||||
|
url='https://github.com/philipMartini/PyCTBN', |
||||||
|
license='MIT', |
||||||
|
author=['Alessandro Bregoli', 'Filippo Martini','Luca Moretti'], |
||||||
|
author_email=['a.bregoli1@campus.unimib.it', 'f.martini@campus.unimib.it','lucamoretti96@gmail.com'], |
||||||
|
description='A Continuous Time Bayesian Networks Library', |
||||||
|
packages=find_packages(exclude=['*test*','test_data','tests','PyCTBN.tests','PyCTBN.test_data']), |
||||||
|
exclude_package_data={'': ['*test*','test_data','tests','PyCTBN.tests','PyCTBN.test_data']}, |
||||||
|
#packages=['PyCTBN.PyCTBN'], |
||||||
|
install_requires=[ |
||||||
|
'numpy', 'pandas', 'networkx', 'scipy', 'matplotlib', 'tqdm'], |
||||||
|
dependency_links=['https://github.com/numpy/numpy', 'https://github.com/pandas-dev/pandas', |
||||||
|
'https://github.com/networkx/networkx', 'https://github.com/scipy/scipy', |
||||||
|
'https://github.com/tqdm/tqdm'], |
||||||
|
#long_description=open('../README.md').read(), |
||||||
|
zip_safe=False, |
||||||
|
include_package_data=True, |
||||||
|
python_requires='>=3.6') |
Reference in new issue