├── .gitignore ├── LICENSE.txt ├── MANIFEST.in ├── README.md ├── README.txt ├── build ├── lib.linux-x86_64-2.7 │ ├── libpgm │ │ ├── CPDtypes │ │ │ ├── __init__.py │ │ │ ├── crazy.py │ │ │ ├── discrete.py │ │ │ ├── lg.py │ │ │ └── lgandd.py │ │ ├── __init__.py │ │ ├── dictionary.py │ │ ├── discretebayesiannetwork.py │ │ ├── dyndiscbayesiannetwork.py │ │ ├── graphskeleton.py │ │ ├── hybayesiannetwork.py │ │ ├── lgbayesiannetwork.py │ │ ├── nodedata.py │ │ ├── orderedskeleton.py │ │ ├── pgmlearner.py │ │ ├── sampleaggregator.py │ │ ├── tablecpdfactor.py │ │ └── tablecpdfactorization.py │ └── utils │ │ ├── __init__.py │ │ ├── bntextutils.py │ │ └── libpgmexceptions.py └── lib │ ├── libpgm │ ├── CPDtypes │ │ ├── __init__.py │ │ ├── crazy.py │ │ ├── discrete.py │ │ ├── lg.py │ │ └── lgandd.py │ ├── __init__.py │ ├── dictionary.py │ ├── discretebayesiannetwork.py │ ├── dyndiscbayesiannetwork.py │ ├── graphskeleton.py │ ├── hybayesiannetwork.py │ ├── lgbayesiannetwork.py │ ├── nodedata.py │ ├── orderedskeleton.py │ ├── pgmlearner.py │ ├── sampleaggregator.py │ ├── tablecpdfactor.py │ └── tablecpdfactorization.py │ └── utils │ ├── __init__.py │ ├── bntextutils.py │ └── libpgmexceptions.py ├── docs ├── CPDtypes.rst ├── Makefile ├── _build │ ├── doctrees │ │ ├── CPDtypes.doctree │ │ ├── dictionary.doctree │ │ ├── discretebayesiannetwork.doctree │ │ ├── dyndiscbayesiannetwork.doctree │ │ ├── environment.pickle │ │ ├── graphskeleton.doctree │ │ ├── hybayesiannetwork.doctree │ │ ├── index.doctree │ │ ├── lgbayesiannetwork.doctree │ │ ├── nodedata.doctree │ │ ├── orderedskeleton.doctree │ │ ├── pgmlearner.doctree │ │ ├── pgmlibrary.doctree │ │ ├── sampleaggregator.doctree │ │ ├── tablecpdfactor.doctree │ │ ├── tablecpdfactorization.doctree │ │ ├── test.doctree │ │ ├── unittestdict.doctree │ │ ├── unittestdyndict.doctree │ │ ├── unittesthdict.doctree │ │ └── unittestlgdict.doctree │ └── html │ │ ├── .buildinfo │ │ ├── CPDtypes.html │ │ ├── _modules │ │ ├── index.html │ │ └── libpgm │ │ │ ├── CPDtypes │ │ │ ├── crazy.html │ │ │ ├── discrete.html │ │ │ ├── lg.html │ │ │ └── lgandd.html │ │ │ ├── dictionary.html │ │ │ ├── discretebayesiannetwork.html │ │ │ ├── dyndiscbayesiannetwork.html │ │ │ ├── graphskeleton.html │ │ │ ├── hybayesiannetwork.html │ │ │ ├── lgbayesiannetwork.html │ │ │ ├── nodedata.html │ │ │ ├── orderedskeleton.html │ │ │ ├── pgmlearner.html │ │ │ ├── sampleaggregator.html │ │ │ ├── tablecpdfactor.html │ │ │ └── tablecpdfactorization.html │ │ ├── _sources │ │ ├── CPDtypes.txt │ │ ├── dictionary.txt │ │ ├── discretebayesiannetwork.txt │ │ ├── dyndiscbayesiannetwork.txt │ │ ├── graphskeleton.txt │ │ ├── hybayesiannetwork.txt │ │ ├── index.txt │ │ ├── lgbayesiannetwork.txt │ │ ├── nodedata.txt │ │ ├── orderedskeleton.txt │ │ ├── pgmlearner.txt │ │ ├── sampleaggregator.txt │ │ ├── tablecpdfactor.txt │ │ ├── tablecpdfactorization.txt │ │ ├── test.txt │ │ ├── unittestdict.txt │ │ ├── unittestdyndict.txt │ │ ├── unittesthdict.txt │ │ └── unittestlgdict.txt │ │ ├── _static │ │ ├── ajax-loader.gif │ │ ├── basic.css │ │ ├── comment-bright.png │ │ ├── comment-close.png │ │ ├── comment.png │ │ ├── default.css │ │ ├── doctools.js │ │ ├── down-pressed.png │ │ ├── down.png │ │ ├── file.png │ │ ├── jquery.js │ │ ├── minus.png │ │ ├── plus.png │ │ ├── pygments.css │ │ ├── searchtools.js │ │ ├── sidebar.js │ │ ├── underscore.js │ │ ├── up-pressed.png │ │ ├── up.png │ │ └── websupport.js │ │ ├── dictionary.html │ │ ├── discretebayesiannetwork.html │ │ ├── dyndiscbayesiannetwork.html │ │ ├── genindex.html │ │ ├── graphskeleton.html │ │ ├── hybayesiannetwork.html │ │ ├── index.html │ │ ├── lgbayesiannetwork.html │ │ ├── nodedata.html │ │ ├── objects.inv │ │ ├── orderedskeleton.html │ │ ├── pgmlearner.html │ │ ├── pgmlibrary.html │ │ ├── py-modindex.html │ │ ├── sampleaggregator.html │ │ ├── search.html │ │ ├── searchindex.js │ │ ├── tablecpdfactor.html │ │ ├── tablecpdfactorization.html │ │ ├── unittestdict.html │ │ ├── unittestdyndict.html │ │ ├── unittesthdict.html │ │ └── unittestlgdict.html ├── conf.py ├── dictionary.rst ├── discretebayesiannetwork.rst ├── dyndiscbayesiannetwork.rst ├── graphskeleton.rst ├── hybayesiannetwork.rst ├── index.rst ├── lgbayesiannetwork.rst ├── nodedata.rst ├── orderedskeleton.rst ├── pgmlearner.rst ├── sampleaggregator.rst ├── tablecpdfactor.rst ├── tablecpdfactorization.rst ├── unittestdict.rst ├── unittestdyndict.rst ├── unittesthdict.rst └── unittestlgdict.rst ├── examples ├── exampledata.txt ├── exampleevidence.txt ├── examplequery.txt └── examples.py ├── libpgm ├── CPDtypes │ ├── __init__.py │ ├── crazy.py │ ├── discrete.py │ ├── lg.py │ └── lgandd.py ├── __init__.py ├── dictionary.py ├── discretebayesiannetwork.py ├── dyndiscbayesiannetwork.py ├── graphskeleton.py ├── hybayesiannetwork.py ├── lgbayesiannetwork.py ├── nodedata.py ├── orderedskeleton.py ├── pgmlearner.py ├── sampleaggregator.py ├── tablecpdfactor.py └── tablecpdfactorization.py ├── libpgm_examples ├── discrete_bayesian_network.py └── discrete_bayesian_network.py~ ├── runtime-tests ├── archives │ ├── rtFnumvertices_processor.py │ └── rtFnumvertices_timer.py ├── bn_generator.py ├── disc_bn_x.txt ├── output.csv ├── processor.py ├── results │ ├── PGMlibrary2.0_Runtime_Report.pdf │ ├── PGMlibrary2.0_Runtime_Report.tex │ ├── dbn_learning_rtFindegree.csv │ ├── dbn_learning_rtFnumdatapoints.csv │ ├── dbn_learning_rtFnumoutcomes.csv │ ├── dbn_learning_rtFnumvertices.csv │ ├── dbn_learningparams_rtFindegree.csv │ ├── dbn_learningparams_rtFnumoutcomes.csv │ ├── dbn_paramlearning_rtFnumdatapoints.csv │ ├── dbn_paramlearning_rtFnumvertices.csv │ ├── dbn_querying_rtFindegree.csv │ ├── dbn_querying_rtFnumoutcomes.csv │ ├── dbn_querying_rtFnumvertices.csv │ ├── dbn_querying_rtFnumvertices2.csv │ ├── dbn_sampling_memFindegree.csv │ ├── dbn_sampling_memFnumoutcomes.csv │ └── dbn_sampling_rtFnumvertices.csv └── timer.py ├── setup.py ├── tests ├── run_unit_tests.py ├── unittestdict.txt ├── unittestdyndict.txt ├── unittesthdict.txt ├── unittesthdict_lgandd_no_lg_parents.txt └── unittestlgdict.txt └── utils ├── __init__.py ├── bntextutils.py └── libpgmexceptions.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | dist/ 3 | MANIFEST 4 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012, CyberPoint International, LLC 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of the CyberPoint International, LLC nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL CYBERPOINT INTERNATIONAL, LLC BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include *.txt 2 | recursive-include examples *.txt *.py 3 | recursive-include tests *.txt *.py 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | libpgm 2 | ====== 3 | 4 | A library for creating and using probabilistic graphical models 5 | Developed by James Ulrich and Charlie Cabot at 6 | Cyberpoint LLC (www.cyberpointllc.com). 7 | 8 | Copyright 2013 CyberPoint International LLC. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. (3) Neither the name of the CyberPoint International, LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 11 | 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CYBERPOINT INTERNATIONAL, LLC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | -------------------------------------------------------------------------------- /build/lib.linux-x86_64-2.7/libpgm/CPDtypes/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ['discrete', 'lg', 'lgandd', 'crazy'] 2 | -------------------------------------------------------------------------------- /build/lib.linux-x86_64-2.7/libpgm/CPDtypes/crazy.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, CyberPoint International, LLC 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the CyberPoint International, LLC nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL CYBERPOINT INTERNATIONAL, LLC BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | ''' 26 | This module contains tools for representing "crazy" nodes -- nodes where the method for sampling is to multiply the crazyinput by -10 or 10 and add :math:`\pi` -- as class instances with their own *choose* method to choose an outcome for themselves based on parent outcomes. 27 | 28 | The existence of this 'crazy' type is meant to indicate the true universality of 29 | the universal sampling method found in :doc:`hybayesiannetwork`. While no CPD would 30 | actually be this crazy, the libary has the setup to support any type of CPD. 31 | 32 | 33 | ''' 34 | import math 35 | import random 36 | 37 | class Crazy(): 38 | ''' 39 | This class represents a crazy node, as described above. It contains the *Vdataentry* attribute and the *choose* method. 40 | 41 | ''' 42 | def __init__(self, Vdataentry): 43 | ''' 44 | This class is constructed with the argument *Vdataentry* which must be a dict containing a dictionary entry for this particualr node. The dict must contain an entry of the following form:: 45 | 46 | "crazyinput": 47 | 48 | This ``"crazyinput"`` entry contains the number that will be used in the crazy sampling function. The *Vdataentry* attribute is set equal to this *Vdataentry* input upon instantiation. 49 | ''' 50 | self.Vdataentry = Vdataentry 51 | '''A dict containing CPD data for the node.''' 52 | 53 | def choose(self, pvalues): 54 | ''' 55 | Randomly choose state of node from probability distribution conditioned on *pvalues*. 56 | 57 | This method has two parts: (1) determining the proper probability 58 | distribution, and (2) using that probability distribution to determine 59 | an outcome. 60 | 61 | Arguments: 62 | 1. *pvalues* -- An array containing the assigned states of the node's parents. This must be in the same order as the parents appear in self.Vdataentry['parents']. 63 | 64 | The function takes the crazyinput, multiplies it by either 10 or -10 randomly, adds :math:`\\pi`, converts it to a string, and appends the word "bluberries!". It returns this value. 65 | 66 | ''' 67 | crazyinput = self.Vdataentry["crazyinput"] 68 | answer = "%.2f blueberries!" % (random.choice([10, -10]) * crazyinput + math.pi) 69 | return answer 70 | -------------------------------------------------------------------------------- /build/lib.linux-x86_64-2.7/libpgm/CPDtypes/discrete.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, CyberPoint International, LLC 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the CyberPoint International, LLC nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL CYBERPOINT INTERNATIONAL, LLC BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | ''' 26 | This module contains tools for representing discrete nodes -- those with a finite number of outcomes and a finite number of possible parent values -- as class instances with their own *choose* method to choose an outcome for themselves based on parent outcomes. 27 | 28 | ''' 29 | import random 30 | 31 | class Discrete(): 32 | ''' 33 | This class represents a discrete node, as described above. It contains the *Vdataentry* attribute and the *choose* method. 34 | 35 | ''' 36 | def __init__(self, Vdataentry): 37 | ''' 38 | This class is constructed with the argument *Vdataentry* which must be a dict containing a dictionary entry for this particular node. The dict must contain an entry of the following form:: 39 | 40 | "cprob": { 41 | "['',...,'']": [, ... , ], 42 | ... 43 | "['',...,'']": [, ... , ], 44 | } 45 | 46 | Where the keys are each possible combination of parent values and the values are the probability of each of the *n* possible node outcomes, given those parent outcomes. The *Vdataentry* attribute is set equal to this *Vdataentry* input upon instantiation. 47 | 48 | ''' 49 | self.Vdataentry = Vdataentry 50 | '''A dict containing CPD data for the node.''' 51 | 52 | def choose(self, pvalues): 53 | ''' 54 | Randomly choose state of node from a probability distribution conditioned on parent values *pvalues*. 55 | 56 | This method has two parts: (1) determining the proper probability 57 | distribution, and (2) using that probability distribution to determine 58 | an outcome. 59 | 60 | Arguments: 61 | 1. *pvalues* -- An array containing the assigned states of the node's parents. This must be in the same order as the parents appear in ``self.Vdataentry["parents"]``. 62 | The function goes to the proper entry in *Vdataentry*, as specified by *pvalues*, and samples the node based on the distribution found there. 63 | 64 | ''' 65 | 66 | 67 | p = self.Vdataentry["parents"] 68 | if (not p): 69 | distribution = self.Vdataentry["cprob"] 70 | else: 71 | pvalues = [str(outcome[t]) for t in self.Vdataentry["parents"]] # ideally can we pull this from the skeleton so as not to store parent data at all? 72 | for pvalue in pvalues: 73 | assert pvalue != 'default', "Graph skeleton was not topologically ordered." 74 | 75 | distribution = self.Vdataentry["cprob"][str(pvalues)] 76 | 77 | # choose 78 | rand = random.random() 79 | lbound = 0 80 | ubound = 0 81 | for interval in range(int(self.Vdataentry["numoutcomes"])): 82 | ubound += distribution[interval] 83 | if (lbound <= rand and rand < ubound): 84 | rindex = interval 85 | break 86 | else: 87 | lbound = ubound 88 | 89 | return str(self.Vdataentry["vals"][rindex]) 90 | -------------------------------------------------------------------------------- /build/lib.linux-x86_64-2.7/libpgm/CPDtypes/lg.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, CyberPoint International, LLC 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the CyberPoint International, LLC nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL CYBERPOINT INTERNATIONAL, LLC BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | ''' 26 | This module contains tools for representing linear Gaussian nodes -- those with a continuous linear Gaussian distribution of outcomes and a finite number of linear Gaussian parents -- as class instances with their own *choose* method to choose an outcome for themselves based on parent outcomes. 27 | 28 | ''' 29 | import random 30 | import math 31 | 32 | class Lg(): 33 | ''' 34 | This class represents a linear Gaussian node, as described above. It contains the *Vdataentry* attribute and the *choose* method. 35 | 36 | ''' 37 | def __init__(self, Vdataentry): 38 | ''' 39 | This class is constructed with the argument *Vdataentry* which must be a dict containing a dictionary entry for this particular node. The dict must contain entries of the following form:: 40 | 41 | "mean_base": , 43 | "mean_scal": , 46 | "variance": 47 | 48 | See :doc:`lgbayesiannetwork` for an explanation of linear Gaussian sampling. 49 | 50 | The *Vdataentry* attribute is set equal to this *Vdataentry* input upon instantiation. 51 | 52 | ''' 53 | self.Vdataentry = Vdataentry 54 | '''A dict containing CPD data for the node.''' 55 | 56 | def choose(self, pvalues): 57 | ''' 58 | Randomly choose state of node from probability distribution conditioned on *pvalues*. 59 | 60 | This method has two parts: (1) determining the proper probability 61 | distribution, and (2) using that probability distribution to determine 62 | an outcome. 63 | 64 | Arguments: 65 | 1. *pvalues* -- An array containing the assigned states of the node's parents. This must be in the same order as the parents appear in ``self.Vdataentry['parents']``. 66 | 67 | The function creates a Gaussian distribution in the manner described in :doc:`lgbayesiannetwork`, and samples from that distribution, returning its outcome. 68 | 69 | ''' 70 | 71 | 72 | # calculate Bayesian parameters (mean and variance) 73 | mean = self.Vdataentry["mean_base"] 74 | if (self.Vdataentry["parents"] != None): 75 | for x in range(len(self.Vdataentry["parents"])): 76 | if (pvalues[x] != "default"): 77 | mean += pvalues[x] * self.Vdataentry["mean_scal"][x] 78 | else: 79 | print "Attempted to sample node with unassigned parents." 80 | 81 | variance = self.Vdataentry["variance"] 82 | 83 | # draw random outcome from Gaussian 84 | # note that this built in function takes the standard deviation, not the 85 | # variance, thus requiring a square root 86 | return random.gauss(mean, math.sqrt(variance)) 87 | -------------------------------------------------------------------------------- /build/lib.linux-x86_64-2.7/libpgm/CPDtypes/lgandd.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, CyberPoint International, LLC 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the CyberPoint International, LLC nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL CYBERPOINT INTERNATIONAL, LLC BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | ''' 26 | This module contains tools for representing "LG + D" (linear Gaussian and discrete) nodes -- those with a Gaussian distribution, zero or more Gaussian parents, and one or more discrete parents -- as class instances with their own *choose* method to choose an outcome for themselves based on parent outcomes. 27 | 28 | ''' 29 | import random 30 | import math 31 | 32 | class Lgandd(): 33 | ''' 34 | This class represents a LG + D node, as described above. It contains the *Vdataentry* attribute and the *choose* method 35 | 36 | ''' 37 | def __init__(self, Vdataentry): 38 | ''' 39 | This class is constructed with the argument *Vdataentry* which must be a dict containing a dictionary entry for this particular node. The dict must contain an entry of the following form:: 40 | 41 | "cprob": { 42 | "['',...,'']": { 43 | "mean_base": , 45 | "mean_scal": , 48 | "variance": 49 | } 50 | ... 51 | "['',...,'']": { 52 | "mean_base": , 54 | "mean_scal": , 57 | "variance": 58 | } 59 | } 60 | 61 | This ``"cprob"`` entry contains a linear Gaussian distribution (conditioned on the Gaussian parents) for each combination of discrete parents. The *Vdataentry* attribute is set equal to this *Vdataentry* input upon instantiation. 62 | 63 | ''' 64 | self.Vdataentry = Vdataentry 65 | '''A dict containing CPD data for the node.''' 66 | 67 | def choose(self, pvalues): 68 | ''' 69 | Randomly choose state of node from probability distribution conditioned on *pvalues*. 70 | 71 | This method has two parts: (1) determining the proper probability 72 | distribution, and (2) using that probability distribution to determine 73 | an outcome. 74 | 75 | Arguments: 76 | 1. *pvalues* -- An array containing the assigned states of the node's parents. This must be in the same order as the parents appear in ``self.Vdataentry['parents']``. 77 | 78 | The function goes to the entry of ``"cprob"`` that matches the outcomes of its discrete parents. Then, it constructs a Gaussian distribution based on its Gaussian parents and the parameters found at that entry. Last, it samples from that distribution and returns its outcome. 79 | 80 | ''' 81 | 82 | 83 | # split parents by type 84 | dispvals = [] 85 | lgpvals = [] 86 | for pval in pvalues: 87 | if (isinstance(pval, str)): 88 | dispvals.append(pval) 89 | else: 90 | lgpvals.append(pval) 91 | 92 | 93 | # Check that we have at least one discrete parent. 94 | if not dispvals: 95 | print "Did not find any discrete parent. Consider using an Lg node." 96 | 97 | # find correct Gaussian 98 | lgdistribution = self.Vdataentry["hybcprob"][str(dispvals)] 99 | 100 | # calculate Bayesian parameters (mean and variance) 101 | mean = lgdistribution["mean_base"] 102 | if (self.Vdataentry["parents"] != None): 103 | for x in range(len(lgpvals)): 104 | if (lgpvals[x] != "default"): 105 | mean += lgpvals[x] * lgdistribution["mean_scal"][x] 106 | else: 107 | 108 | # temporary error check 109 | print "Attempted to sample node with unassigned parents." 110 | 111 | variance = lgdistribution["variance"] 112 | 113 | # draw random outcome from Gaussian (I love python) 114 | return random.gauss(mean, math.sqrt(variance)) 115 | -------------------------------------------------------------------------------- /build/lib.linux-x86_64-2.7/libpgm/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ['CPDtypes', 'dictionary', 'discretebayesiannetwork', 'graphskeleton', 'hybayesiannetwork', 'lgbayesiannetwork', 'nodedata', 'orderedskeleton', 'pgmlearner', 'sampleaggregator', 'tablecpdfactor', 'tablecpdfactorization'] 2 | -------------------------------------------------------------------------------- /build/lib.linux-x86_64-2.7/libpgm/dictionary.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, CyberPoint International, LLC 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the CyberPoint International, LLC nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL CYBERPOINT INTERNATIONAL, LLC BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | ''' 26 | Nearly all of the functions of this library require key indexing, which means it deals with dictionaries internally. This module deals with loading dictionaries and handles automatically converting from python-style dictionaries to condensed (no excess white space) JSON-style dictionaries. 27 | 28 | ''' 29 | import sys 30 | import json 31 | import string 32 | 33 | class Dictionary(object): 34 | ''' 35 | This class represents a JSON-style, key-indexable dictionary of data. It contains the attribute *alldata* and the method *dictload*. 36 | ''' 37 | 38 | def __init__(self): 39 | self.alldata = None 40 | '''An internal representation of a key-indexable dictionary.''' 41 | 42 | def dictload(self, path): 43 | ''' 44 | Load a dictionary from a JSON-like text in a text file located at *path* into the attribute *alldata*. 45 | 46 | In order for this function to execute successfully, the text file must have the proper formatting, particularly with regard to quotation marks. See :doc:`unittestdict` for an example. Specifically, the function can get rid of excess whitespace, convert ``.x`` to ``0.x`` in decimals, and convert ``None`` to ``null``, but nothing else. 47 | 48 | Arguments: 49 | 50 | 1. *path* -- Path to the text file (e.g. "mydictionary.txt") 51 | 52 | Attributes modified: 53 | 54 | 1. *alldata* -- The entire loaded dictionary. 55 | 56 | The function also returns an error if nothing was loaded into *alldata*. 57 | 58 | ''' 59 | f = open(path, 'r') 60 | ftext = f.read() 61 | assert (ftext and isinstance(ftext, str)), "Input file is empty or could not be read." 62 | 63 | 64 | # alter for json input, if necessary 65 | loaded = False 66 | try: 67 | self.alldata = json.loads(ftext) 68 | loaded = True 69 | except ValueError: 70 | pass 71 | 72 | if not loaded: 73 | try: 74 | ftext = ftext.translate(None, '\t\n ') 75 | ftext = ftext.replace(':', ': ') 76 | ftext = ftext.replace(',', ', ') 77 | ftext = ftext.replace('None', 'null') 78 | ftext = ftext.replace('.', '0.') 79 | self.alldata = json.loads(ftext) 80 | except ValueError: 81 | raise ValueError, "Convert to JSON from input file failed. Check formatting." 82 | f.close() 83 | 84 | assert isinstance(self.alldata, dict), "In method dictload, path did not direct to a proper text file." 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /build/lib.linux-x86_64-2.7/libpgm/orderedskeleton.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, CyberPoint International, LLC 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the CyberPoint International, LLC nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL CYBERPOINT INTERNATIONAL, LLC BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | ''' 26 | This module facilitates the process of creating ordered graph skeletons by topologically ordering them automatically. 27 | 28 | ''' 29 | 30 | from graphskeleton import GraphSkeleton 31 | 32 | class OrderedSkeleton(GraphSkeleton): 33 | ''' 34 | This class represents a graph skeleton (see :doc:`graphskeleton`) that is always topologically ordered. 35 | 36 | ''' 37 | 38 | def __init__(self, graphskeleton=None): 39 | self.V = None 40 | '''A list of names of vertices''' 41 | self.E = None 42 | '''A list of [origin, destination] pairs of verties that constitute edges.''' 43 | 44 | def load(self, path): 45 | '''Loads a dictionary from a file located at *path* in the same manner as :doc:`graphskeleton`, but includes a step where it topologically orders the nodes.''' 46 | 47 | self.dictload(path) 48 | self.V = self.alldata["V"] 49 | self.E = self.alldata["E"] 50 | 51 | # topologically order 52 | self.toporder() 53 | 54 | # free unused memory 55 | del self.alldata 56 | -------------------------------------------------------------------------------- /build/lib.linux-x86_64-2.7/libpgm/sampleaggregator.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, CyberPoint International, LLC 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the CyberPoint International, LLC nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL CYBERPOINT INTERNATIONAL, LLC BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | ''' 26 | This module provides tools for collecting and managing sets of samples generated by the library's sampling functions. By averaging a series of samples, the progam can approximate a joint probability distribution without having to do the exact calculations, which may be useful in large networks. 27 | 28 | ''' 29 | 30 | 31 | class SampleAggregator(object): 32 | ''' 33 | This class is a machine for aggregating data from sample sequences. It contains the method *aggregate*. 34 | 35 | ''' 36 | def __init__(self): 37 | self.seq = None 38 | '''The sequence inputted.''' 39 | self.avg = None 40 | '''The average of all the entries in *seq*, represented as a dict where each vertex has an entry whose value is a dict of {key, value} pairs, where each key is a possible outcome of that vertex and its value is the approximate frequency.''' 41 | 42 | 43 | def aggregate(self, samplerstatement): 44 | ''' 45 | Generate a sequence of samples using *samplerstatement* and return the average of its results. 46 | 47 | Arguments: 48 | 1. *samplerstatement* -- The statement of a function (with inputs) that would output a sequence of samples. For example: ``bn.randomsample(50)`` where ``bn`` is an instance of the :doc:`DiscreteBayesianNetwork ` class. 49 | 50 | This function stores the output of *samplerstatement* in the attribute *seq*, and then averages *seq* and stores the approximate distribution found in the attribute *avg*. It then returns *avg*. 51 | 52 | Usage example: this would print the average of 10 data points:: 53 | 54 | import json 55 | 56 | from libpgm.nodedata import NodeData 57 | from libpgm.graphskeleton import GraphSkeleton 58 | from libpgm.discretebayesiannetwork import DiscreteBayesianNetwork 59 | from libpgm.sampleaggregator import SampleAggregator 60 | 61 | # load nodedata and graphskeleton 62 | nd = NodeData() 63 | skel = GraphSkeleton() 64 | nd.load("../tests/unittestdict.txt") 65 | skel.load("../tests/unittestdict.txt") 66 | 67 | # topologically order graphskeleton 68 | skel.toporder() 69 | 70 | # load bayesian network 71 | bn = DiscreteBayesianNetwork(skel, nd) 72 | 73 | # build aggregator 74 | agg = SampleAggregator() 75 | 76 | # average samples 77 | result = agg.aggregate(bn.randomsample(10)) 78 | 79 | # output 80 | print json.dumps(result, indent=2) 81 | 82 | ''' 83 | 84 | # get sequence 85 | seq = samplerstatement 86 | 87 | # denominator 88 | denom = len(seq) 89 | 90 | output = dict() 91 | for key in seq[0].keys(): 92 | output[key] = dict() 93 | for trial in seq: 94 | keyss = output[key].keys() 95 | vall = trial[key] 96 | if (keyss.count(vall) > 0): 97 | output[key][trial[key]] += 1 98 | else: 99 | output[key][trial[key]] = 1 100 | 101 | # normalize 102 | for entry in output[key].keys(): 103 | output[key][entry] = output[key][entry] / float(denom) 104 | 105 | self.seq = seq 106 | self.avg = output 107 | 108 | return output 109 | -------------------------------------------------------------------------------- /build/lib.linux-x86_64-2.7/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/build/lib.linux-x86_64-2.7/utils/__init__.py -------------------------------------------------------------------------------- /build/lib.linux-x86_64-2.7/utils/libpgmexceptions.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright 2013 CyberPoint International, LLC. 3 | All rights reserved. Use and disclosure prohibited 4 | except as permitted in writing by CyberPoint. 5 | 6 | libpgm exception handler 7 | 8 | Charlie Cabot 9 | Sept 27 2013 10 | 11 | ''' 12 | class libpgmError(Exception): 13 | pass 14 | 15 | class bntextError(libpgmError): 16 | pass 17 | -------------------------------------------------------------------------------- /build/lib/libpgm/CPDtypes/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ['discrete', 'lg', 'lgandd', 'crazy'] 2 | -------------------------------------------------------------------------------- /build/lib/libpgm/CPDtypes/crazy.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, CyberPoint International, LLC 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the CyberPoint International, LLC nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL CYBERPOINT INTERNATIONAL, LLC BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | ''' 26 | This module contains tools for representing "crazy" nodes -- nodes where the method for sampling is to multiply the crazyinput by -10 or 10 and add :math:`\pi` -- as class instances with their own *choose* method to choose an outcome for themselves based on parent outcomes. 27 | 28 | The existence of this 'crazy' type is meant to indicate the true universality of 29 | the universal sampling method found in :doc:`hybayesiannetwork`. While no CPD would 30 | actually be this crazy, the libary has the setup to support any type of CPD. 31 | 32 | 33 | ''' 34 | import math 35 | import random 36 | 37 | class Crazy(): 38 | ''' 39 | This class represents a crazy node, as described above. It contains the *Vdataentry* attribute and the *choose* method. 40 | 41 | ''' 42 | def __init__(self, Vdataentry): 43 | ''' 44 | This class is constructed with the argument *Vdataentry* which must be a dict containing a dictionary entry for this particualr node. The dict must contain an entry of the following form:: 45 | 46 | "crazyinput": 47 | 48 | This ``"crazyinput"`` entry contains the number that will be used in the crazy sampling function. The *Vdataentry* attribute is set equal to this *Vdataentry* input upon instantiation. 49 | ''' 50 | self.Vdataentry = Vdataentry 51 | '''A dict containing CPD data for the node.''' 52 | 53 | def choose(self, pvalues): 54 | ''' 55 | Randomly choose state of node from probability distribution conditioned on *pvalues*. 56 | 57 | This method has two parts: (1) determining the proper probability 58 | distribution, and (2) using that probability distribution to determine 59 | an outcome. 60 | 61 | Arguments: 62 | 1. *pvalues* -- An array containing the assigned states of the node's parents. This must be in the same order as the parents appear in self.Vdataentry['parents']. 63 | 64 | The function takes the crazyinput, multiplies it by either 10 or -10 randomly, adds :math:`\\pi`, converts it to a string, and appends the word "bluberries!". It returns this value. 65 | 66 | ''' 67 | crazyinput = self.Vdataentry["crazyinput"] 68 | answer = "%.2f blueberries!" % (random.choice([10, -10]) * crazyinput + math.pi) 69 | return answer 70 | -------------------------------------------------------------------------------- /build/lib/libpgm/CPDtypes/discrete.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, CyberPoint International, LLC 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the CyberPoint International, LLC nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL CYBERPOINT INTERNATIONAL, LLC BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | ''' 26 | This module contains tools for representing discrete nodes -- those with a finite number of outcomes and a finite number of possible parent values -- as class instances with their own *choose* method to choose an outcome for themselves based on parent outcomes. 27 | 28 | ''' 29 | import random 30 | 31 | class Discrete(): 32 | ''' 33 | This class represents a discrete node, as described above. It contains the *Vdataentry* attribute and the *choose* method. 34 | 35 | ''' 36 | def __init__(self, Vdataentry): 37 | ''' 38 | This class is constructed with the argument *Vdataentry* which must be a dict containing a dictionary entry for this particular node. The dict must contain an entry of the following form:: 39 | 40 | "cprob": { 41 | "['',...,'']": [, ... , ], 42 | ... 43 | "['',...,'']": [, ... , ], 44 | } 45 | 46 | Where the keys are each possible combination of parent values and the values are the probability of each of the *n* possible node outcomes, given those parent outcomes. The *Vdataentry* attribute is set equal to this *Vdataentry* input upon instantiation. 47 | 48 | ''' 49 | self.Vdataentry = Vdataentry 50 | '''A dict containing CPD data for the node.''' 51 | 52 | def choose(self, pvalues): 53 | ''' 54 | Randomly choose state of node from a probability distribution conditioned on parent values *pvalues*. 55 | 56 | This method has two parts: (1) determining the proper probability 57 | distribution, and (2) using that probability distribution to determine 58 | an outcome. 59 | 60 | Arguments: 61 | 1. *pvalues* -- An array containing the assigned states of the node's parents. This must be in the same order as the parents appear in ``self.Vdataentry["parents"]``. 62 | The function goes to the proper entry in *Vdataentry*, as specified by *pvalues*, and samples the node based on the distribution found there. 63 | 64 | ''' 65 | 66 | 67 | p = self.Vdataentry["parents"] 68 | if (not p): 69 | distribution = self.Vdataentry["cprob"] 70 | else: 71 | pvalues = [str(outcome[t]) for t in self.Vdataentry["parents"]] # ideally can we pull this from the skeleton so as not to store parent data at all? 72 | for pvalue in pvalues: 73 | assert pvalue != 'default', "Graph skeleton was not topologically ordered." 74 | 75 | distribution = self.Vdataentry["cprob"][str(pvalues)] 76 | 77 | # choose 78 | rand = random.random() 79 | lbound = 0 80 | ubound = 0 81 | for interval in range(int(self.Vdataentry["numoutcomes"])): 82 | ubound += distribution[interval] 83 | if (lbound <= rand and rand < ubound): 84 | rindex = interval 85 | break 86 | else: 87 | lbound = ubound 88 | 89 | return str(self.Vdataentry["vals"][rindex]) 90 | -------------------------------------------------------------------------------- /build/lib/libpgm/CPDtypes/lg.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, CyberPoint International, LLC 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the CyberPoint International, LLC nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL CYBERPOINT INTERNATIONAL, LLC BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | ''' 26 | This module contains tools for representing linear Gaussian nodes -- those with a continuous linear Gaussian distribution of outcomes and a finite number of linear Gaussian parents -- as class instances with their own *choose* method to choose an outcome for themselves based on parent outcomes. 27 | 28 | ''' 29 | import random 30 | import math 31 | 32 | class Lg(): 33 | ''' 34 | This class represents a linear Gaussian node, as described above. It contains the *Vdataentry* attribute and the *choose* method. 35 | 36 | ''' 37 | def __init__(self, Vdataentry): 38 | ''' 39 | This class is constructed with the argument *Vdataentry* which must be a dict containing a dictionary entry for this particular node. The dict must contain entries of the following form:: 40 | 41 | "mean_base": , 43 | "mean_scal": , 46 | "variance": 47 | 48 | See :doc:`lgbayesiannetwork` for an explanation of linear Gaussian sampling. 49 | 50 | The *Vdataentry* attribute is set equal to this *Vdataentry* input upon instantiation. 51 | 52 | ''' 53 | self.Vdataentry = Vdataentry 54 | '''A dict containing CPD data for the node.''' 55 | 56 | def choose(self, pvalues): 57 | ''' 58 | Randomly choose state of node from probability distribution conditioned on *pvalues*. 59 | 60 | This method has two parts: (1) determining the proper probability 61 | distribution, and (2) using that probability distribution to determine 62 | an outcome. 63 | 64 | Arguments: 65 | 1. *pvalues* -- An array containing the assigned states of the node's parents. This must be in the same order as the parents appear in ``self.Vdataentry['parents']``. 66 | 67 | The function creates a Gaussian distribution in the manner described in :doc:`lgbayesiannetwork`, and samples from that distribution, returning its outcome. 68 | 69 | ''' 70 | 71 | 72 | # calculate Bayesian parameters (mean and variance) 73 | mean = self.Vdataentry["mean_base"] 74 | if (self.Vdataentry["parents"] != None): 75 | for x in range(len(self.Vdataentry["parents"])): 76 | if (pvalues[x] != "default"): 77 | mean += pvalues[x] * self.Vdataentry["mean_scal"][x] 78 | else: 79 | print("Attempted to sample node with unassigned parents.") 80 | 81 | variance = self.Vdataentry["variance"] 82 | 83 | # draw random outcome from Gaussian 84 | # note that this built in function takes the standard deviation, not the 85 | # variance, thus requiring a square root 86 | return random.gauss(mean, math.sqrt(variance)) 87 | -------------------------------------------------------------------------------- /build/lib/libpgm/CPDtypes/lgandd.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, CyberPoint International, LLC 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the CyberPoint International, LLC nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL CYBERPOINT INTERNATIONAL, LLC BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | ''' 26 | This module contains tools for representing "LG + D" (linear Gaussian and discrete) nodes -- those with a Gaussian distribution, zero or more Gaussian parents, and one or more discrete parents -- as class instances with their own *choose* method to choose an outcome for themselves based on parent outcomes. 27 | 28 | ''' 29 | import random 30 | import math 31 | 32 | class Lgandd(): 33 | ''' 34 | This class represents a LG + D node, as described above. It contains the *Vdataentry* attribute and the *choose* method 35 | 36 | ''' 37 | def __init__(self, Vdataentry): 38 | ''' 39 | This class is constructed with the argument *Vdataentry* which must be a dict containing a dictionary entry for this particular node. The dict must contain an entry of the following form:: 40 | 41 | "cprob": { 42 | "['',...,'']": { 43 | "mean_base": , 45 | "mean_scal": , 48 | "variance": 49 | } 50 | ... 51 | "['',...,'']": { 52 | "mean_base": , 54 | "mean_scal": , 57 | "variance": 58 | } 59 | } 60 | 61 | This ``"cprob"`` entry contains a linear Gaussian distribution (conditioned on the Gaussian parents) for each combination of discrete parents. The *Vdataentry* attribute is set equal to this *Vdataentry* input upon instantiation. 62 | 63 | ''' 64 | self.Vdataentry = Vdataentry 65 | '''A dict containing CPD data for the node.''' 66 | 67 | def choose(self, pvalues): 68 | ''' 69 | Randomly choose state of node from probability distribution conditioned on *pvalues*. 70 | 71 | This method has two parts: (1) determining the proper probability 72 | distribution, and (2) using that probability distribution to determine 73 | an outcome. 74 | 75 | Arguments: 76 | 1. *pvalues* -- An array containing the assigned states of the node's parents. This must be in the same order as the parents appear in ``self.Vdataentry['parents']``. 77 | 78 | The function goes to the entry of ``"cprob"`` that matches the outcomes of its discrete parents. Then, it constructs a Gaussian distribution based on its Gaussian parents and the parameters found at that entry. Last, it samples from that distribution and returns its outcome. 79 | 80 | ''' 81 | 82 | 83 | # split parents by type 84 | dispvals = [] 85 | lgpvals = [] 86 | for pval in pvalues: 87 | if (isinstance(pval, str)): 88 | dispvals.append(pval) 89 | else: 90 | lgpvals.append(pval) 91 | 92 | 93 | # Check that we have at least one discrete parent. 94 | if not dispvals: 95 | print("Did not find any discrete parent. Consider using an Lg node.") 96 | 97 | # find correct Gaussian 98 | lgdistribution = self.Vdataentry["hybcprob"][str(dispvals)] 99 | 100 | # calculate Bayesian parameters (mean and variance) 101 | mean = lgdistribution["mean_base"] 102 | if (self.Vdataentry["parents"] != None): 103 | for x in range(len(lgpvals)): 104 | if (lgpvals[x] != "default"): 105 | mean += lgpvals[x] * lgdistribution["mean_scal"][x] 106 | else: 107 | 108 | # temporary error check 109 | print("Attempted to sample node with unassigned parents.") 110 | 111 | variance = lgdistribution["variance"] 112 | 113 | # draw random outcome from Gaussian (I love python) 114 | return random.gauss(mean, math.sqrt(variance)) 115 | -------------------------------------------------------------------------------- /build/lib/libpgm/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ['CPDtypes', 'dictionary', 'discretebayesiannetwork', 'graphskeleton', 'hybayesiannetwork', 'lgbayesiannetwork', 'nodedata', 'orderedskeleton', 'pgmlearner', 'sampleaggregator', 'tablecpdfactor', 'tablecpdfactorization'] 2 | -------------------------------------------------------------------------------- /build/lib/libpgm/dictionary.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, CyberPoint International, LLC 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the CyberPoint International, LLC nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL CYBERPOINT INTERNATIONAL, LLC BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | ''' 26 | Nearly all of the functions of this library require key indexing, which means it deals with dictionaries internally. This module deals with loading dictionaries and handles automatically converting from python-style dictionaries to condensed (no excess white space) JSON-style dictionaries. 27 | 28 | ''' 29 | import sys 30 | import json 31 | import string 32 | 33 | class Dictionary(object): 34 | ''' 35 | This class represents a JSON-style, key-indexable dictionary of data. It contains the attribute *alldata* and the method *dictload*. 36 | ''' 37 | 38 | def __init__(self): 39 | self.alldata = None 40 | '''An internal representation of a key-indexable dictionary.''' 41 | 42 | def dictload(self, path): 43 | ''' 44 | Load a dictionary from a JSON-like text in a text file located at *path* into the attribute *alldata*. 45 | 46 | In order for this function to execute successfully, the text file must have the proper formatting, particularly with regard to quotation marks. See :doc:`unittestdict` for an example. Specifically, the function can get rid of excess whitespace, convert ``.x`` to ``0.x`` in decimals, and convert ``None`` to ``null``, but nothing else. 47 | 48 | Arguments: 49 | 50 | 1. *path* -- Path to the text file (e.g. "mydictionary.txt") 51 | 52 | Attributes modified: 53 | 54 | 1. *alldata* -- The entire loaded dictionary. 55 | 56 | The function also returns an error if nothing was loaded into *alldata*. 57 | 58 | ''' 59 | f = open(path, 'r') 60 | ftext = f.read() 61 | assert (ftext and isinstance(ftext, str)), "Input file is empty or could not be read." 62 | 63 | 64 | # alter for json input, if necessary 65 | loaded = False 66 | try: 67 | self.alldata = json.loads(ftext) 68 | loaded = True 69 | except ValueError: 70 | pass 71 | 72 | if not loaded: 73 | try: 74 | ftext = ftext.translate('\t\n ') 75 | ftext = ftext.replace(':', ': ') 76 | ftext = ftext.replace(',', ', ') 77 | ftext = ftext.replace('None', 'null') 78 | ftext = ftext.replace('.', '0.') 79 | self.alldata = json.loads(ftext) 80 | except ValueError: 81 | raise ValueError("Convert to JSON from input file failed. Check formatting.") 82 | f.close() 83 | 84 | assert isinstance(self.alldata, dict), "In method dictload, path did not direct to a proper text file." 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /build/lib/libpgm/orderedskeleton.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, CyberPoint International, LLC 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the CyberPoint International, LLC nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL CYBERPOINT INTERNATIONAL, LLC BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | ''' 26 | This module facilitates the process of creating ordered graph skeletons by topologically ordering them automatically. 27 | 28 | ''' 29 | 30 | from .graphskeleton import GraphSkeleton 31 | 32 | class OrderedSkeleton(GraphSkeleton): 33 | ''' 34 | This class represents a graph skeleton (see :doc:`graphskeleton`) that is always topologically ordered. 35 | 36 | ''' 37 | 38 | def __init__(self, graphskeleton=None): 39 | self.V = None 40 | '''A list of names of vertices''' 41 | self.E = None 42 | '''A list of [origin, destination] pairs of verties that constitute edges.''' 43 | 44 | def load(self, path): 45 | '''Loads a dictionary from a file located at *path* in the same manner as :doc:`graphskeleton`, but includes a step where it topologically orders the nodes.''' 46 | 47 | self.dictload(path) 48 | self.V = self.alldata["V"] 49 | self.E = self.alldata["E"] 50 | 51 | # topologically order 52 | self.toporder() 53 | 54 | # free unused memory 55 | del self.alldata 56 | -------------------------------------------------------------------------------- /build/lib/libpgm/sampleaggregator.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, CyberPoint International, LLC 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the CyberPoint International, LLC nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL CYBERPOINT INTERNATIONAL, LLC BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | ''' 26 | This module provides tools for collecting and managing sets of samples generated by the library's sampling functions. By averaging a series of samples, the progam can approximate a joint probability distribution without having to do the exact calculations, which may be useful in large networks. 27 | 28 | ''' 29 | 30 | 31 | class SampleAggregator(object): 32 | ''' 33 | This class is a machine for aggregating data from sample sequences. It contains the method *aggregate*. 34 | 35 | ''' 36 | def __init__(self): 37 | self.seq = None 38 | '''The sequence inputted.''' 39 | self.avg = None 40 | '''The average of all the entries in *seq*, represented as a dict where each vertex has an entry whose value is a dict of {key, value} pairs, where each key is a possible outcome of that vertex and its value is the approximate frequency.''' 41 | 42 | 43 | def aggregate(self, samplerstatement): 44 | ''' 45 | Generate a sequence of samples using *samplerstatement* and return the average of its results. 46 | 47 | Arguments: 48 | 1. *samplerstatement* -- The statement of a function (with inputs) that would output a sequence of samples. For example: ``bn.randomsample(50)`` where ``bn`` is an instance of the :doc:`DiscreteBayesianNetwork ` class. 49 | 50 | This function stores the output of *samplerstatement* in the attribute *seq*, and then averages *seq* and stores the approximate distribution found in the attribute *avg*. It then returns *avg*. 51 | 52 | Usage example: this would print the average of 10 data points:: 53 | 54 | import json 55 | 56 | from libpgm.nodedata import NodeData 57 | from libpgm.graphskeleton import GraphSkeleton 58 | from libpgm.discretebayesiannetwork import DiscreteBayesianNetwork 59 | from libpgm.sampleaggregator import SampleAggregator 60 | 61 | # load nodedata and graphskeleton 62 | nd = NodeData() 63 | skel = GraphSkeleton() 64 | nd.load("../tests/unittestdict.txt") 65 | skel.load("../tests/unittestdict.txt") 66 | 67 | # topologically order graphskeleton 68 | skel.toporder() 69 | 70 | # load bayesian network 71 | bn = DiscreteBayesianNetwork(skel, nd) 72 | 73 | # build aggregator 74 | agg = SampleAggregator() 75 | 76 | # average samples 77 | result = agg.aggregate(bn.randomsample(10)) 78 | 79 | # output 80 | print json.dumps(result, indent=2) 81 | 82 | ''' 83 | 84 | # get sequence 85 | seq = samplerstatement 86 | 87 | # denominator 88 | denom = len(seq) 89 | 90 | output = dict() 91 | for key in seq[0].keys(): 92 | output[key] = dict() 93 | for trial in seq: 94 | keyss = list(output[key].keys()) 95 | vall = trial[key] 96 | if (keyss.count(vall) > 0): 97 | output[key][trial[key]] += 1 98 | else: 99 | output[key][trial[key]] = 1 100 | 101 | # normalize 102 | for entry in output[key].keys(): 103 | output[key][entry] = output[key][entry] / float(denom) 104 | 105 | self.seq = seq 106 | self.avg = output 107 | 108 | return output 109 | -------------------------------------------------------------------------------- /build/lib/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/build/lib/utils/__init__.py -------------------------------------------------------------------------------- /build/lib/utils/bntextutils.py: -------------------------------------------------------------------------------- 1 | 2 | ''' 3 | Copyright CyberPoint International LLC 4 | All rights reserved 5 | 6 | C. Cabot 7 | 09-19-13 8 | 9 | Functions to construct/modify a json-style txt file to be 10 | used as a discrete Bayesian network in libpgm. 11 | 12 | ''' 13 | 14 | import json 15 | import sys 16 | 17 | def list_edges(path): 18 | _validate(path) 19 | with open(path, "r") as f: 20 | j = json.load(f) 21 | for e in j["E"]: 22 | print "%s --> %s" % (e[0], e[1]) 23 | 24 | def list_nodes(path): 25 | _validate(path) 26 | with open(path, "r") as f: 27 | j = json.load(f) 28 | for v in j["V"]: 29 | print "%s" % (v) 30 | 31 | def list_nodedata(path): 32 | _validate(path) 33 | with open(path, "r") as f: 34 | j = json.load(f) 35 | for v in j["Vdata"].keys(): 36 | print "%s" % (v) 37 | 38 | def add_edge(path, edge): 39 | _validate(path) 40 | with open(path, "r") as f: 41 | j = json.load(f) 42 | assert edge[0] in j["V"] and edge[1] in j["V"], "bad edge" 43 | if edge not in j["E"]: 44 | j["E"].append(edge) 45 | with open(path, "w") as f: 46 | json.dump(j, f, indent=2) 47 | 48 | def remove_edge(path, edge): 49 | _validate(path) 50 | with open(path, "r") as f: 51 | j = json.load(f) 52 | assert edge in j["E"], "edge not present" 53 | j["E"].remove(edge) 54 | with open(path, "w") as f: 55 | json.dump(j, f, indent=2) 56 | 57 | def add_node(path, node): 58 | _validate(path) 59 | with open(path, "r") as f: 60 | j = json.load(f) 61 | if node not in j["V"]: 62 | j["V"].append(node) 63 | with open(path, "w") as f: 64 | json.dump(j, f, indent=2) 65 | 66 | def remove_node(path, node): 67 | _validate(path) 68 | with open(path, "r") as f: 69 | j = json.load(f) 70 | assert node in j["V"], "node not present" 71 | j["V"].remove(node) 72 | # delete associated Vdata and edges 73 | if node in j["Vdata"]: 74 | del j["Vdata"][node] 75 | for edge in j["E"]: 76 | if edge[0] == node or edge[1] == node: 77 | edges.remove(edge) 78 | with open(path, "w") as f: 79 | json.dump(j, f, indent=2) 80 | 81 | def alter_vdata(path, node): 82 | _validate(path) 83 | with open(path, "r") as f: 84 | j = json.load(f) 85 | assert node in j["V"], "node not present" 86 | print "Current node data: " 87 | print "------------------ " 88 | try: 89 | print json.dumps(j["Vdata"][node], indent=2) 90 | except KeyError: 91 | print "[uninitialized! you may create this node data]" 92 | print "enter new node data: " 93 | while (1): 94 | try: 95 | minij = json.load(sys.stdin) 96 | break 97 | except: 98 | print("malformatted json, try again:") 99 | j["Vdata"][node] = minij 100 | with open(path, "w") as f: 101 | json.dump(j, f, indent=2) 102 | 103 | def refresh(path): 104 | """updates ord, numoutcomes, parents, and children in vdata""" 105 | with open(path, "r") as f: 106 | d = json.load(f) 107 | 108 | # topologically order vertices 109 | Ecopy = [x[:] for x in d["E"]] 110 | roots = [] 111 | toporder = [] 112 | 113 | for vertex in d["V"]: 114 | # find roots 115 | roots = d["V"][:] 116 | for e in Ecopy: 117 | try: 118 | roots.remove(e[1]) 119 | except: 120 | pass 121 | 122 | while roots != []: 123 | n = roots.pop() 124 | toporder.append(n) 125 | for edge in reversed(Ecopy): 126 | if edge[0] == n: 127 | m = edge[1] 128 | Ecopy.remove(edge) 129 | yesparent = False 130 | for e in Ecopy: 131 | if e[1] == m: 132 | yesparent = True 133 | break 134 | if yesparent == False: 135 | roots.append(m) 136 | assert (not Ecopy), ("Graph contains a cycle", Ecopy) 137 | d["V"] = toporder 138 | 139 | # clear attributes 140 | for entry in d["Vdata"]: 141 | d["Vdata"][entry]["parents"] = None 142 | d["Vdata"][entry]["children"] = None 143 | d["Vdata"][entry]["numoutcomes"] = len(d["Vdata"][entry]["vals"]) 144 | d["Vdata"][entry]["ord"] = d["V"].index(entry) 145 | 146 | # make parents and children 147 | for edge in d["E"]: 148 | parent = edge[0] 149 | child = edge[1] 150 | 151 | if d["Vdata"][child]["parents"] == None: 152 | d["Vdata"][child]["parents"] = [] 153 | if parent not in d["Vdata"][child]["parents"]: 154 | d["Vdata"][child]["parents"].append(parent) 155 | 156 | if d["Vdata"][parent]["children"] == None: 157 | d["Vdata"][parent]["children"] = [] 158 | if child not in d["Vdata"][parent]["children"]: 159 | d["Vdata"][parent]["children"].append(child) 160 | 161 | with open(path, "w") as f: 162 | json.dump(d, f, indent=2) 163 | 164 | def _validate(path): 165 | # is json correctly formatted? 166 | try: 167 | with open(path) as f: 168 | json.load(f) 169 | except: 170 | raise Exception("The network file you are trying to modify is invalid") 171 | 172 | # do the nodes match the node data? 173 | with open(path) as f: 174 | j = json.load(f) 175 | if not (sorted(j["V"]) == sorted(j["Vdata"].keys())): 176 | print "warning: nodes and node data do not match" 177 | 178 | # are the edges valid? 179 | for e in j["E"]: 180 | if (e[0] not in j["V"]) or (e[1] not in j["V"]): 181 | print "warning: nodes not found for this edge:", 182 | print e 183 | 184 | -------------------------------------------------------------------------------- /build/lib/utils/libpgmexceptions.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright 2013 CyberPoint International, LLC. 3 | All rights reserved. Use and disclosure prohibited 4 | except as permitted in writing by CyberPoint. 5 | 6 | libpgm exception handler 7 | 8 | Charlie Cabot 9 | Sept 27 2013 10 | 11 | ''' 12 | class libpgmError(Exception): 13 | pass 14 | 15 | class bntextError(libpgmError): 16 | pass 17 | -------------------------------------------------------------------------------- /docs/CPDtypes.rst: -------------------------------------------------------------------------------- 1 | CPDtypes 2 | ******** 3 | 4 | There are currently three real types of CPD nodes in this directory, but there could be infinitely many more. The *crazy* type listed last is meant to show that classes can exist for any computational way to sample a node based on its parent values. The flexibility provided allows for random sampling to exist in hybrid networks. 5 | 6 | 7 | discrete 8 | -------- 9 | 10 | .. automodule:: libpgm.CPDtypes.discrete 11 | :members: 12 | 13 | linear gaussian 14 | --------------- 15 | 16 | .. automodule:: libpgm.CPDtypes.lg 17 | :members: 18 | 19 | linear gaussian + discrete 20 | -------------------------- 21 | 22 | .. automodule:: libpgm.CPDtypes.lgandd 23 | :members: 24 | 25 | crazy (test type) 26 | ----------------- 27 | 28 | .. automodule:: libpgm.CPDtypes.crazy 29 | :members: 30 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = _build 9 | 10 | # Internal variables. 11 | PAPEROPT_a4 = -D latex_paper_size=a4 12 | PAPEROPT_letter = -D latex_paper_size=letter 13 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 14 | # the i18n builder cannot share the environment and doctrees with the others 15 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 16 | 17 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext 18 | 19 | help: 20 | @echo "Please use \`make ' where is one of" 21 | @echo " html to make standalone HTML files" 22 | @echo " dirhtml to make HTML files named index.html in directories" 23 | @echo " singlehtml to make a single large HTML file" 24 | @echo " pickle to make pickle files" 25 | @echo " json to make JSON files" 26 | @echo " htmlhelp to make HTML files and a HTML help project" 27 | @echo " qthelp to make HTML files and a qthelp project" 28 | @echo " devhelp to make HTML files and a Devhelp project" 29 | @echo " epub to make an epub" 30 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 31 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 32 | @echo " text to make text files" 33 | @echo " man to make manual pages" 34 | @echo " texinfo to make Texinfo files" 35 | @echo " info to make Texinfo files and run them through makeinfo" 36 | @echo " gettext to make PO message catalogs" 37 | @echo " changes to make an overview of all changed/added/deprecated items" 38 | @echo " linkcheck to check all external links for integrity" 39 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 40 | 41 | clean: 42 | -rm -rf $(BUILDDIR)/* 43 | 44 | html: 45 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 46 | @echo 47 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 48 | 49 | dirhtml: 50 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 51 | @echo 52 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 53 | 54 | singlehtml: 55 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 56 | @echo 57 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 58 | 59 | pickle: 60 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 61 | @echo 62 | @echo "Build finished; now you can process the pickle files." 63 | 64 | json: 65 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 66 | @echo 67 | @echo "Build finished; now you can process the JSON files." 68 | 69 | htmlhelp: 70 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 71 | @echo 72 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 73 | ".hhp project file in $(BUILDDIR)/htmlhelp." 74 | 75 | qthelp: 76 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 77 | @echo 78 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 79 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 80 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/pgmpy.qhcp" 81 | @echo "To view the help file:" 82 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/pgmpy.qhc" 83 | 84 | devhelp: 85 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 86 | @echo 87 | @echo "Build finished." 88 | @echo "To view the help file:" 89 | @echo "# mkdir -p $$HOME/.local/share/devhelp/pgmpy" 90 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/pgmpy" 91 | @echo "# devhelp" 92 | 93 | epub: 94 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 95 | @echo 96 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 97 | 98 | latex: 99 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 100 | @echo 101 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 102 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 103 | "(use \`make latexpdf' here to do that automatically)." 104 | 105 | latexpdf: 106 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 107 | @echo "Running LaTeX files through pdflatex..." 108 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 109 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 110 | 111 | text: 112 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 113 | @echo 114 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 115 | 116 | man: 117 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 118 | @echo 119 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 120 | 121 | texinfo: 122 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 123 | @echo 124 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 125 | @echo "Run \`make' in that directory to run these through makeinfo" \ 126 | "(use \`make info' here to do that automatically)." 127 | 128 | info: 129 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 130 | @echo "Running Texinfo files through makeinfo..." 131 | make -C $(BUILDDIR)/texinfo info 132 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 133 | 134 | gettext: 135 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 136 | @echo 137 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 138 | 139 | changes: 140 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 141 | @echo 142 | @echo "The overview file is in $(BUILDDIR)/changes." 143 | 144 | linkcheck: 145 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 146 | @echo 147 | @echo "Link check complete; look for any errors in the above output " \ 148 | "or in $(BUILDDIR)/linkcheck/output.txt." 149 | 150 | doctest: 151 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 152 | @echo "Testing of doctests in the sources finished, look at the " \ 153 | "results in $(BUILDDIR)/doctest/output.txt." 154 | -------------------------------------------------------------------------------- /docs/_build/doctrees/CPDtypes.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/doctrees/CPDtypes.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/dictionary.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/doctrees/dictionary.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/discretebayesiannetwork.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/doctrees/discretebayesiannetwork.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/dyndiscbayesiannetwork.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/doctrees/dyndiscbayesiannetwork.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/environment.pickle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/doctrees/environment.pickle -------------------------------------------------------------------------------- /docs/_build/doctrees/graphskeleton.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/doctrees/graphskeleton.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/hybayesiannetwork.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/doctrees/hybayesiannetwork.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/doctrees/index.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/lgbayesiannetwork.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/doctrees/lgbayesiannetwork.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/nodedata.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/doctrees/nodedata.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/orderedskeleton.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/doctrees/orderedskeleton.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/pgmlearner.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/doctrees/pgmlearner.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/pgmlibrary.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/doctrees/pgmlibrary.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/sampleaggregator.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/doctrees/sampleaggregator.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/tablecpdfactor.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/doctrees/tablecpdfactor.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/tablecpdfactorization.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/doctrees/tablecpdfactorization.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/test.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/doctrees/test.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/unittestdict.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/doctrees/unittestdict.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/unittestdyndict.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/doctrees/unittestdyndict.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/unittesthdict.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/doctrees/unittesthdict.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/unittestlgdict.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/doctrees/unittestlgdict.doctree -------------------------------------------------------------------------------- /docs/_build/html/.buildinfo: -------------------------------------------------------------------------------- 1 | # Sphinx build info version 1 2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. 3 | config: 4 | tags: 5 | -------------------------------------------------------------------------------- /docs/_build/html/_modules/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Overview: module code — libpgm 1.1 documentation 12 | 13 | 14 | 15 | 16 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 44 | 45 |
46 | 72 |
73 |
74 | 86 | 87 |
88 |
89 |
90 |
91 | 103 | 107 | 108 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/CPDtypes.txt: -------------------------------------------------------------------------------- 1 | CPDtypes 2 | ******** 3 | 4 | There are currently three real types of CPD nodes in this directory, but there could be infinitely many more. The *crazy* type listed last is meant to show that classes can exist for any computational way to sample a node based on its parent values. The flexibility provided allows for random sampling to exist in hybrid networks. 5 | 6 | 7 | discrete 8 | -------- 9 | 10 | .. automodule:: libpgm.CPDtypes.discrete 11 | :members: 12 | 13 | linear gaussian 14 | --------------- 15 | 16 | .. automodule:: libpgm.CPDtypes.lg 17 | :members: 18 | 19 | linear gaussian + discrete 20 | -------------------------- 21 | 22 | .. automodule:: libpgm.CPDtypes.lgandd 23 | :members: 24 | 25 | crazy (test type) 26 | ----------------- 27 | 28 | .. automodule:: libpgm.CPDtypes.crazy 29 | :members: 30 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/dictionary.txt: -------------------------------------------------------------------------------- 1 | dictionary 2 | ********** 3 | 4 | .. automodule:: libpgm.dictionary 5 | :members: 6 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/discretebayesiannetwork.txt: -------------------------------------------------------------------------------- 1 | discretebayesiannetwork 2 | *********************** 3 | 4 | .. automodule:: libpgm.discretebayesiannetwork 5 | :members: 6 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/dyndiscbayesiannetwork.txt: -------------------------------------------------------------------------------- 1 | dyndiscbayesiannetwork 2 | *********************** 3 | 4 | .. automodule:: libpgm.dyndiscbayesiannetwork 5 | :members: 6 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/graphskeleton.txt: -------------------------------------------------------------------------------- 1 | graphskeleton 2 | ************* 3 | 4 | .. automodule:: libpgm.graphskeleton 5 | :members: 6 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/hybayesiannetwork.txt: -------------------------------------------------------------------------------- 1 | hybayesiannetwork 2 | ***************** 3 | 4 | .. automodule:: libpgm.hybayesiannetwork 5 | :members: 6 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/index.txt: -------------------------------------------------------------------------------- 1 | .. libpgm documentation master file, created by 2 | sphinx-quickstart on Tue Aug 7 11:49:49 2012. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to libpgm! 7 | ================== 8 | 9 | libpgm is an endeavor to make Bayesian probability graphs easy to use. The effort originates from Daphne Koller and Nir Friedman's *Probabilistic Graphical Models* (2009), which provides an in-depth study of probabilistic graphical models and their applications. 10 | 11 | Install from pypi at `http://pypi.python.org/pypi/libpgm `_ or download a tarball `here `_. 12 | 13 | Documentation 14 | ------------- 15 | 16 | The library consists of a series of importable modules, which either represent types of Bayesian graphs, contain methods to operate on them, or both. The methods' individual documentation pages are found below: 17 | 18 | .. toctree:: 19 | 20 | dictionary 21 | graphskeleton 22 | orderedskeleton 23 | nodedata 24 | discretebayesiannetwork 25 | hybayesiannetwork 26 | lgbayesiannetwork 27 | dyndiscbayesiannetwork 28 | tablecpdfactorization 29 | tablecpdfactor 30 | sampleaggregator 31 | pgmlearner 32 | CPDtypes 33 | 34 | 35 | Note that `numpy `_, `scipy `_, and Python 2.7 are required for this library. 36 | 37 | Capabilities 38 | ------------ 39 | 40 | Briefly, the capabilities of this library are: 41 | 42 | - Sampling 43 | - Forward sampling in a discrete-CPD Bayesian network 44 | - Forward sampling in a linear Gaussian-CPD Bayesian network 45 | - Forward sampling in a hybrid (any CPD type) Bayesian network 46 | - Forward sampling in a dynamic 2-TBN Bayesian network 47 | - Gibbs sampling in a discrete-CPD Bayesian network (given evidence) 48 | - Deterministic Inference 49 | - Compute the probability distribution over a specific node or nodes in a discrete-CPD Bayesian network (given evidence, if present) 50 | - Compute the exact probability of an outcome in a discrete-CPD Bayesian network (given evidence, if present) 51 | - Approximative Inference 52 | - Compute the approximate probability distribution by generating samples 53 | - Learning 54 | - Learn the CPDs of a discrete-CPD Bayesian network, given data and a structure 55 | - Learn the structure of a discrete Bayesian network, given only data 56 | - Learn the CPDs of a linear Gaussian Bayesian network, given data and a structure 57 | - Learn the strcutre of a linear Gaussian Bayesian network, given only data 58 | - Learn entire Bayesian networks (structures and parameters) from data 59 | 60 | Input files 61 | ----------- 62 | 63 | Because Bayesian probability graphs are large and contain a lot of data, the library works with .txt files as inputs. The formatting used is JavaScript Object Notation (JSON), with some flexibility (the :doc:`dictionary` module has the capacity to transform python-style dicts to JSON, for instance). Internally, the library stores these files as *json* objects from python's `json `_ library. For examples of the formatting, and of the particular data required for each different Bayesian network type, see the example input files below: 64 | 65 | .. toctree:: 66 | 67 | unittestdict 68 | unittestlgdict 69 | unittesthdict 70 | unittestdyndict 71 | 72 | 73 | Indices and tables 74 | ================== 75 | 76 | * :ref:`genindex` 77 | * :ref:`modindex` 78 | * :ref:`search` 79 | 80 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/lgbayesiannetwork.txt: -------------------------------------------------------------------------------- 1 | lgbayesiannetwork 2 | ***************** 3 | 4 | .. automodule:: libpgm.lgbayesiannetwork 5 | :members: 6 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/nodedata.txt: -------------------------------------------------------------------------------- 1 | nodedata 2 | ******** 3 | 4 | .. automodule:: libpgm.nodedata 5 | :members: 6 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/orderedskeleton.txt: -------------------------------------------------------------------------------- 1 | orderedskeleton 2 | *************** 3 | 4 | .. automodule:: libpgm.orderedskeleton 5 | :members: 6 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/pgmlearner.txt: -------------------------------------------------------------------------------- 1 | pgmlearner 2 | ********** 3 | 4 | .. automodule:: libpgm.pgmlearner 5 | :members: 6 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/sampleaggregator.txt: -------------------------------------------------------------------------------- 1 | sampleaggregator 2 | **************** 3 | 4 | .. automodule:: libpgm.sampleaggregator 5 | :members: 6 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/tablecpdfactor.txt: -------------------------------------------------------------------------------- 1 | tablecpdfactor 2 | ************** 3 | 4 | .. automodule:: libpgm.tablecpdfactor 5 | :members: 6 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/tablecpdfactorization.txt: -------------------------------------------------------------------------------- 1 | tablecpdfactorization 2 | ********************* 3 | 4 | .. automodule:: libpgm.tablecpdfactorization 5 | :members: 6 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/test.txt: -------------------------------------------------------------------------------- 1 | test!! 2 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/unittestdict.txt: -------------------------------------------------------------------------------- 1 | discrete bayesian network 2 | ========================= 3 | 4 | This is an example input file for a Bayesian network with discrete conditional probability distributions. The example is a small (5 node) graph modeling a student's performance. The graph skeleton data is also included, in the vertex set ("V") and the edge set ("E"). The graph itself is from Koller et al. 53.:: 5 | 6 | { 7 | "V": ["Letter", "Grade", "Intelligence", "SAT", "Difficulty"], 8 | "E": [["Intelligence", "Grade"], 9 | ["Difficulty", "Grade"], 10 | ["Intelligence", "SAT"], 11 | ["Grade", "Letter"]], 12 | "Vdata": { 13 | "Letter": { 14 | "ord": 4, 15 | "numoutcomes": 2, 16 | "vals": ["weak", "strong"], 17 | "parents": ["Grade"], 18 | "children": None, 19 | "cprob": { 20 | "['A']": [.1, .9], 21 | "['B']": [.4, .6], 22 | "['C']": [.99, .01] 23 | } 24 | }, 25 | 26 | "SAT": { 27 | "ord": 3, 28 | "numoutcomes": 2, 29 | "vals": ["lowscore", "highscore"], 30 | "parents": ["Intelligence"], 31 | "children": None, 32 | "cprob": { 33 | "['low']": [.95, .05], 34 | "['high']": [.2, .8] 35 | } 36 | }, 37 | 38 | "Grade": { 39 | "ord": 2, 40 | "numoutcomes": 3, 41 | "vals": ["A", "B", "C"], 42 | "parents": ["Difficulty", "Intelligence"], 43 | "children": ["Letter"], 44 | "cprob": { 45 | "['easy', 'low']": [.3, .4, .3], 46 | "['easy', 'high']": [.9, .08, .02], 47 | "['hard', 'low']": [.05, .25, .7], 48 | "['hard', 'high']": [.5, .3, .2] 49 | } 50 | }, 51 | 52 | "Intelligence": { 53 | "ord": 1, 54 | "numoutcomes": 2, 55 | "vals": ["low", "high"], 56 | "parents": None, 57 | "children": ["SAT", "Grade"], 58 | "cprob": [.7, .3] 59 | }, 60 | 61 | "Difficulty": { 62 | "ord": 0, 63 | "numoutcomes": 2, 64 | "vals": ["easy", "hard"], 65 | "parents": None, 66 | "children": ["Grade"], 67 | "cprob": [.6, .4] 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/unittesthdict.txt: -------------------------------------------------------------------------------- 1 | hybrid bayesian network 2 | ======================= 3 | 4 | This is an example input file for a "hybrid" Bayesian network, i.e., one with varying types of conditional probability distributions. It provides hybrid CPD data for the same graph skeleton as in the :doc:`discrete case `:: 5 | 6 | { 7 | "Vdata": { 8 | "Grade": { 9 | "parents": [ 10 | "Difficulty", 11 | "Intelligence" 12 | ], 13 | "type": "lgandd", 14 | "children": [ 15 | "Letter" 16 | ], 17 | "hybcprob": { 18 | "['high']": { 19 | "variance": 10, 20 | "mean_base": 20, 21 | "mean_scal": [ 22 | 1 23 | ] 24 | }, 25 | "['low']": { 26 | "variance": 10, 27 | "mean_base": 10, 28 | "mean_scal": [ 29 | 1 30 | ] 31 | } 32 | } 33 | }, 34 | "Intelligence": { 35 | "numoutcomes": 2, 36 | "cprob": [ 37 | 0.9, 38 | 0.1 39 | ], 40 | "parents": null, 41 | "vals": [ 42 | "low", 43 | "high" 44 | ], 45 | "type": "discrete", 46 | "children": [ 47 | "SAT", 48 | "Grade" 49 | ] 50 | }, 51 | "Difficulty": { 52 | "mean_base": 50, 53 | "mean_scal": [], 54 | "parents": null, 55 | "variance": 18, 56 | "type": "lg", 57 | "children": [ 58 | "Grade" 59 | ] 60 | }, 61 | "Letter": { 62 | "mean_base": -110, 63 | "mean_scal": [ 64 | 2 65 | ], 66 | "parents": [ 67 | "Grade" 68 | ], 69 | "variance": 10, 70 | "type": "lg", 71 | "children": null 72 | }, 73 | "SAT": { 74 | "parents": [ 75 | "Intelligence" 76 | ], 77 | "crazyinput": 7, 78 | "type": "crazy" 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/unittestlgdict.txt: -------------------------------------------------------------------------------- 1 | linear gaussian bayesian network 2 | ================================ 3 | 4 | This is an example input file for a Bayesian network with linear Gaussian conditional probability distributions. It provides linear Gaussian CPD data for the same graph skeleton as in the :doc:`discrete case `:: 5 | 6 | { 7 | "Vdata": { 8 | "Grade": { 9 | "mean_base": 80, 10 | "mean_scal": [ 11 | -0.25, 12 | 0.25 13 | ], 14 | "parents": [ 15 | "Difficulty", 16 | "Intelligence" 17 | ], 18 | "variance": 5, 19 | "type": "lg", 20 | "children": [ 21 | "Letter" 22 | ] 23 | }, 24 | "Intelligence": { 25 | "mean_base": 50, 26 | "mean_scal": [], 27 | "parents": null, 28 | "variance": 18, 29 | "type": "lg", 30 | "children": [ 31 | "SAT", 32 | "Grade" 33 | ] 34 | }, 35 | "Difficulty": { 36 | "mean_base": 50, 37 | "mean_scal": [], 38 | "parents": null, 39 | "variance": 18, 40 | "type": "lg", 41 | "children": [ 42 | "Grade" 43 | ] 44 | }, 45 | "Letter": { 46 | "mean_base": -110, 47 | "mean_scal": [ 48 | 2 49 | ], 50 | "parents": [ 51 | "Grade" 52 | ], 53 | "variance": 10, 54 | "type": "lg", 55 | "children": null 56 | }, 57 | "SAT": { 58 | "mean_base": 10, 59 | "mean_scal": [ 60 | 1 61 | ], 62 | "parents": [ 63 | "Intelligence" 64 | ], 65 | "variance": 10, 66 | "type": "lg", 67 | "children": null 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /docs/_build/html/_static/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/html/_static/ajax-loader.gif -------------------------------------------------------------------------------- /docs/_build/html/_static/comment-bright.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/html/_static/comment-bright.png -------------------------------------------------------------------------------- /docs/_build/html/_static/comment-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/html/_static/comment-close.png -------------------------------------------------------------------------------- /docs/_build/html/_static/comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/html/_static/comment.png -------------------------------------------------------------------------------- /docs/_build/html/_static/default.css: -------------------------------------------------------------------------------- 1 | /* 2 | * default.css_t 3 | * ~~~~~~~~~~~~~ 4 | * 5 | * Sphinx stylesheet -- default theme. 6 | * 7 | * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. 8 | * :license: BSD, see LICENSE for details. 9 | * 10 | */ 11 | 12 | @import url("basic.css"); 13 | 14 | /* -- page layout ----------------------------------------------------------- */ 15 | 16 | body { 17 | font-family: sans-serif; 18 | font-size: 100%; 19 | background-color: #11303d; 20 | color: #000; 21 | margin: 0; 22 | padding: 0; 23 | } 24 | 25 | div.document { 26 | background-color: #1c4e63; 27 | } 28 | 29 | div.documentwrapper { 30 | float: left; 31 | width: 100%; 32 | } 33 | 34 | div.bodywrapper { 35 | margin: 0 0 0 230px; 36 | } 37 | 38 | div.body { 39 | background-color: #ffffff; 40 | color: #000000; 41 | padding: 0 20px 30px 20px; 42 | } 43 | 44 | div.footer { 45 | color: #ffffff; 46 | width: 100%; 47 | padding: 9px 0 9px 0; 48 | text-align: center; 49 | font-size: 75%; 50 | } 51 | 52 | div.footer a { 53 | color: #ffffff; 54 | text-decoration: underline; 55 | } 56 | 57 | div.related { 58 | background-color: #133f52; 59 | line-height: 30px; 60 | color: #ffffff; 61 | } 62 | 63 | div.related a { 64 | color: #ffffff; 65 | } 66 | 67 | div.sphinxsidebar { 68 | } 69 | 70 | div.sphinxsidebar h3 { 71 | font-family: 'Trebuchet MS', sans-serif; 72 | color: #ffffff; 73 | font-size: 1.4em; 74 | font-weight: normal; 75 | margin: 0; 76 | padding: 0; 77 | } 78 | 79 | div.sphinxsidebar h3 a { 80 | color: #ffffff; 81 | } 82 | 83 | div.sphinxsidebar h4 { 84 | font-family: 'Trebuchet MS', sans-serif; 85 | color: #ffffff; 86 | font-size: 1.3em; 87 | font-weight: normal; 88 | margin: 5px 0 0 0; 89 | padding: 0; 90 | } 91 | 92 | div.sphinxsidebar p { 93 | color: #ffffff; 94 | } 95 | 96 | div.sphinxsidebar p.topless { 97 | margin: 5px 10px 10px 10px; 98 | } 99 | 100 | div.sphinxsidebar ul { 101 | margin: 10px; 102 | padding: 0; 103 | color: #ffffff; 104 | } 105 | 106 | div.sphinxsidebar a { 107 | color: #98dbcc; 108 | } 109 | 110 | div.sphinxsidebar input { 111 | border: 1px solid #98dbcc; 112 | font-family: sans-serif; 113 | font-size: 1em; 114 | } 115 | 116 | 117 | 118 | /* -- hyperlink styles ------------------------------------------------------ */ 119 | 120 | a { 121 | color: #355f7c; 122 | text-decoration: none; 123 | } 124 | 125 | a:visited { 126 | color: #355f7c; 127 | text-decoration: none; 128 | } 129 | 130 | a:hover { 131 | text-decoration: underline; 132 | } 133 | 134 | 135 | 136 | /* -- body styles ----------------------------------------------------------- */ 137 | 138 | div.body h1, 139 | div.body h2, 140 | div.body h3, 141 | div.body h4, 142 | div.body h5, 143 | div.body h6 { 144 | font-family: 'Trebuchet MS', sans-serif; 145 | background-color: #f2f2f2; 146 | font-weight: normal; 147 | color: #20435c; 148 | border-bottom: 1px solid #ccc; 149 | margin: 20px -20px 10px -20px; 150 | padding: 3px 0 3px 10px; 151 | } 152 | 153 | div.body h1 { margin-top: 0; font-size: 200%; } 154 | div.body h2 { font-size: 160%; } 155 | div.body h3 { font-size: 140%; } 156 | div.body h4 { font-size: 120%; } 157 | div.body h5 { font-size: 110%; } 158 | div.body h6 { font-size: 100%; } 159 | 160 | a.headerlink { 161 | color: #c60f0f; 162 | font-size: 0.8em; 163 | padding: 0 4px 0 4px; 164 | text-decoration: none; 165 | } 166 | 167 | a.headerlink:hover { 168 | background-color: #c60f0f; 169 | color: white; 170 | } 171 | 172 | div.body p, div.body dd, div.body li { 173 | text-align: justify; 174 | line-height: 130%; 175 | } 176 | 177 | div.admonition p.admonition-title + p { 178 | display: inline; 179 | } 180 | 181 | div.admonition p { 182 | margin-bottom: 5px; 183 | } 184 | 185 | div.admonition pre { 186 | margin-bottom: 5px; 187 | } 188 | 189 | div.admonition ul, div.admonition ol { 190 | margin-bottom: 5px; 191 | } 192 | 193 | div.note { 194 | background-color: #eee; 195 | border: 1px solid #ccc; 196 | } 197 | 198 | div.seealso { 199 | background-color: #ffc; 200 | border: 1px solid #ff6; 201 | } 202 | 203 | div.topic { 204 | background-color: #eee; 205 | } 206 | 207 | div.warning { 208 | background-color: #ffe4e4; 209 | border: 1px solid #f66; 210 | } 211 | 212 | p.admonition-title { 213 | display: inline; 214 | } 215 | 216 | p.admonition-title:after { 217 | content: ":"; 218 | } 219 | 220 | pre { 221 | padding: 5px; 222 | background-color: #eeffcc; 223 | color: #333333; 224 | line-height: 120%; 225 | border: 1px solid #ac9; 226 | border-left: none; 227 | border-right: none; 228 | } 229 | 230 | tt { 231 | background-color: #ecf0f3; 232 | padding: 0 1px 0 1px; 233 | font-size: 0.95em; 234 | } 235 | 236 | th { 237 | background-color: #ede; 238 | } 239 | 240 | .warning tt { 241 | background: #efc2c2; 242 | } 243 | 244 | .note tt { 245 | background: #d6d6d6; 246 | } 247 | 248 | .viewcode-back { 249 | font-family: sans-serif; 250 | } 251 | 252 | div.viewcode-block:target { 253 | background-color: #f4debf; 254 | border-top: 1px solid #ac9; 255 | border-bottom: 1px solid #ac9; 256 | } -------------------------------------------------------------------------------- /docs/_build/html/_static/down-pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/html/_static/down-pressed.png -------------------------------------------------------------------------------- /docs/_build/html/_static/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/html/_static/down.png -------------------------------------------------------------------------------- /docs/_build/html/_static/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/html/_static/file.png -------------------------------------------------------------------------------- /docs/_build/html/_static/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/html/_static/minus.png -------------------------------------------------------------------------------- /docs/_build/html/_static/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/docs/_build/html/_static/plus.png -------------------------------------------------------------------------------- /docs/_build/html/_static/pygments.css: -------------------------------------------------------------------------------- 1 | .highlight .hll { background-color: #ffffcc } 2 | .highlight { background: #eeffcc; } 3 | .highlight .c { color: #408090; font-style: italic } /* Comment */ 4 | .highlight .err { border: 1px solid #FF0000 } /* Error */ 5 | .highlight .k { color: #007020; font-weight: bold } /* Keyword */ 6 | .highlight .o { color: #666666 } /* Operator */ 7 | .highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ 8 | .highlight .cp { color: #007020 } /* Comment.Preproc */ 9 | .highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ 10 | .highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ 11 | .highlight .gd { color: #A00000 } /* Generic.Deleted */ 12 | .highlight .ge { font-style: italic } /* Generic.Emph */ 13 | .highlight .gr { color: #FF0000 } /* Generic.Error */ 14 | .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ 15 | .highlight .gi { color: #00A000 } /* Generic.Inserted */ 16 | .highlight .go { color: #303030 } /* Generic.Output */ 17 | .highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ 18 | .highlight .gs { font-weight: bold } /* Generic.Strong */ 19 | .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ 20 | .highlight .gt { color: #0040D0 } /* Generic.Traceback */ 21 | .highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ 22 | .highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ 23 | .highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ 24 | .highlight .kp { color: #007020 } /* Keyword.Pseudo */ 25 | .highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ 26 | .highlight .kt { color: #902000 } /* Keyword.Type */ 27 | .highlight .m { color: #208050 } /* Literal.Number */ 28 | .highlight .s { color: #4070a0 } /* Literal.String */ 29 | .highlight .na { color: #4070a0 } /* Name.Attribute */ 30 | .highlight .nb { color: #007020 } /* Name.Builtin */ 31 | .highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ 32 | .highlight .no { color: #60add5 } /* Name.Constant */ 33 | .highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ 34 | .highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ 35 | .highlight .ne { color: #007020 } /* Name.Exception */ 36 | .highlight .nf { color: #06287e } /* Name.Function */ 37 | .highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ 38 | .highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ 39 | .highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ 40 | .highlight .nv { color: #bb60d5 } /* Name.Variable */ 41 | .highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ 42 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */ 43 | .highlight .mf { color: #208050 } /* Literal.Number.Float */ 44 | .highlight .mh { color: #208050 } /* Literal.Number.Hex */ 45 | .highlight .mi { color: #208050 } /* Literal.Number.Integer */ 46 | .highlight .mo { color: #208050 } /* Literal.Number.Oct */ 47 | .highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ 48 | .highlight .sc { color: #4070a0 } /* Literal.String.Char */ 49 | .highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ 50 | .highlight .s2 { color: #4070a0 } /* Literal.String.Double */ 51 | .highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ 52 | .highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ 53 | .highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ 54 | .highlight .sx { color: #c65d09 } /* Literal.String.Other */ 55 | .highlight .sr { color: #235388 } /* Literal.String.Regex */ 56 | .highlight .s1 { color: #4070a0 } /* Literal.String.Single */ 57 | .highlight .ss { color: #517918 } /* Literal.String.Symbol */ 58 | .highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ 59 | .highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ 60 | .highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ 61 | .highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ 62 | .highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ -------------------------------------------------------------------------------- /docs/_build/html/_static/sidebar.js: -------------------------------------------------------------------------------- 1 | /* 2 | * sidebar.js 3 | * ~~~~~~~~~~ 4 | * 5 | * This script makes the Sphinx sidebar collapsible. 6 | * 7 | * .sphinxsidebar contains .sphinxsidebarwrapper. This script adds 8 | * in .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton 9 | * used to collapse and expand the sidebar. 10 | * 11 | * When the sidebar is collapsed the .sphinxsidebarwrapper is hidden 12 | * and the width of the sidebar and the margin-left of the document 13 | * are decreased. When the sidebar is expanded the opposite happens. 14 | * This script saves a per-browser/per-session cookie used to 15 | * remember the position of the sidebar among the pages. 16 | * Once the browser is closed the cookie is deleted and the position 17 | * reset to the default (expanded). 18 | * 19 | * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. 20 | * :license: BSD, see LICENSE for details. 21 | * 22 | */ 23 | 24 | $(function() { 25 | // global elements used by the functions. 26 | // the 'sidebarbutton' element is defined as global after its 27 | // creation, in the add_sidebar_button function 28 | var bodywrapper = $('.bodywrapper'); 29 | var sidebar = $('.sphinxsidebar'); 30 | var sidebarwrapper = $('.sphinxsidebarwrapper'); 31 | 32 | // for some reason, the document has no sidebar; do not run into errors 33 | if (!sidebar.length) return; 34 | 35 | // original margin-left of the bodywrapper and width of the sidebar 36 | // with the sidebar expanded 37 | var bw_margin_expanded = bodywrapper.css('margin-left'); 38 | var ssb_width_expanded = sidebar.width(); 39 | 40 | // margin-left of the bodywrapper and width of the sidebar 41 | // with the sidebar collapsed 42 | var bw_margin_collapsed = '.8em'; 43 | var ssb_width_collapsed = '.8em'; 44 | 45 | // colors used by the current theme 46 | var dark_color = $('.related').css('background-color'); 47 | var light_color = $('.document').css('background-color'); 48 | 49 | function sidebar_is_collapsed() { 50 | return sidebarwrapper.is(':not(:visible)'); 51 | } 52 | 53 | function toggle_sidebar() { 54 | if (sidebar_is_collapsed()) 55 | expand_sidebar(); 56 | else 57 | collapse_sidebar(); 58 | } 59 | 60 | function collapse_sidebar() { 61 | sidebarwrapper.hide(); 62 | sidebar.css('width', ssb_width_collapsed); 63 | bodywrapper.css('margin-left', bw_margin_collapsed); 64 | sidebarbutton.css({ 65 | 'margin-left': '0', 66 | 'height': bodywrapper.height() 67 | }); 68 | sidebarbutton.find('span').text('»'); 69 | sidebarbutton.attr('title', _('Expand sidebar')); 70 | document.cookie = 'sidebar=collapsed'; 71 | } 72 | 73 | function expand_sidebar() { 74 | bodywrapper.css('margin-left', bw_margin_expanded); 75 | sidebar.css('width', ssb_width_expanded); 76 | sidebarwrapper.show(); 77 | sidebarbutton.css({ 78 | 'margin-left': ssb_width_expanded-12, 79 | 'height': bodywrapper.height() 80 | }); 81 | sidebarbutton.find('span').text('«'); 82 | sidebarbutton.attr('title', _('Collapse sidebar')); 83 | document.cookie = 'sidebar=expanded'; 84 | } 85 | 86 | function add_sidebar_button() { 87 | sidebarwrapper.css({ 88 | 'float': 'left', 89 | 'margin-right': '0', 90 | 'width': ssb_width_expanded - 28 91 | }); 92 | // create the button 93 | sidebar.append( 94 | '
«
' 95 | ); 96 | var sidebarbutton = $('#sidebarbutton'); 97 | light_color = sidebarbutton.css('background-color'); 98 | // find the height of the viewport to center the '<<' in the page 99 | var viewport_height; 100 | if (window.innerHeight) 101 | viewport_height = window.innerHeight; 102 | else 103 | viewport_height = $(window).height(); 104 | sidebarbutton.find('span').css({ 105 | 'display': 'block', 106 | 'margin-top': (viewport_height - sidebar.position().top - 20) / 2 107 | }); 108 | 109 | sidebarbutton.click(toggle_sidebar); 110 | sidebarbutton.attr('title', _('Collapse sidebar')); 111 | sidebarbutton.css({ 112 | 'color': '#FFFFFF', 113 | 'border-left': '1px solid ' + dark_color, 114 | 'font-size': '1.2em', 115 | 'cursor': 'pointer', 116 | 'height': bodywrapper.height(), 117 | 'padding-top': '1px', 118 | 'margin-left': ssb_width_expanded - 12 119 | }); 120 | 121 | sidebarbutton.hover( 122 | function () { 123 | $(this).css('background-color', dark_color); 124 | }, 125 | function () { 126 | $(this).css('background-color', light_color); 127 | } 128 | ); 129 | } 130 | 131 | function set_position_from_cookie() { 132 | if (!document.cookie) 133 | return; 134 | var items = document.cookie.split(';'); 135 | for(var k=0; k 5 | 6 | 7 | 8 | 9 | 10 | 11 | <no title> — pgmpy 1.1 documentation 12 | 13 | 14 | 15 | 16 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 43 | 44 |
45 |
46 |
47 |
48 | 49 |

A module for loading dictionaries from text files.

50 |

Exported classes:

51 |

Dictionary – Loads a text file into an internal python dict.

52 |

Created on Jun 20, 2012 53 | @author: ccabot

54 |
55 |
56 | class pgmlibrary.dictionary.Dictionary[source]
57 |

Load a text file into an internal python dict.

58 |

Public functions:

59 |

dictload – Load a python dict from JSON-like text in a text file.

60 |
61 |
62 | dictload(path)[source]
63 |

Load a python dict from a JSON-like text in a text file.

64 |

Arguments:

65 |

path – Path to the text file (e.g. “mydictionary.txt”)

66 |

Attributes instantiated:

67 |

self.alldata – The entire loaded dictionary.

68 |

Other actions:

69 |

Checks that the dictionary was properly loaded.

70 |
71 | 72 |
73 | 74 | 75 | 76 |
77 |
78 |
79 |
80 |
81 |

This Page

82 | 86 | 98 | 99 |
100 |
101 |
102 |
103 | 115 | 119 | 120 | -------------------------------------------------------------------------------- /docs/_build/html/search.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Search — libpgm 1.1 documentation 12 | 13 | 14 | 15 | 16 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 34 | 35 | 36 | 37 | 38 | 50 | 51 |
52 |
53 |
54 |
55 | 56 |

Search

57 |
58 | 59 |

60 | Please activate JavaScript to enable the search 61 | functionality. 62 |

63 |
64 |

65 | From here you can search these documents. Enter your search 66 | words into the box below and click "search". Note that the search 67 | function will automatically search for all of the words. Pages 68 | containing fewer words won't appear in the result list. 69 |

70 |
71 | 72 | 73 | 74 |
75 | 76 |
77 | 78 |
79 | 80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 | 101 | 105 | 106 | -------------------------------------------------------------------------------- /docs/dictionary.rst: -------------------------------------------------------------------------------- 1 | dictionary 2 | ********** 3 | 4 | .. automodule:: libpgm.dictionary 5 | :members: 6 | -------------------------------------------------------------------------------- /docs/discretebayesiannetwork.rst: -------------------------------------------------------------------------------- 1 | discretebayesiannetwork 2 | *********************** 3 | 4 | .. automodule:: libpgm.discretebayesiannetwork 5 | :members: 6 | -------------------------------------------------------------------------------- /docs/dyndiscbayesiannetwork.rst: -------------------------------------------------------------------------------- 1 | dyndiscbayesiannetwork 2 | *********************** 3 | 4 | .. automodule:: libpgm.dyndiscbayesiannetwork 5 | :members: 6 | -------------------------------------------------------------------------------- /docs/graphskeleton.rst: -------------------------------------------------------------------------------- 1 | graphskeleton 2 | ************* 3 | 4 | .. automodule:: libpgm.graphskeleton 5 | :members: 6 | -------------------------------------------------------------------------------- /docs/hybayesiannetwork.rst: -------------------------------------------------------------------------------- 1 | hybayesiannetwork 2 | ***************** 3 | 4 | .. automodule:: libpgm.hybayesiannetwork 5 | :members: 6 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. libpgm documentation master file, created by 2 | sphinx-quickstart on Tue Aug 7 11:49:49 2012. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to libpgm! 7 | ================== 8 | 9 | libpgm is an endeavor to make Bayesian probability graphs easy to use. The effort originates from Daphne Koller and Nir Friedman's *Probabilistic Graphical Models* (2009), which provides an in-depth study of probabilistic graphical models and their applications. 10 | 11 | Install from pypi at `http://pypi.python.org/pypi/libpgm `_ or download a tarball `here `_. 12 | 13 | Documentation 14 | ------------- 15 | 16 | The library consists of a series of importable modules, which either represent types of Bayesian graphs, contain methods to operate on them, or both. The methods' individual documentation pages are found below: 17 | 18 | .. toctree:: 19 | 20 | dictionary 21 | graphskeleton 22 | orderedskeleton 23 | nodedata 24 | discretebayesiannetwork 25 | hybayesiannetwork 26 | lgbayesiannetwork 27 | dyndiscbayesiannetwork 28 | tablecpdfactorization 29 | tablecpdfactor 30 | sampleaggregator 31 | pgmlearner 32 | CPDtypes 33 | 34 | 35 | Note that `numpy `_, `scipy `_, and Python 2.7 are required for this library. 36 | 37 | Capabilities 38 | ------------ 39 | 40 | Briefly, the capabilities of this library are: 41 | 42 | - Sampling 43 | - Forward sampling in a discrete-CPD Bayesian network 44 | - Forward sampling in a linear Gaussian-CPD Bayesian network 45 | - Forward sampling in a hybrid (any CPD type) Bayesian network 46 | - Forward sampling in a dynamic 2-TBN Bayesian network 47 | - Gibbs sampling in a discrete-CPD Bayesian network (given evidence) 48 | - Deterministic Inference 49 | - Compute the probability distribution over a specific node or nodes in a discrete-CPD Bayesian network (given evidence, if present) 50 | - Compute the exact probability of an outcome in a discrete-CPD Bayesian network (given evidence, if present) 51 | - Approximative Inference 52 | - Compute the approximate probability distribution by generating samples 53 | - Learning 54 | - Learn the CPDs of a discrete-CPD Bayesian network, given data and a structure 55 | - Learn the structure of a discrete Bayesian network, given only data 56 | - Learn the CPDs of a linear Gaussian Bayesian network, given data and a structure 57 | - Learn the strcutre of a linear Gaussian Bayesian network, given only data 58 | - Learn entire Bayesian networks (structures and parameters) from data 59 | 60 | Input files 61 | ----------- 62 | 63 | Because Bayesian probability graphs are large and contain a lot of data, the library works with .txt files as inputs. The formatting used is JavaScript Object Notation (JSON), with some flexibility (the :doc:`dictionary` module has the capacity to transform python-style dicts to JSON, for instance). Internally, the library stores these files as *json* objects from python's `json `_ library. For examples of the formatting, and of the particular data required for each different Bayesian network type, see the example input files below: 64 | 65 | .. toctree:: 66 | 67 | unittestdict 68 | unittestlgdict 69 | unittesthdict 70 | unittestdyndict 71 | 72 | 73 | Indices and tables 74 | ================== 75 | 76 | * :ref:`genindex` 77 | * :ref:`modindex` 78 | * :ref:`search` 79 | 80 | -------------------------------------------------------------------------------- /docs/lgbayesiannetwork.rst: -------------------------------------------------------------------------------- 1 | lgbayesiannetwork 2 | ***************** 3 | 4 | .. automodule:: libpgm.lgbayesiannetwork 5 | :members: 6 | -------------------------------------------------------------------------------- /docs/nodedata.rst: -------------------------------------------------------------------------------- 1 | nodedata 2 | ******** 3 | 4 | .. automodule:: libpgm.nodedata 5 | :members: 6 | -------------------------------------------------------------------------------- /docs/orderedskeleton.rst: -------------------------------------------------------------------------------- 1 | orderedskeleton 2 | *************** 3 | 4 | .. automodule:: libpgm.orderedskeleton 5 | :members: 6 | -------------------------------------------------------------------------------- /docs/pgmlearner.rst: -------------------------------------------------------------------------------- 1 | pgmlearner 2 | ********** 3 | 4 | .. automodule:: libpgm.pgmlearner 5 | :members: 6 | -------------------------------------------------------------------------------- /docs/sampleaggregator.rst: -------------------------------------------------------------------------------- 1 | sampleaggregator 2 | **************** 3 | 4 | .. automodule:: libpgm.sampleaggregator 5 | :members: 6 | -------------------------------------------------------------------------------- /docs/tablecpdfactor.rst: -------------------------------------------------------------------------------- 1 | tablecpdfactor 2 | ************** 3 | 4 | .. automodule:: libpgm.tablecpdfactor 5 | :members: 6 | -------------------------------------------------------------------------------- /docs/tablecpdfactorization.rst: -------------------------------------------------------------------------------- 1 | tablecpdfactorization 2 | ********************* 3 | 4 | .. automodule:: libpgm.tablecpdfactorization 5 | :members: 6 | -------------------------------------------------------------------------------- /docs/unittestdict.rst: -------------------------------------------------------------------------------- 1 | discrete bayesian network 2 | ========================= 3 | 4 | This is an example input file for a Bayesian network with discrete conditional probability distributions. The example is a small (5 node) graph modeling a student's performance. The graph skeleton data is also included, in the vertex set ("V") and the edge set ("E"). The graph itself is from Koller et al. 53.:: 5 | 6 | { 7 | "V": ["Letter", "Grade", "Intelligence", "SAT", "Difficulty"], 8 | "E": [["Intelligence", "Grade"], 9 | ["Difficulty", "Grade"], 10 | ["Intelligence", "SAT"], 11 | ["Grade", "Letter"]], 12 | "Vdata": { 13 | "Letter": { 14 | "ord": 4, 15 | "numoutcomes": 2, 16 | "vals": ["weak", "strong"], 17 | "parents": ["Grade"], 18 | "children": None, 19 | "cprob": { 20 | "['A']": [.1, .9], 21 | "['B']": [.4, .6], 22 | "['C']": [.99, .01] 23 | } 24 | }, 25 | 26 | "SAT": { 27 | "ord": 3, 28 | "numoutcomes": 2, 29 | "vals": ["lowscore", "highscore"], 30 | "parents": ["Intelligence"], 31 | "children": None, 32 | "cprob": { 33 | "['low']": [.95, .05], 34 | "['high']": [.2, .8] 35 | } 36 | }, 37 | 38 | "Grade": { 39 | "ord": 2, 40 | "numoutcomes": 3, 41 | "vals": ["A", "B", "C"], 42 | "parents": ["Difficulty", "Intelligence"], 43 | "children": ["Letter"], 44 | "cprob": { 45 | "['easy', 'low']": [.3, .4, .3], 46 | "['easy', 'high']": [.9, .08, .02], 47 | "['hard', 'low']": [.05, .25, .7], 48 | "['hard', 'high']": [.5, .3, .2] 49 | } 50 | }, 51 | 52 | "Intelligence": { 53 | "ord": 1, 54 | "numoutcomes": 2, 55 | "vals": ["low", "high"], 56 | "parents": None, 57 | "children": ["SAT", "Grade"], 58 | "cprob": [.7, .3] 59 | }, 60 | 61 | "Difficulty": { 62 | "ord": 0, 63 | "numoutcomes": 2, 64 | "vals": ["easy", "hard"], 65 | "parents": None, 66 | "children": ["Grade"], 67 | "cprob": [.6, .4] 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /docs/unittesthdict.rst: -------------------------------------------------------------------------------- 1 | hybrid bayesian network 2 | ======================= 3 | 4 | This is an example input file for a "hybrid" Bayesian network, i.e., one with varying types of conditional probability distributions. It provides hybrid CPD data for the same graph skeleton as in the :doc:`discrete case `:: 5 | 6 | { 7 | "Vdata": { 8 | "Grade": { 9 | "parents": [ 10 | "Difficulty", 11 | "Intelligence" 12 | ], 13 | "type": "lgandd", 14 | "children": [ 15 | "Letter" 16 | ], 17 | "hybcprob": { 18 | "['high']": { 19 | "variance": 10, 20 | "mean_base": 20, 21 | "mean_scal": [ 22 | 1 23 | ] 24 | }, 25 | "['low']": { 26 | "variance": 10, 27 | "mean_base": 10, 28 | "mean_scal": [ 29 | 1 30 | ] 31 | } 32 | } 33 | }, 34 | "Intelligence": { 35 | "numoutcomes": 2, 36 | "cprob": [ 37 | 0.9, 38 | 0.1 39 | ], 40 | "parents": null, 41 | "vals": [ 42 | "low", 43 | "high" 44 | ], 45 | "type": "discrete", 46 | "children": [ 47 | "SAT", 48 | "Grade" 49 | ] 50 | }, 51 | "Difficulty": { 52 | "mean_base": 50, 53 | "mean_scal": [], 54 | "parents": null, 55 | "variance": 18, 56 | "type": "lg", 57 | "children": [ 58 | "Grade" 59 | ] 60 | }, 61 | "Letter": { 62 | "mean_base": -110, 63 | "mean_scal": [ 64 | 2 65 | ], 66 | "parents": [ 67 | "Grade" 68 | ], 69 | "variance": 10, 70 | "type": "lg", 71 | "children": null 72 | }, 73 | "SAT": { 74 | "parents": [ 75 | "Intelligence" 76 | ], 77 | "crazyinput": 7, 78 | "type": "crazy" 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /docs/unittestlgdict.rst: -------------------------------------------------------------------------------- 1 | linear gaussian bayesian network 2 | ================================ 3 | 4 | This is an example input file for a Bayesian network with linear Gaussian conditional probability distributions. It provides linear Gaussian CPD data for the same graph skeleton as in the :doc:`discrete case `:: 5 | 6 | { 7 | "Vdata": { 8 | "Grade": { 9 | "mean_base": 80, 10 | "mean_scal": [ 11 | -0.25, 12 | 0.25 13 | ], 14 | "parents": [ 15 | "Difficulty", 16 | "Intelligence" 17 | ], 18 | "variance": 5, 19 | "type": "lg", 20 | "children": [ 21 | "Letter" 22 | ] 23 | }, 24 | "Intelligence": { 25 | "mean_base": 50, 26 | "mean_scal": [], 27 | "parents": null, 28 | "variance": 18, 29 | "type": "lg", 30 | "children": [ 31 | "SAT", 32 | "Grade" 33 | ] 34 | }, 35 | "Difficulty": { 36 | "mean_base": 50, 37 | "mean_scal": [], 38 | "parents": null, 39 | "variance": 18, 40 | "type": "lg", 41 | "children": [ 42 | "Grade" 43 | ] 44 | }, 45 | "Letter": { 46 | "mean_base": -110, 47 | "mean_scal": [ 48 | 2 49 | ], 50 | "parents": [ 51 | "Grade" 52 | ], 53 | "variance": 10, 54 | "type": "lg", 55 | "children": null 56 | }, 57 | "SAT": { 58 | "mean_base": 10, 59 | "mean_scal": [ 60 | 1 61 | ], 62 | "parents": [ 63 | "Intelligence" 64 | ], 65 | "variance": 10, 66 | "type": "lg", 67 | "children": null 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /examples/exampledata.txt: -------------------------------------------------------------------------------- 1 | # an example set of data to be used by the learning functions in the PGMlibrary 2 | # it is an array of dicts 3 | [ 4 | { 5 | "Grade": "B", 6 | "Difficulty": "easy", 7 | "SAT": "lowscore", 8 | "Letter": "strong", 9 | "Intelligence": "high" 10 | }, 11 | { 12 | "Grade": "B", 13 | "Difficulty": "hard", 14 | "SAT": "lowscore", 15 | "Letter": "weak", 16 | "Intelligence": "low" 17 | }, 18 | { 19 | "Grade": "C", 20 | "Difficulty": "easy", 21 | "SAT": "lowscore", 22 | "Letter": "weak", 23 | "Intelligence": "low" 24 | }, 25 | { 26 | "Grade": "A", 27 | "Difficulty": "easy", 28 | "SAT": "highscore", 29 | "Letter": "strong", 30 | "Intelligence": "low" 31 | }, 32 | { 33 | "Grade": "B", 34 | "Difficulty": "easy", 35 | "SAT": "lowscore", 36 | "Letter": "weak", 37 | "Intelligence": "low" 38 | }, 39 | { 40 | "Grade": "A", 41 | "Difficulty": "easy", 42 | "SAT": "highscore", 43 | "Letter": "strong", 44 | "Intelligence": "high" 45 | }, 46 | { 47 | "Grade": "A", 48 | "Difficulty": "easy", 49 | "SAT": "highscore", 50 | "Letter": "strong", 51 | "Intelligence": "high" 52 | }, 53 | { 54 | "Grade": "C", 55 | "Difficulty": "easy", 56 | "SAT": "lowscore", 57 | "Letter": "weak", 58 | "Intelligence": "low" 59 | }, 60 | { 61 | "Grade": "C", 62 | "Difficulty": "hard", 63 | "SAT": "lowscore", 64 | "Letter": "weak", 65 | "Intelligence": "high" 66 | }, 67 | { 68 | "Grade": "A", 69 | "Difficulty": "easy", 70 | "SAT": "highscore", 71 | "Letter": "weak", 72 | "Intelligence": "high" 73 | } 74 | ] 75 | -------------------------------------------------------------------------------- /examples/exampleevidence.txt: -------------------------------------------------------------------------------- 1 | # a sample dict holding evidence. this dict says that we know the Difficulty 2 | # is easy 3 | { 4 | 'Difficulty': 'easy' 5 | } 6 | -------------------------------------------------------------------------------- /examples/examplequery.txt: -------------------------------------------------------------------------------- 1 | # a sample query dictionary 2 | # 3 | # example: 4 | # 5 | # { 6 | # 'Grade': ['A', 'B'] 7 | # } 8 | # 9 | # means that you want to know the probability that Grade has outcome A or B. 10 | # 11 | { 12 | 'Grade': ['A', 'B'] 13 | } 14 | -------------------------------------------------------------------------------- /libpgm/CPDtypes/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ['discrete', 'lg', 'lgandd', 'crazy'] 2 | -------------------------------------------------------------------------------- /libpgm/CPDtypes/crazy.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, CyberPoint International, LLC 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the CyberPoint International, LLC nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL CYBERPOINT INTERNATIONAL, LLC BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | ''' 26 | This module contains tools for representing "crazy" nodes -- nodes where the method for sampling is to multiply the crazyinput by -10 or 10 and add :math:`\pi` -- as class instances with their own *choose* method to choose an outcome for themselves based on parent outcomes. 27 | 28 | The existence of this 'crazy' type is meant to indicate the true universality of 29 | the universal sampling method found in :doc:`hybayesiannetwork`. While no CPD would 30 | actually be this crazy, the libary has the setup to support any type of CPD. 31 | 32 | 33 | ''' 34 | import math 35 | import random 36 | 37 | class Crazy(): 38 | ''' 39 | This class represents a crazy node, as described above. It contains the *Vdataentry* attribute and the *choose* method. 40 | 41 | ''' 42 | def __init__(self, Vdataentry): 43 | ''' 44 | This class is constructed with the argument *Vdataentry* which must be a dict containing a dictionary entry for this particualr node. The dict must contain an entry of the following form:: 45 | 46 | "crazyinput": 47 | 48 | This ``"crazyinput"`` entry contains the number that will be used in the crazy sampling function. The *Vdataentry* attribute is set equal to this *Vdataentry* input upon instantiation. 49 | ''' 50 | self.Vdataentry = Vdataentry 51 | '''A dict containing CPD data for the node.''' 52 | 53 | def choose(self, pvalues): 54 | ''' 55 | Randomly choose state of node from probability distribution conditioned on *pvalues*. 56 | 57 | This method has two parts: (1) determining the proper probability 58 | distribution, and (2) using that probability distribution to determine 59 | an outcome. 60 | 61 | Arguments: 62 | 1. *pvalues* -- An array containing the assigned states of the node's parents. This must be in the same order as the parents appear in self.Vdataentry['parents']. 63 | 64 | The function takes the crazyinput, multiplies it by either 10 or -10 randomly, adds :math:`\\pi`, converts it to a string, and appends the word "bluberries!". It returns this value. 65 | 66 | ''' 67 | crazyinput = self.Vdataentry["crazyinput"] 68 | answer = "%.2f blueberries!" % (random.choice([10, -10]) * crazyinput + math.pi) 69 | return answer 70 | -------------------------------------------------------------------------------- /libpgm/CPDtypes/discrete.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, CyberPoint International, LLC 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the CyberPoint International, LLC nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL CYBERPOINT INTERNATIONAL, LLC BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | ''' 26 | This module contains tools for representing discrete nodes -- those with a finite number of outcomes and a finite number of possible parent values -- as class instances with their own *choose* method to choose an outcome for themselves based on parent outcomes. 27 | 28 | ''' 29 | import random 30 | 31 | class Discrete(): 32 | ''' 33 | This class represents a discrete node, as described above. It contains the *Vdataentry* attribute and the *choose* method. 34 | 35 | ''' 36 | def __init__(self, Vdataentry): 37 | ''' 38 | This class is constructed with the argument *Vdataentry* which must be a dict containing a dictionary entry for this particular node. The dict must contain an entry of the following form:: 39 | 40 | "cprob": { 41 | "['',...,'']": [, ... , ], 42 | ... 43 | "['',...,'']": [, ... , ], 44 | } 45 | 46 | Where the keys are each possible combination of parent values and the values are the probability of each of the *n* possible node outcomes, given those parent outcomes. The *Vdataentry* attribute is set equal to this *Vdataentry* input upon instantiation. 47 | 48 | ''' 49 | self.Vdataentry = Vdataentry 50 | '''A dict containing CPD data for the node.''' 51 | 52 | def choose(self, pvalues): 53 | ''' 54 | Randomly choose state of node from a probability distribution conditioned on parent values *pvalues*. 55 | 56 | This method has two parts: (1) determining the proper probability 57 | distribution, and (2) using that probability distribution to determine 58 | an outcome. 59 | 60 | Arguments: 61 | 1. *pvalues* -- An array containing the assigned states of the node's parents. This must be in the same order as the parents appear in ``self.Vdataentry["parents"]``. 62 | The function goes to the proper entry in *Vdataentry*, as specified by *pvalues*, and samples the node based on the distribution found there. 63 | 64 | ''' 65 | 66 | 67 | p = self.Vdataentry["parents"] 68 | if (not p): 69 | distribution = self.Vdataentry["cprob"] 70 | else: 71 | pvalues = [str(outcome[t]) for t in self.Vdataentry["parents"]] # ideally can we pull this from the skeleton so as not to store parent data at all? 72 | for pvalue in pvalues: 73 | assert pvalue != 'default', "Graph skeleton was not topologically ordered." 74 | 75 | distribution = self.Vdataentry["cprob"][str(pvalues)] 76 | 77 | # choose 78 | rand = random.random() 79 | lbound = 0 80 | ubound = 0 81 | for interval in range(int(self.Vdataentry["numoutcomes"])): 82 | ubound += distribution[interval] 83 | if (lbound <= rand and rand < ubound): 84 | rindex = interval 85 | break 86 | else: 87 | lbound = ubound 88 | 89 | return str(self.Vdataentry["vals"][rindex]) 90 | -------------------------------------------------------------------------------- /libpgm/CPDtypes/lg.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, CyberPoint International, LLC 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the CyberPoint International, LLC nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL CYBERPOINT INTERNATIONAL, LLC BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | ''' 26 | This module contains tools for representing linear Gaussian nodes -- those with a continuous linear Gaussian distribution of outcomes and a finite number of linear Gaussian parents -- as class instances with their own *choose* method to choose an outcome for themselves based on parent outcomes. 27 | 28 | ''' 29 | import random 30 | import math 31 | 32 | class Lg(): 33 | ''' 34 | This class represents a linear Gaussian node, as described above. It contains the *Vdataentry* attribute and the *choose* method. 35 | 36 | ''' 37 | def __init__(self, Vdataentry): 38 | ''' 39 | This class is constructed with the argument *Vdataentry* which must be a dict containing a dictionary entry for this particular node. The dict must contain entries of the following form:: 40 | 41 | "mean_base": , 43 | "mean_scal": , 46 | "variance": 47 | 48 | See :doc:`lgbayesiannetwork` for an explanation of linear Gaussian sampling. 49 | 50 | The *Vdataentry* attribute is set equal to this *Vdataentry* input upon instantiation. 51 | 52 | ''' 53 | self.Vdataentry = Vdataentry 54 | '''A dict containing CPD data for the node.''' 55 | 56 | def choose(self, pvalues): 57 | ''' 58 | Randomly choose state of node from probability distribution conditioned on *pvalues*. 59 | 60 | This method has two parts: (1) determining the proper probability 61 | distribution, and (2) using that probability distribution to determine 62 | an outcome. 63 | 64 | Arguments: 65 | 1. *pvalues* -- An array containing the assigned states of the node's parents. This must be in the same order as the parents appear in ``self.Vdataentry['parents']``. 66 | 67 | The function creates a Gaussian distribution in the manner described in :doc:`lgbayesiannetwork`, and samples from that distribution, returning its outcome. 68 | 69 | ''' 70 | 71 | 72 | # calculate Bayesian parameters (mean and variance) 73 | mean = self.Vdataentry["mean_base"] 74 | if (self.Vdataentry["parents"] != None): 75 | for x in range(len(self.Vdataentry["parents"])): 76 | if (pvalues[x] != "default"): 77 | mean += pvalues[x] * self.Vdataentry["mean_scal"][x] 78 | else: 79 | print("Attempted to sample node with unassigned parents.") 80 | 81 | variance = self.Vdataentry["variance"] 82 | 83 | # draw random outcome from Gaussian 84 | # note that this built in function takes the standard deviation, not the 85 | # variance, thus requiring a square root 86 | return random.gauss(mean, math.sqrt(variance)) 87 | -------------------------------------------------------------------------------- /libpgm/CPDtypes/lgandd.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, CyberPoint International, LLC 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the CyberPoint International, LLC nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL CYBERPOINT INTERNATIONAL, LLC BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | ''' 26 | This module contains tools for representing "LG + D" (linear Gaussian and discrete) nodes -- those with a Gaussian distribution, zero or more Gaussian parents, and one or more discrete parents -- as class instances with their own *choose* method to choose an outcome for themselves based on parent outcomes. 27 | 28 | ''' 29 | import random 30 | import math 31 | 32 | class Lgandd(): 33 | ''' 34 | This class represents a LG + D node, as described above. It contains the *Vdataentry* attribute and the *choose* method 35 | 36 | ''' 37 | def __init__(self, Vdataentry): 38 | ''' 39 | This class is constructed with the argument *Vdataentry* which must be a dict containing a dictionary entry for this particular node. The dict must contain an entry of the following form:: 40 | 41 | "cprob": { 42 | "['',...,'']": { 43 | "mean_base": , 45 | "mean_scal": , 48 | "variance": 49 | } 50 | ... 51 | "['',...,'']": { 52 | "mean_base": , 54 | "mean_scal": , 57 | "variance": 58 | } 59 | } 60 | 61 | This ``"cprob"`` entry contains a linear Gaussian distribution (conditioned on the Gaussian parents) for each combination of discrete parents. The *Vdataentry* attribute is set equal to this *Vdataentry* input upon instantiation. 62 | 63 | ''' 64 | self.Vdataentry = Vdataentry 65 | '''A dict containing CPD data for the node.''' 66 | 67 | def choose(self, pvalues): 68 | ''' 69 | Randomly choose state of node from probability distribution conditioned on *pvalues*. 70 | 71 | This method has two parts: (1) determining the proper probability 72 | distribution, and (2) using that probability distribution to determine 73 | an outcome. 74 | 75 | Arguments: 76 | 1. *pvalues* -- An array containing the assigned states of the node's parents. This must be in the same order as the parents appear in ``self.Vdataentry['parents']``. 77 | 78 | The function goes to the entry of ``"cprob"`` that matches the outcomes of its discrete parents. Then, it constructs a Gaussian distribution based on its Gaussian parents and the parameters found at that entry. Last, it samples from that distribution and returns its outcome. 79 | 80 | ''' 81 | 82 | 83 | # split parents by type 84 | dispvals = [] 85 | lgpvals = [] 86 | for pval in pvalues: 87 | if (isinstance(pval, str)): 88 | dispvals.append(pval) 89 | else: 90 | lgpvals.append(pval) 91 | 92 | 93 | # Check that we have at least one discrete parent. 94 | if not dispvals: 95 | print("Did not find any discrete parent. Consider using an Lg node.") 96 | 97 | # find correct Gaussian 98 | lgdistribution = self.Vdataentry["hybcprob"][str(dispvals)] 99 | 100 | # calculate Bayesian parameters (mean and variance) 101 | mean = lgdistribution["mean_base"] 102 | if (self.Vdataentry["parents"] != None): 103 | for x in range(len(lgpvals)): 104 | if (lgpvals[x] != "default"): 105 | mean += lgpvals[x] * lgdistribution["mean_scal"][x] 106 | else: 107 | 108 | # temporary error check 109 | print("Attempted to sample node with unassigned parents.") 110 | 111 | variance = lgdistribution["variance"] 112 | 113 | # draw random outcome from Gaussian (I love python) 114 | return random.gauss(mean, math.sqrt(variance)) 115 | -------------------------------------------------------------------------------- /libpgm/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ['CPDtypes', 'dictionary', 'discretebayesiannetwork', 'graphskeleton', 'hybayesiannetwork', 'lgbayesiannetwork', 'nodedata', 'orderedskeleton', 'pgmlearner', 'sampleaggregator', 'tablecpdfactor', 'tablecpdfactorization'] 2 | -------------------------------------------------------------------------------- /libpgm/dictionary.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, CyberPoint International, LLC 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the CyberPoint International, LLC nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL CYBERPOINT INTERNATIONAL, LLC BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | ''' 26 | Nearly all of the functions of this library require key indexing, which means it deals with dictionaries internally. This module deals with loading dictionaries and handles automatically converting from python-style dictionaries to condensed (no excess white space) JSON-style dictionaries. 27 | 28 | ''' 29 | import sys 30 | import json 31 | import string 32 | 33 | class Dictionary(object): 34 | ''' 35 | This class represents a JSON-style, key-indexable dictionary of data. It contains the attribute *alldata* and the method *dictload*. 36 | ''' 37 | 38 | def __init__(self): 39 | self.alldata = None 40 | '''An internal representation of a key-indexable dictionary.''' 41 | 42 | def dictload(self, path): 43 | ''' 44 | Load a dictionary from a JSON-like text in a text file located at *path* into the attribute *alldata*. 45 | 46 | In order for this function to execute successfully, the text file must have the proper formatting, particularly with regard to quotation marks. See :doc:`unittestdict` for an example. Specifically, the function can get rid of excess whitespace, convert ``.x`` to ``0.x`` in decimals, and convert ``None`` to ``null``, but nothing else. 47 | 48 | Arguments: 49 | 50 | 1. *path* -- Path to the text file (e.g. "mydictionary.txt") 51 | 52 | Attributes modified: 53 | 54 | 1. *alldata* -- The entire loaded dictionary. 55 | 56 | The function also returns an error if nothing was loaded into *alldata*. 57 | 58 | ''' 59 | f = open(path, 'r') 60 | ftext = f.read() 61 | assert (ftext and isinstance(ftext, str)), "Input file is empty or could not be read." 62 | 63 | 64 | # alter for json input, if necessary 65 | loaded = False 66 | try: 67 | self.alldata = json.loads(ftext) 68 | loaded = True 69 | except ValueError: 70 | pass 71 | 72 | if not loaded: 73 | try: 74 | ftext = ftext.translate('\t\n ') 75 | ftext = ftext.replace(':', ': ') 76 | ftext = ftext.replace(',', ', ') 77 | ftext = ftext.replace('None', 'null') 78 | ftext = ftext.replace('.', '0.') 79 | self.alldata = json.loads(ftext) 80 | except ValueError: 81 | raise ValueError("Convert to JSON from input file failed. Check formatting.") 82 | f.close() 83 | 84 | assert isinstance(self.alldata, dict), "In method dictload, path did not direct to a proper text file." 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /libpgm/orderedskeleton.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, CyberPoint International, LLC 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the CyberPoint International, LLC nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL CYBERPOINT INTERNATIONAL, LLC BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | ''' 26 | This module facilitates the process of creating ordered graph skeletons by topologically ordering them automatically. 27 | 28 | ''' 29 | 30 | from .graphskeleton import GraphSkeleton 31 | 32 | class OrderedSkeleton(GraphSkeleton): 33 | ''' 34 | This class represents a graph skeleton (see :doc:`graphskeleton`) that is always topologically ordered. 35 | 36 | ''' 37 | 38 | def __init__(self, graphskeleton=None): 39 | self.V = None 40 | '''A list of names of vertices''' 41 | self.E = None 42 | '''A list of [origin, destination] pairs of verties that constitute edges.''' 43 | 44 | def load(self, path): 45 | '''Loads a dictionary from a file located at *path* in the same manner as :doc:`graphskeleton`, but includes a step where it topologically orders the nodes.''' 46 | 47 | self.dictload(path) 48 | self.V = self.alldata["V"] 49 | self.E = self.alldata["E"] 50 | 51 | # topologically order 52 | self.toporder() 53 | 54 | # free unused memory 55 | del self.alldata 56 | -------------------------------------------------------------------------------- /libpgm/sampleaggregator.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, CyberPoint International, LLC 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the CyberPoint International, LLC nor the 12 | # names of its contributors may be used to endorse or promote products 13 | # derived from this software without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL CYBERPOINT INTERNATIONAL, LLC BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | ''' 26 | This module provides tools for collecting and managing sets of samples generated by the library's sampling functions. By averaging a series of samples, the progam can approximate a joint probability distribution without having to do the exact calculations, which may be useful in large networks. 27 | 28 | ''' 29 | 30 | 31 | class SampleAggregator(object): 32 | ''' 33 | This class is a machine for aggregating data from sample sequences. It contains the method *aggregate*. 34 | 35 | ''' 36 | def __init__(self): 37 | self.seq = None 38 | '''The sequence inputted.''' 39 | self.avg = None 40 | '''The average of all the entries in *seq*, represented as a dict where each vertex has an entry whose value is a dict of {key, value} pairs, where each key is a possible outcome of that vertex and its value is the approximate frequency.''' 41 | 42 | 43 | def aggregate(self, samplerstatement): 44 | ''' 45 | Generate a sequence of samples using *samplerstatement* and return the average of its results. 46 | 47 | Arguments: 48 | 1. *samplerstatement* -- The statement of a function (with inputs) that would output a sequence of samples. For example: ``bn.randomsample(50)`` where ``bn`` is an instance of the :doc:`DiscreteBayesianNetwork ` class. 49 | 50 | This function stores the output of *samplerstatement* in the attribute *seq*, and then averages *seq* and stores the approximate distribution found in the attribute *avg*. It then returns *avg*. 51 | 52 | Usage example: this would print the average of 10 data points:: 53 | 54 | import json 55 | 56 | from libpgm.nodedata import NodeData 57 | from libpgm.graphskeleton import GraphSkeleton 58 | from libpgm.discretebayesiannetwork import DiscreteBayesianNetwork 59 | from libpgm.sampleaggregator import SampleAggregator 60 | 61 | # load nodedata and graphskeleton 62 | nd = NodeData() 63 | skel = GraphSkeleton() 64 | nd.load("../tests/unittestdict.txt") 65 | skel.load("../tests/unittestdict.txt") 66 | 67 | # topologically order graphskeleton 68 | skel.toporder() 69 | 70 | # load bayesian network 71 | bn = DiscreteBayesianNetwork(skel, nd) 72 | 73 | # build aggregator 74 | agg = SampleAggregator() 75 | 76 | # average samples 77 | result = agg.aggregate(bn.randomsample(10)) 78 | 79 | # output 80 | print json.dumps(result, indent=2) 81 | 82 | ''' 83 | 84 | # get sequence 85 | seq = samplerstatement 86 | 87 | # denominator 88 | denom = len(seq) 89 | 90 | output = dict() 91 | for key in seq[0].keys(): 92 | output[key] = dict() 93 | for trial in seq: 94 | keyss = list(output[key].keys()) 95 | vall = trial[key] 96 | if (keyss.count(vall) > 0): 97 | output[key][trial[key]] += 1 98 | else: 99 | output[key][trial[key]] = 1 100 | 101 | # normalize 102 | for entry in output[key].keys(): 103 | output[key][entry] = output[key][entry] / float(denom) 104 | 105 | self.seq = seq 106 | self.avg = output 107 | 108 | return output 109 | -------------------------------------------------------------------------------- /libpgm_examples/discrete_bayesian_network.py: -------------------------------------------------------------------------------- 1 | from libpgm.nodedata import NodeData 2 | from libpgm.graphskeleton import GraphSkeleton 3 | from libpgm.discretebayesiannetwork import DiscreteBayesianNetwork 4 | from libpgm.lgbayesiannetwork import LGBayesianNetwork 5 | from libpgm.hybayesiannetwork import HyBayesianNetwork 6 | from libpgm.dyndiscbayesiannetwork import DynDiscBayesianNetwork 7 | from libpgm.tablecpdfactorization import TableCPDFactorization 8 | from libpgm.sampleaggregator import SampleAggregator 9 | from libpgm.pgmlearner import PGMLearner 10 | -------------------------------------------------------------------------------- /libpgm_examples/discrete_bayesian_network.py~: -------------------------------------------------------------------------------- 1 | { 2 | "V": ["Letter", "Grade", "Intelligence", "SAT", "Difficulty"], 3 | "E": [["Intelligence", "Grade"], 4 | ["Difficulty", "Grade"], 5 | ["Intelligence", "SAT"], 6 | ["Grade", "Letter"]], 7 | "Vdata": { 8 | "Letter": { 9 | "ord": 4, 10 | "numoutcomes": 2, 11 | "vals": ["weak", "strong"], 12 | "parents": ["Grade"], 13 | "children": None, 14 | "cprob": { 15 | "['A']": [.1, .9], 16 | "['B']": [.4, .6], 17 | "['C']": [.99, .01] 18 | } 19 | }, 20 | 21 | "SAT": { 22 | "ord": 3, 23 | "numoutcomes": 2, 24 | "vals": ["lowscore", "highscore"], 25 | "parents": ["Intelligence"], 26 | "children": None, 27 | "cprob": { 28 | "['low']": [.95, .05], 29 | "['high']": [.2, .8] 30 | } 31 | }, 32 | 33 | "Grade": { 34 | "ord": 2, 35 | "numoutcomes": 3, 36 | "vals": ["A", "B", "C"], 37 | "parents": ["Difficulty", "Intelligence"], 38 | "children": ["Letter"], 39 | "cprob": { 40 | "['easy', 'low']": [.3, .4, .3], 41 | "['easy', 'high']": [.9, .08, .02], 42 | "['hard', 'low']": [.05, .25, .7], 43 | "['hard', 'high']": [.5, .3, .2] 44 | } 45 | }, 46 | 47 | "Intelligence": { 48 | "ord": 1, 49 | "numoutcomes": 2, 50 | "vals": ["low", "high"], 51 | "parents": None, 52 | "children": ["SAT", "Grade"], 53 | "cprob": [.7, .3] 54 | }, 55 | 56 | "Difficulty": { 57 | "ord": 0, 58 | "numoutcomes": 2, 59 | "vals": ["easy", "hard"], 60 | "parents": None, 61 | "children": ["Grade"], 62 | "cprob": [.6, .4] 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /runtime-tests/archives/rtFnumvertices_processor.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Processes trials and outputs to a file. 3 | 4 | Charlie Cabot 5 | August 1, 2012 6 | 7 | ''' 8 | 9 | from bn_generator import disc_bn_generator 10 | from timer import timer 11 | 12 | graphsizes = range(100, 10000)[::100] 13 | 14 | op = open("output.csv", 'w') 15 | print >>op, "Forward Sampling in a discrete BN. Runtime as a function of number of vertices. Indegree=3. Numoutcomes=3. Samples=100." 16 | 17 | for size in graphsizes: 18 | disc_bn_generator(size, 3, 3, "disc_bn_x.txt") 19 | runtime = timer("disc_bn_x.txt", 1) 20 | line = "%d, %f" % (size, runtime) 21 | print line 22 | print >>op, line 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /runtime-tests/archives/rtFnumvertices_timer.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Tests the runtime of functions. 3 | 4 | Charlie Cabot 5 | Aug 1 2012 6 | 7 | ''' 8 | 9 | import time 10 | import sys 11 | 12 | sys.path.append("/home/ccabot/Documents/bayesian networks project/bayesian/v3_bayesian/PGMlibrary") 13 | 14 | from nodedata import NodeData 15 | from graphskeleton import GraphSkeleton 16 | from discretebayesiannetwork import DiscreteBayesianNetwork 17 | 18 | def timer(inputfile, trials): 19 | 20 | # load nodedata and graphskeleton 21 | nd = NodeData() 22 | skel = GraphSkeleton() 23 | nd.load(inputfile) 24 | skel.load(inputfile) 25 | 26 | # topologically order graphskeleton 27 | skel.toporder() 28 | 29 | # load bayesian network 30 | bn = DiscreteBayesianNetwork(skel, nd) 31 | 32 | # TIME 33 | totaltime = 0 34 | for _ in range(trials): 35 | start = time.clock() 36 | ret = bn.randomsample(100) 37 | elapsed = time.clock() - start 38 | totaltime += elapsed 39 | totaltime /= trials 40 | 41 | return totaltime 42 | 43 | #timer("/home/ccabot/Documents/bayesian networks project/bayesian/v3_bayesian/PGMlibrary/unittestdict.txt", 10) 44 | 45 | -------------------------------------------------------------------------------- /runtime-tests/bn_generator.py: -------------------------------------------------------------------------------- 1 | ''' 2 | For creating Bayesian network input files 3 | 4 | Charlie Cabot 5 | August 1, 2012 6 | 7 | ''' 8 | import json 9 | 10 | def disc_bn_generator(numvertices, numoutcomes, indegree, outputpath): 11 | ''' 12 | Creates a graph with a specified number of vertices, where all vertices 13 | except the roots have a specified number of parents and a 14 | specified number of children. 15 | 16 | Arguments: 17 | numvertices -- Number of desired vertices 18 | indegree -- Number of parents for all vertices except the roots 19 | outputpath -- Path to created .txt file 20 | 21 | Format is as corresponds to the PGMlibrary discrete-CPD Vdata format. 22 | See PGMlibrary/discretebayesiannetwork.py 23 | 24 | ''' 25 | import random 26 | 27 | op = open(outputpath, 'w') 28 | 29 | # lay out result 30 | result = dict() 31 | result["V"] = [] 32 | result["E"] = [] 33 | result["Vdata"] = dict() 34 | 35 | # make vertices 36 | for x in range(numvertices): 37 | result["V"].append(str(x)) 38 | result["Vdata"][str(x)] = dict() 39 | result["Vdata"][str(x)]["vals"] = [] 40 | result["Vdata"][str(x)]["parents"] = [] 41 | result["Vdata"][str(x)]["children"] = [] 42 | result["Vdata"][str(x)]["cprob"] = dict() 43 | 44 | for y in range(numoutcomes): 45 | result["Vdata"][str(x)]["vals"].append(str(y)) 46 | result["Vdata"][str(x)]["numoutcomes"] = len(result["Vdata"][str(x)]["vals"]) 47 | 48 | # make edges 49 | for x in range(numvertices): 50 | for j in range(indegree): 51 | if x + j + 1 < numvertices: 52 | result["E"].append([str(x), str(x + j + 1)]) 53 | result["Vdata"][str(x)]["children"].append(str(x + j + 1)) 54 | result["Vdata"][str(x + j + 1)]["parents"].append(str(x)) 55 | 56 | # make cprob recursively 57 | 58 | # define helper procedures 59 | def createinterval(n): 60 | '''divide [0, 1] into n slices"''' 61 | ret = [] 62 | nret = [] 63 | for i in range(n): 64 | nret.append(random.random()) 65 | s = sum(nret) 66 | ret = [x/float(s) for x in nret] 67 | return ret 68 | 69 | def explore(x, _dict, key, depth, totaldepth): 70 | '''recursively fill a cprob table''' 71 | if depth < totaldepth: 72 | for val in result["Vdata"][result["Vdata"][x]["parents"][depth]]["vals"]: 73 | ckey = key[:] 74 | ckey.append(val) 75 | explore(x, _dict, ckey, depth + 1, totaldepth) 76 | else: 77 | _dict[str(key)] = createinterval(result["Vdata"][x]["numoutcomes"]) 78 | 79 | for x in range(numvertices): 80 | if result["Vdata"][str(x)]["parents"]: 81 | explore(str(x), result["Vdata"][str(x)]["cprob"], [], 0, len(result["Vdata"][str(x)]["parents"])) 82 | else: 83 | result["Vdata"][str(x)]["cprob"] = createinterval(result["Vdata"][str(x)]["numoutcomes"]) 84 | 85 | print >>op, json.dumps(result) 86 | -------------------------------------------------------------------------------- /runtime-tests/output.csv: -------------------------------------------------------------------------------- 1 | Discrete bn parameter learning. Runtime as a function of datapoints. numvertices=300. numoutcomes=2. indegree=2. max witness size=1. 2 | 500, 0.400000 3 | 1000, 0.800000 4 | 1500, 1.180000 5 | 2000, 1.580000 6 | 2500, 1.970000 7 | 3000, 2.360000 8 | 3500, 2.770000 9 | 4000, 3.230000 10 | 4500, 3.480000 11 | -------------------------------------------------------------------------------- /runtime-tests/processor.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Processes trials and outputs to a file. 3 | 4 | Charlie Cabot 5 | August 1, 2012 6 | 7 | ''' 8 | 9 | from bn_generator import disc_bn_generator 10 | from timer import timer 11 | 12 | r = range(500, 5000)[::500] 13 | 14 | op = open("output.csv", 'w') 15 | print >>op, "Discrete bn parameter learning. Runtime as a function of datapoints. numvertices=300. numoutcomes=2. indegree=2. max witness size=1." 16 | 17 | for dl in r: 18 | disc_bn_generator(300, 2, 2, "disc_bn_x.txt") 19 | runtime = timer("disc_bn_x.txt", 1, dl) 20 | line = "%d, %f" % (dl, runtime) 21 | print line 22 | print >>op, line 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /runtime-tests/results/PGMlibrary2.0_Runtime_Report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/runtime-tests/results/PGMlibrary2.0_Runtime_Report.pdf -------------------------------------------------------------------------------- /runtime-tests/results/dbn_learning_rtFindegree.csv: -------------------------------------------------------------------------------- 1 | Discrete bn learning. Runtime as a function of indegree. Numvertices=30. datapoints=150. numoutcomes=2. max witness size=1. 2 | 1, 1.130000 3 | 2, 1.130000 4 | 3, 1.120000 5 | 4, 1.150000 6 | 5, 1.140000 7 | 6, 1.170000 8 | 7, 1.150000 9 | 8, 1.160000 10 | 9, 1.160000 11 | 10, 1.170000 12 | 11, 1.170000 13 | 12, 1.170000 14 | 13, 1.140000 15 | 14, 1.160000 16 | 15, 1.200000 17 | -------------------------------------------------------------------------------- /runtime-tests/results/dbn_learning_rtFnumdatapoints.csv: -------------------------------------------------------------------------------- 1 | Discrete bn learning. Runtime as a function of data points. Numvertices=30. Indegree=2. numoutcomes=2. max witness size=1. 2 | 50, 0.540000 3 | 100, 0.820000 4 | 150, 1.130000 5 | 200, 1.440000 6 | 250, 1.750000 7 | 300, 2.060000 8 | 350, 2.360000 9 | 400, 2.690000 10 | 450, 3.130000 11 | 500, 3.300000 12 | 550, 3.630000 13 | 600, 4.070000 14 | 650, 4.260000 15 | 700, 4.590000 16 | 750, 4.890000 17 | 800, 5.370000 18 | 850, 5.490000 19 | 900, 5.930000 20 | 950, 6.180000 21 | 1000, 6.480000 22 | 1050, 6.740000 23 | 1100, 7.340000 24 | -------------------------------------------------------------------------------- /runtime-tests/results/dbn_learning_rtFnumoutcomes.csv: -------------------------------------------------------------------------------- 1 | Discrete bn learning. Runtime as a function of numoutcomes. Numvertices=30. datapoints=150. indegree=2. max witness size=1. 2 | 1, 0.390000 3 | 2, 1.170000 4 | 3, 1.500000 5 | 4, 2.000000 6 | 5, 2.800000 7 | 6, 4.220000 8 | 7, 6.310000 9 | 8, 9.010000 10 | 9, 12.470000 11 | 10, 16.860000 12 | 11, 22.110000 13 | -------------------------------------------------------------------------------- /runtime-tests/results/dbn_learning_rtFnumvertices.csv: -------------------------------------------------------------------------------- 1 | Discrete BN learning. Runtime as a function of numvertices. Numoutcomes=2 Indegree=2. Data points=150. Max witness size=1. 2 | 5, 0.010000 3 | 10, 0.070000 4 | 15, 0.200000 5 | 20, 0.410000 6 | 25, 0.710000 7 | 30, 1.140000 8 | 35, 1.710000 9 | 40, 2.440000 10 | 45, 3.400000 11 | 50, 4.560000 12 | 55, 5.910000 13 | 60, 7.520000 14 | 65, 9.670000 15 | 70, 11.590000 16 | 75, 14.000000 17 | -------------------------------------------------------------------------------- /runtime-tests/results/dbn_learningparams_rtFindegree.csv: -------------------------------------------------------------------------------- 1 | Discrete bn parameter learning. Runtime as a function of indegree. numvertices=300. numoutcomes=2. datapoints=1500. indegree=2. max witness size=1. 2 | 1, 0.980000 3 | 2, 1.170000 4 | 3, 1.350000 5 | 4, 1.490000 6 | 5, 1.810000 7 | 6, 2.060000 8 | 7, 2.410000 9 | 8, 3.050000 10 | 9, 4.060000 11 | 10, 5.950000 12 | -------------------------------------------------------------------------------- /runtime-tests/results/dbn_learningparams_rtFnumoutcomes.csv: -------------------------------------------------------------------------------- 1 | Discrete bn parameter learning. Runtime as a function of numoutcomes. numvertices=300. datapoints=1500. indegree=2. max witness size=1. 2 | 1, 1.060000 3 | 2, 1.130000 4 | 3, 1.210000 5 | 4, 1.270000 6 | 5, 1.480000 7 | -------------------------------------------------------------------------------- /runtime-tests/results/dbn_paramlearning_rtFnumdatapoints.csv: -------------------------------------------------------------------------------- 1 | Discrete bn parameter learning. Runtime as a function of datapoints. numvertices=300. numoutcomes=2. indegree=2. max witness size=1. 2 | 500, 0.400000 3 | 1000, 0.800000 4 | 1500, 1.180000 5 | 2000, 1.580000 6 | 2500, 1.970000 7 | 3000, 2.360000 8 | 3500, 2.770000 9 | 4000, 3.230000 10 | 4500, 3.480000 11 | -------------------------------------------------------------------------------- /runtime-tests/results/dbn_paramlearning_rtFnumvertices.csv: -------------------------------------------------------------------------------- 1 | Discrete bn parameter learning. Runtime as a function of numvertices. numoutcomes=2. datapoints=1500. indegree=2. max witness size=1. 2 | 100, 0.360000 3 | 200, 0.740000 4 | 300, 1.140000 5 | 400, 1.520000 6 | 500, 1.930000 7 | 600, 2.390000 8 | 700, 2.860000 9 | 800, 3.160000 10 | -------------------------------------------------------------------------------- /runtime-tests/results/dbn_querying_rtFindegree.csv: -------------------------------------------------------------------------------- 1 | Probability querying in a discrete BN. Runtime as a function of indegree. Numvertices=300. Numoutcomes=3. Evidence=None. Queried node=root of tree. 2 | 1, 0.060000 3 | 2, 0.080000 4 | 3, 0.150000 5 | 4, 0.340000 6 | 5, 0.920000 7 | 6, 2.770000 8 | 7, 8.010000 9 | -------------------------------------------------------------------------------- /runtime-tests/results/dbn_querying_rtFnumoutcomes.csv: -------------------------------------------------------------------------------- 1 | Probability querying in a discrete BN. Runtime as a function of numoutcomes. Numvertices=300. Indegree=3. Evidence=None. Queried node=root of tree. 2 | 2, 0.060000 3 | 3, 0.150000 4 | 4, 0.420000 5 | 5, 1.080000 6 | 6, 2.380000 7 | 7, 4.970000 8 | 8, 9.290000 9 | 9, 16.890000 10 | 10, 27.960000 11 | -------------------------------------------------------------------------------- /runtime-tests/results/dbn_querying_rtFnumvertices.csv: -------------------------------------------------------------------------------- 1 | Probability querying in a discrete BN. Runtime as a function of number of vertices. Indegree=3. Numoutcomes=3. Evidence=None. Queried node=root of tree. 2 | 100, 0.050000 3 | 200, 0.120000 4 | 300, 0.190000 5 | 400, 0.280000 6 | 500, 0.380000 7 | 600, 0.480000 8 | 700, 0.600000 9 | 800, 0.720000 10 | 900, 0.850000 11 | 1000, 1.040000 12 | 1100, 1.160000 13 | 1200, 1.330000 14 | 1300, 1.500000 15 | 1400, 1.740000 16 | 1500, 1.970000 17 | 1600, 2.180000 18 | 1700, 2.400000 19 | 1800, 2.740000 20 | 1900, 2.830000 21 | 2000, 3.250000 22 | 2100, 3.320000 23 | 2200, 3.650000 24 | 2300, 3.970000 25 | 2400, 4.290000 26 | 2500, 4.580000 27 | -------------------------------------------------------------------------------- /runtime-tests/results/dbn_querying_rtFnumvertices2.csv: -------------------------------------------------------------------------------- 1 | Probability querying in a discrete BN. Runtime as a function of number of vertices. Indegree=3. Numoutcomes=3. Evidence=None. Queried node=leaf of tree. 2 | 100, 0.020000 3 | 200, 0.060000 4 | 300, 0.110000 5 | 400, 0.150000 6 | 500, 0.220000 7 | 600, 0.300000 8 | 700, 0.380000 9 | 800, 0.480000 10 | 900, 0.590000 11 | 1000, 0.720000 12 | 1100, 0.830000 13 | 1200, 0.970000 14 | 1300, 1.130000 15 | 1400, 1.280000 16 | 1500, 1.460000 17 | 1600, 1.650000 18 | 1700, 1.840000 19 | 1800, 2.060000 20 | 1900, 2.250000 21 | 2000, 2.580000 22 | 2100, 2.730000 23 | 2200, 2.990000 24 | 2300, 3.250000 25 | 2400, 3.560000 26 | 2500, 3.880000 27 | -------------------------------------------------------------------------------- /runtime-tests/results/dbn_sampling_memFindegree.csv: -------------------------------------------------------------------------------- 1 | Memory usage (nodedata and then skeleton) as a function of indegree. Numoutcomes=2. Numvertices=300.,, 1,621584,93848 2,821696,165152 3,1420312,237056 4,2196888,307816 5,4443488,378944 6,7792624,448712 7,17281032,520576 8,31969704,590600 9,72569936,660704 10,136750336,727904 11,309613872,797880 -------------------------------------------------------------------------------- /runtime-tests/results/dbn_sampling_memFnumoutcomes.csv: -------------------------------------------------------------------------------- 1 | memory space in megabytes used by (nodedata, graphskeleton) as a function of number of outcomes per node. indegree=2. numvertices=300. 2 | 1, 575760, 165152 3 | 2, 821696, 165152 4 | 3, 1501568, 165152 5 | 4, 2200560, 165152 6 | 5, 4125232, 165152 7 | 6, 5554624, 165152 8 | 7, 7379040, 165152 9 | 8, 9642160, 165152 10 | 9, 13951568, 165152 11 | 10, 20329632, 165152 12 | 11, 24571704, 165152 13 | 12, 29467040, 165152 14 | 13, 35058552, 165152 15 | 14, 41389152, 165152 16 | 15, 48501752, 165152 17 | 16, 56439264, 165152 18 | 17, 71468280, 165152 19 | 18, 81935384, 165152 20 | 19, 104384520, 165152 21 | -------------------------------------------------------------------------------- /runtime-tests/results/dbn_sampling_rtFnumvertices.csv: -------------------------------------------------------------------------------- 1 | Forward Sampling in a discrete BN. Runtime as a function of number of vertices. Indegree=3. Numoutcomes=3. Samples=100. 2 | 100, 0.050000 3 | 200, 0.100000 4 | 300, 0.150000 5 | 400, 0.210000 6 | 500, 0.260000 7 | 600, 0.310000 8 | 700, 0.380000 9 | 800, 0.440000 10 | 900, 0.500000 11 | 1000, 0.550000 12 | 1100, 0.620000 13 | 1200, 0.700000 14 | 1300, 0.760000 15 | 1400, 0.860000 16 | 1500, 0.910000 17 | 1600, 0.990000 18 | 1700, 1.060000 19 | 1800, 1.130000 20 | 1900, 1.220000 21 | 2000, 1.290000 22 | 2100, 1.350000 23 | 2200, 1.420000 24 | 2300, 1.490000 25 | 2400, 1.570000 26 | 2500, 1.640000 27 | -------------------------------------------------------------------------------- /runtime-tests/timer.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Tests the runtime of functions. 3 | 4 | Charlie Cabot 5 | Aug 1 2012 6 | 7 | ''' 8 | 9 | import time 10 | import json 11 | import sys 12 | 13 | sys.path.append("../libpgm/") # make sure this is right 14 | 15 | #from pympler.asizeof import asizeof 16 | #from pympler import muppy, summary 17 | 18 | from nodedata import NodeData 19 | from graphskeleton import GraphSkeleton 20 | from discretebayesiannetwork import DiscreteBayesianNetwork 21 | from tablecpdfactorization import TableCPDFactorization 22 | from pgmlearner import PGMLearner 23 | 24 | op = open("output.csv", 'w') 25 | 26 | 27 | 28 | def timer(inputfile, trials, datalength): 29 | 30 | # load nodedata and graphskeleton 31 | nd = NodeData() 32 | skel = GraphSkeleton() 33 | #print "bp1" 34 | nd.load(inputfile) 35 | #print "bp2" 36 | skel.load(inputfile) 37 | #print "bp3" 38 | 39 | # msg = "%d, %d" % (asizeof(nd), asizeof(skel)) 40 | # print >>op, msg 41 | 42 | # topologically order graphskeleton 43 | skel.toporder() 44 | 45 | # load bayesian network 46 | bn = DiscreteBayesianNetwork(skel, nd) 47 | 48 | # instantiate pgm learner 49 | l = PGMLearner() 50 | 51 | # free unused memory 52 | del nd 53 | 54 | #sum1 = summary.summarize(muppy.get_objects()) 55 | #summary.print_(sum1) 56 | 57 | # TIME 58 | totaltime = 0 59 | for _ in range(trials): 60 | data = bn.randomsample(datalength) 61 | start = time.clock() 62 | ret = l.discrete_mle_estimateparams(skel, data) 63 | elapsed = time.clock() - start 64 | totaltime += elapsed 65 | totaltime /= trials 66 | 67 | 68 | print json.dumps(ret.Vdata, indent=1) 69 | return totaltime 70 | #timer("/home/ccabot/Documents/bayesian networks project/bayesian/v3_bayesian/PGMlibrary/unittestdict.txt", 10) 71 | 72 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # run python setup.py install to install 2 | # run python setup.py sdist to generate a tarball 3 | 4 | from distutils.core import setup 5 | 6 | setup( 7 | 8 | name = 'libpgm', 9 | version = '1.3', 10 | author = 'CyberPoint International, LLC', 11 | author_email = 'mraugas@cyberpointllc.com', 12 | url = 'http://www.cyberpointllc.com', 13 | description = 'A library for creating and using probabilistic graphical models', 14 | long_description = 'This library provides tools for modeling large systems with Bayesian networks. Using these tools allows for efficient statistical analysis on large data sets.', 15 | packages = ['libpgm', 'libpgm.CPDtypes', 'utils'] 16 | ) 17 | -------------------------------------------------------------------------------- /tests/unittestdict.txt: -------------------------------------------------------------------------------- 1 | { 2 | "V": ["Letter", "Grade", "Intelligence", "SAT", "Difficulty"], 3 | "E": [["Intelligence", "Grade"], 4 | ["Difficulty", "Grade"], 5 | ["Intelligence", "SAT"], 6 | ["Grade", "Letter"]], 7 | "Vdata": { 8 | "Letter": { 9 | "ord": 4, 10 | "numoutcomes": 2, 11 | "vals": ["weak", "strong"], 12 | "parents": ["Grade"], 13 | "children": None, 14 | "cprob": { 15 | "['A']": [.1, .9], 16 | "['B']": [.4, .6], 17 | "['C']": [.99, .01] 18 | } 19 | }, 20 | 21 | "SAT": { 22 | "ord": 3, 23 | "numoutcomes": 2, 24 | "vals": ["lowscore", "highscore"], 25 | "parents": ["Intelligence"], 26 | "children": None, 27 | "cprob": { 28 | "['low']": [.95, .05], 29 | "['high']": [.2, .8] 30 | } 31 | }, 32 | 33 | "Grade": { 34 | "ord": 2, 35 | "numoutcomes": 3, 36 | "vals": ["A", "B", "C"], 37 | "parents": ["Difficulty", "Intelligence"], 38 | "children": ["Letter"], 39 | "cprob": { 40 | "['easy', 'low']": [.3, .4, .3], 41 | "['easy', 'high']": [.9, .08, .02], 42 | "['hard', 'low']": [.05, .25, .7], 43 | "['hard', 'high']": [.5, .3, .2] 44 | } 45 | }, 46 | 47 | "Intelligence": { 48 | "ord": 1, 49 | "numoutcomes": 2, 50 | "vals": ["low", "high"], 51 | "parents": None, 52 | "children": ["SAT", "Grade"], 53 | "cprob": [.7, .3] 54 | }, 55 | 56 | "Difficulty": { 57 | "ord": 0, 58 | "numoutcomes": 2, 59 | "vals": ["easy", "hard"], 60 | "parents": None, 61 | "children": ["Grade"], 62 | "cprob": [.6, .4] 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /tests/unittestdyndict.txt: -------------------------------------------------------------------------------- 1 | { 2 | "V": ["Letter", "Grade", "Intelligence", "SAT", "Difficulty"], 3 | "E": [["Intelligence", "Grade"], 4 | ["Difficulty", "Grade"], 5 | ["Intelligence", "SAT"], 6 | ["Grade", "Letter"]], 7 | "initial_Vdata": { 8 | "Letter": { 9 | "ord": 4, 10 | "numoutcomes": 2, 11 | "vals": ["weak", "strong"], 12 | "parents": ["Grade"], 13 | "children": None, 14 | "cprob": { 15 | "['A']": [.1, .9], 16 | "['B']": [.4, .6], 17 | "['C']": [.99, .01] 18 | } 19 | }, 20 | 21 | "SAT": { 22 | "ord": 3, 23 | "numoutcomes": 2, 24 | "vals": ["lowscore", "highscore"], 25 | "parents": ["Intelligence"], 26 | "children": None, 27 | "cprob": { 28 | "['low']": [.95, .05], 29 | "['high']": [.2, .8] 30 | } 31 | }, 32 | 33 | "Grade": { 34 | "ord": 2, 35 | "numoutcomes": 3, 36 | "vals": ["A", "B", "C"], 37 | "parents": ["Difficulty", "Intelligence"], 38 | "children": ["Letter"], 39 | "cprob": { 40 | "['easy', 'low']": [.3, .4, .3], 41 | "['easy', 'high']": [.9, .08, .02], 42 | "['hard', 'low']": [.05, .25, .7], 43 | "['hard', 'high']": [.5, .3, .2] 44 | } 45 | }, 46 | 47 | "Intelligence": { 48 | "ord": 1, 49 | "numoutcomes": 2, 50 | "vals": ["low", "high"], 51 | "parents": None, 52 | "children": ["SAT", "Grade"], 53 | "cprob": [.7, .3] 54 | }, 55 | 56 | "Difficulty": { 57 | "ord": 0, 58 | "numoutcomes": 2, 59 | "vals": ["easy", "hard"], 60 | "parents": None, 61 | "children": ["Grade"], 62 | "cprob": [.6, .4] 63 | } 64 | }, 65 | "twotbn_Vdata": { 66 | "Letter": { 67 | "ord": 4, 68 | "numoutcomes": 2, 69 | "vals": ["weak", "strong"], 70 | "parents": ["past_Grade", "past_Letter", "Grade"], 71 | "children": None, 72 | "cprob": { 73 | "['A', 'weak', 'A']": [.1, .9], 74 | "['A', 'weak', 'B']": [.15, .85], 75 | "['A', 'weak', 'C']": [.05, .95], 76 | "['A', 'strong', 'A']": [.1, .9], 77 | "['A', 'strong', 'B']": [.1, .9], 78 | "['A', 'strong', 'C']": [.1, .9], 79 | "['B', 'weak', 'A']": [.47, .53], 80 | "['B', 'weak', 'B']": [.4, .6], 81 | "['B', 'weak', 'C']": [.4, .6], 82 | "['B', 'strong', 'A']": [.4, .6], 83 | "['B', 'strong', 'B']": [.41, .59], 84 | "['B', 'strong', 'C']": [.42, .58], 85 | "['C', 'weak', 'A']": [.99, .01], 86 | "['C', 'weak', 'B']": [.99, .01], 87 | "['C', 'weak', 'C']": [.99, .01], 88 | "['C', 'strong', 'A']": [.99, .01], 89 | "['C', 'strong', 'B']": [.99, .01], 90 | "['C', 'strong', 'C']": [.99, .01] 91 | } 92 | }, 93 | 94 | "SAT": { 95 | "ord": 3, 96 | "numoutcomes": 2, 97 | "vals": ["lowscore", "highscore"], 98 | "parents": ["Intelligence"], 99 | "children": None, 100 | "cprob": { 101 | "['low']": [.95, .05], 102 | "['high']": [.2, .8] 103 | } 104 | }, 105 | 106 | "Grade": { 107 | "ord": 2, 108 | "numoutcomes": 3, 109 | "vals": ["A", "B", "C"], 110 | "parents": ["Difficulty", "Intelligence"], 111 | "children": ["Letter"], 112 | "cprob": { 113 | "['easy', 'low']": [.3, .4, .3], 114 | "['easy', 'high']": [.9, .08, .02], 115 | "['hard', 'low']": [.05, .25, .7], 116 | "['hard', 'high']": [.5, .3, .2] 117 | } 118 | }, 119 | 120 | "Intelligence": { 121 | "ord": 1, 122 | "numoutcomes": 2, 123 | "vals": ["low", "high"], 124 | "parents": ["past_Intelligence"], 125 | "children": ["SAT", "Grade"], 126 | "cprob": { 127 | "['high']": [.7, .3], 128 | "['low']": [.7, .3] 129 | } 130 | }, 131 | 132 | "Difficulty": { 133 | "ord": 0, 134 | "numoutcomes": 2, 135 | "vals": ["easy", "hard"], 136 | "parents": ["past_Difficulty"], 137 | "children": ["Grade"], 138 | "cprob": { 139 | "['easy']": [1, 0], 140 | "['hard']": [0, 1] 141 | } 142 | } 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /tests/unittesthdict.txt: -------------------------------------------------------------------------------- 1 | { 2 | "Vdata": { 3 | "Grade": { 4 | "parents": [ 5 | "Difficulty", 6 | "Intelligence" 7 | ], 8 | "type": "lgandd", 9 | "children": [ 10 | "Letter" 11 | ], 12 | "hybcprob": { 13 | "['high']": { 14 | "variance": 10, 15 | "mean_base": 20, 16 | "mean_scal": [ 17 | 1 18 | ] 19 | }, 20 | "['low']": { 21 | "variance": 10, 22 | "mean_base": 10, 23 | "mean_scal": [ 24 | 1 25 | ] 26 | } 27 | } 28 | }, 29 | "Intelligence": { 30 | "numoutcomes": 2, 31 | "cprob": [ 32 | 0.9, 33 | 0.1 34 | ], 35 | "parents": null, 36 | "vals": [ 37 | "low", 38 | "high" 39 | ], 40 | "type": "discrete", 41 | "children": [ 42 | "SAT", 43 | "Grade" 44 | ] 45 | }, 46 | "Difficulty": { 47 | "mean_base": 50, 48 | "mean_scal": [], 49 | "parents": null, 50 | "variance": 18, 51 | "type": "lg", 52 | "children": [ 53 | "Grade" 54 | ] 55 | }, 56 | "Letter": { 57 | "mean_base": -110, 58 | "mean_scal": [ 59 | 2 60 | ], 61 | "parents": [ 62 | "Grade" 63 | ], 64 | "variance": 10, 65 | "type": "lg", 66 | "children": null 67 | }, 68 | "SAT": { 69 | "parents": [ 70 | "Intelligence" 71 | ], 72 | "crazyinput": 7, 73 | "type": "crazy" 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /tests/unittesthdict_lgandd_no_lg_parents.txt: -------------------------------------------------------------------------------- 1 | { 2 | "V": ["Letter", "Grade", "Intelligence", "SAT", "Difficulty"], 3 | "E": [["Intelligence", "Grade"], 4 | ["Difficulty", "Grade"], 5 | ["Intelligence", "SAT"], 6 | ["Grade", "Letter"]], 7 | "Vdata": { 8 | "Grade": { 9 | "parents": [ 10 | "Intelligence" 11 | ], 12 | "type": "lgandd", 13 | "children": [ 14 | "Letter" 15 | ], 16 | "hybcprob": { 17 | "['high']": { 18 | "variance": 10, 19 | "mean_base": 20, 20 | "mean_scal": [ 21 | 1 22 | ] 23 | }, 24 | "['low']": { 25 | "variance": 10, 26 | "mean_base": 10, 27 | "mean_scal": [ 28 | 1 29 | ] 30 | } 31 | } 32 | }, 33 | "Intelligence": { 34 | "numoutcomes": 2, 35 | "cprob": [ 36 | 0.9, 37 | 0.1 38 | ], 39 | "parents": null, 40 | "vals": [ 41 | "low", 42 | "high" 43 | ], 44 | "type": "discrete", 45 | "children": [ 46 | "SAT", 47 | "Grade" 48 | ] 49 | }, 50 | "Difficulty": { 51 | "mean_base": 50, 52 | "mean_scal": [], 53 | "parents": null, 54 | "variance": 18, 55 | "type": "lg", 56 | "children": [ 57 | "Grade" 58 | ] 59 | }, 60 | "Letter": { 61 | "mean_base": -110, 62 | "mean_scal": [ 63 | 2 64 | ], 65 | "parents": [ 66 | "Grade" 67 | ], 68 | "variance": 10, 69 | "type": "lg", 70 | "children": null 71 | }, 72 | "SAT": { 73 | "parents": [ 74 | "Intelligence" 75 | ], 76 | "crazyinput": 7, 77 | "type": "crazy" 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /tests/unittestlgdict.txt: -------------------------------------------------------------------------------- 1 | { 2 | "Vdata": { 3 | "Grade": { 4 | "mean_base": 80, 5 | "mean_scal": [ 6 | -0.25, 7 | 0.25 8 | ], 9 | "parents": [ 10 | "Difficulty", 11 | "Intelligence" 12 | ], 13 | "variance": 5, 14 | "type": "lg", 15 | "children": [ 16 | "Letter" 17 | ] 18 | }, 19 | "Intelligence": { 20 | "mean_base": 50, 21 | "mean_scal": [], 22 | "parents": null, 23 | "variance": 18, 24 | "type": "lg", 25 | "children": [ 26 | "SAT", 27 | "Grade" 28 | ] 29 | }, 30 | "Difficulty": { 31 | "mean_base": 50, 32 | "mean_scal": [], 33 | "parents": null, 34 | "variance": 18, 35 | "type": "lg", 36 | "children": [ 37 | "Grade" 38 | ] 39 | }, 40 | "Letter": { 41 | "mean_base": -110, 42 | "mean_scal": [ 43 | 2 44 | ], 45 | "parents": [ 46 | "Grade" 47 | ], 48 | "variance": 10, 49 | "type": "lg", 50 | "children": null 51 | }, 52 | "SAT": { 53 | "mean_base": 10, 54 | "mean_scal": [ 55 | 1 56 | ], 57 | "parents": [ 58 | "Intelligence" 59 | ], 60 | "variance": 10, 61 | "type": "lg", 62 | "children": null 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberPoint/libpgm/be32202d28f53cf3761a2e31ea8ffcdc3e383789/utils/__init__.py -------------------------------------------------------------------------------- /utils/bntextutils.py: -------------------------------------------------------------------------------- 1 | 2 | ''' 3 | Copyright CyberPoint International LLC 4 | All rights reserved 5 | 6 | C. Cabot 7 | 09-19-13 8 | 9 | Functions to construct/modify a json-style txt file to be 10 | used as a discrete Bayesian network in libpgm. 11 | 12 | ''' 13 | 14 | import json 15 | import sys 16 | 17 | def list_edges(path): 18 | _validate(path) 19 | with open(path, "r") as f: 20 | j = json.load(f) 21 | for e in j["E"]: 22 | print("{} --> {}".format(e[0], e[1])) 23 | 24 | def list_nodes(path): 25 | _validate(path) 26 | with open(path, "r") as f: 27 | j = json.load(f) 28 | for v in j["V"]: 29 | print("{}".format(v)) 30 | 31 | def list_nodedata(path): 32 | _validate(path) 33 | with open(path, "r") as f: 34 | j = json.load(f) 35 | for v in j["Vdata"].keys(): 36 | print("{}".format(v)) 37 | 38 | def add_edge(path, edge): 39 | _validate(path) 40 | with open(path, "r") as f: 41 | j = json.load(f) 42 | assert edge[0] in j["V"] and edge[1] in j["V"], "bad edge" 43 | if edge not in j["E"]: 44 | j["E"].append(edge) 45 | with open(path, "w") as f: 46 | json.dump(j, f, indent=2) 47 | 48 | def remove_edge(path, edge): 49 | _validate(path) 50 | with open(path, "r") as f: 51 | j = json.load(f) 52 | assert edge in j["E"], "edge not present" 53 | j["E"].remove(edge) 54 | with open(path, "w") as f: 55 | json.dump(j, f, indent=2) 56 | 57 | def add_node(path, node): 58 | _validate(path) 59 | with open(path, "r") as f: 60 | j = json.load(f) 61 | if node not in j["V"]: 62 | j["V"].append(node) 63 | with open(path, "w") as f: 64 | json.dump(j, f, indent=2) 65 | 66 | def remove_node(path, node): 67 | _validate(path) 68 | with open(path, "r") as f: 69 | j = json.load(f) 70 | assert node in j["V"], "node not present" 71 | j["V"].remove(node) 72 | # delete associated Vdata and edges 73 | if node in j["Vdata"]: 74 | del j["Vdata"][node] 75 | for edge in j["E"]: 76 | if edge[0] == node or edge[1] == node: 77 | edges.remove(edge) 78 | with open(path, "w") as f: 79 | json.dump(j, f, indent=2) 80 | 81 | def alter_vdata(path, node): 82 | _validate(path) 83 | with open(path, "r") as f: 84 | j = json.load(f) 85 | assert node in j["V"], "node not present" 86 | print("Current node data: ") 87 | print("------------------ ") 88 | try: 89 | print(json.dumps(j["Vdata"][node], indent=2)) 90 | except KeyError: 91 | print("[uninitialized! you may create this node data]") 92 | print("enter new node data: ") 93 | while (1): 94 | try: 95 | minij = json.load(sys.stdin) 96 | break 97 | except: 98 | print("malformatted json, try again:") 99 | j["Vdata"][node] = minij 100 | with open(path, "w") as f: 101 | json.dump(j, f, indent=2) 102 | 103 | def refresh(path): 104 | """updates ord, numoutcomes, parents, and children in vdata""" 105 | with open(path, "r") as f: 106 | d = json.load(f) 107 | 108 | # topologically order vertices 109 | Ecopy = [x[:] for x in d["E"]] 110 | roots = [] 111 | toporder = [] 112 | 113 | for vertex in d["V"]: 114 | # find roots 115 | roots = d["V"][:] 116 | for e in Ecopy: 117 | try: 118 | roots.remove(e[1]) 119 | except: 120 | pass 121 | 122 | while roots != []: 123 | n = roots.pop() 124 | toporder.append(n) 125 | for edge in reversed(Ecopy): 126 | if edge[0] == n: 127 | m = edge[1] 128 | Ecopy.remove(edge) 129 | yesparent = False 130 | for e in Ecopy: 131 | if e[1] == m: 132 | yesparent = True 133 | break 134 | if yesparent == False: 135 | roots.append(m) 136 | assert (not Ecopy), ("Graph contains a cycle", Ecopy) 137 | d["V"] = toporder 138 | 139 | # clear attributes 140 | for entry in d["Vdata"]: 141 | d["Vdata"][entry]["parents"] = None 142 | d["Vdata"][entry]["children"] = None 143 | d["Vdata"][entry]["numoutcomes"] = len(d["Vdata"][entry]["vals"]) 144 | d["Vdata"][entry]["ord"] = d["V"].index(entry) 145 | 146 | # make parents and children 147 | for edge in d["E"]: 148 | parent = edge[0] 149 | child = edge[1] 150 | 151 | if d["Vdata"][child]["parents"] == None: 152 | d["Vdata"][child]["parents"] = [] 153 | if parent not in d["Vdata"][child]["parents"]: 154 | d["Vdata"][child]["parents"].append(parent) 155 | 156 | if d["Vdata"][parent]["children"] == None: 157 | d["Vdata"][parent]["children"] = [] 158 | if child not in d["Vdata"][parent]["children"]: 159 | d["Vdata"][parent]["children"].append(child) 160 | 161 | with open(path, "w") as f: 162 | json.dump(d, f, indent=2) 163 | 164 | def _validate(path): 165 | # is json correctly formatted? 166 | try: 167 | with open(path) as f: 168 | json.load(f) 169 | except: 170 | raise Exception("The network file you are trying to modify is invalid") 171 | 172 | # do the nodes match the node data? 173 | with open(path) as f: 174 | j = json.load(f) 175 | if not (sorted(j["V"]) == sorted(j["Vdata"].keys())): 176 | print("warning: nodes and node data do not match") 177 | 178 | # are the edges valid? 179 | for e in j["E"]: 180 | if (e[0] not in j["V"]) or (e[1] not in j["V"]): 181 | print("warning: nodes not found for this edge:") 182 | print(e) 183 | 184 | -------------------------------------------------------------------------------- /utils/libpgmexceptions.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright 2013 CyberPoint International, LLC. 3 | All rights reserved. Use and disclosure prohibited 4 | except as permitted in writing by CyberPoint. 5 | 6 | libpgm exception handler 7 | 8 | Charlie Cabot 9 | Sept 27 2013 10 | 11 | ''' 12 | class libpgmError(Exception): 13 | pass 14 | 15 | class bntextError(libpgmError): 16 | pass 17 | --------------------------------------------------------------------------------