Package: pybdm
The Block Decomposition Method (BDM) approximates algorithmic complexity
of a dataset of arbitrary size, that is, the length of the shortest computer
program that generates it. This is not trivial as algorithmic complexity
is not a computable quantity in the general case and estimation of
algorithmic complexity of a dataset can be very useful as it points to
mechanistic connections between elements of a system, even such that
do not yield any regular statistical patterns that can be captured with
more traditional tools based on probability theory and information theory.Currently 1D and 2D binary arrays are supported, as well as 1D arrays
with 4, 5, 6 and 9 discrete symbols.BDM and the necessary parts of the algorithmic information theory
it is based on are described inthis article.See the officialdocumentationfor more information.InstallationStandard installation (stable):pip install pybdmDevelopment version installation:pip install git+https://github.com/sztal/pybdm.gitLocal development:git clone https://github.com/sztal/pybdm
cd pybdm
pip install --editable .Supported versionsPython3.5+ is supported. Tests are run against Linux, but
Windows and OSX should work as well.UsageThe BDM is implemented using the object-oriented approach and expects
input represented asNumpyarrays of integer type.BDMobjects operate exclusively oninteger arrays.
Hence, any alphabet must be first mapped to a set of integers ranging
from0tok.Detailed usage examples can be found in the officialdocumentation.Binary sequences (1D)importnumpyasnpfrompybdmimportBDM# Create a dataset (must be of integer type)X=np.ones((100,),dtype=int)# Initialize BDM object# ndim argument specifies dimensionality of BDMbdm=BDM(ndim=1)# Compute BDMbdm.bdm(X)# BDM objects may also compute standard Shannon entropy in base 2bdm.ent(X)Binary matrices (2D)importnumpyasnpfrompybdmimportBDM# Create a dataset (must be of integer type)X=np.ones((100,100),dtype=int)# Initialize BDM objectbdm=BDM(ndim=2)# Compute BDMbdm.bdm(X)# BDM objects may also compute standard Shannon entropy in base 2bdm.ent(X)Non-binary sequences (1D)importnumpyasnpfrompybdmimportBDM# Create a dataset (4 discrete symbols)np.random.seed(303)X=np.random.randint(0,4,(100,))# Initialize BDM object with 4-symbols alphabetbdm=BDM(ndim=1,nsymbols=4)# Compute BDMbdm.bdm(X)Parallel processingPyBDMwas designed with parallel processing in mind.
Using modern packages for parallelization such asjoblibmakes it really easy to compute BDM for massive objects.In this example we will slice a 1000x1000 dataset into 200x200 pieces
compute so-called counter objects (final BDM computation operates on such objects)
in parallel in 4 independent processes, and aggregate the results
into a single BDM approximation of the algorithmic complexity of the dataset.Remember that data has to be sliced correctly during parallelization
in order to ensure fully correct BDM computations. That is, all slices
except lower and right boundaries have to be decomposable without
any boundary leftovers by the selected decomposition algorithm.importnumpyasnpfromjoblibimportParallel,delayedfrompybdmimportBDMfrompybdm.utilsimportdecompose_dataset# Create a dataset (must be of integer type)X=np.ones((1000,1000),dtype=int)# Initialize BDM objectbdm=BDM(ndim=2)# Compute counter objects in parallelcounters=Parallel(n_jobs=4)\(delayed(bdm.decompose_and_count)(d)fordindecompose_dataset(X,(200,200)))# Compute BDMbdm.compute_bdm(*counters)Perturbation analysisBesides the mainBlock Decomposition MethodimplementationPyBDMprovides
also an efficient algorithm for perturbation analysis based onBDM(or standard Shannon entropy).A perturbation experiment studies change ofBDM/ entropy under changes
applied to the underlying dataset. This is the main tool for detecting
parts of a system having some causal significance as opposed
to noise parts.Parts which after yield negative contribution to the overall
complexity after change are likely to be important for the system,
since their removal make it more noisy. On the other hand parts that yield
positive contribution to the overall complexity after change are likely
to be noise since they extend the system’s description length.importnumpyasnpfrompybdmimportBDMfrompybdm.algorithmsimportPerturbationExperiment# Create a dataset (must be of integer type)X=np.ones((100,100),dtype=int)# Initialize BDM objectbdm=BDM(ndim=2)# Initialize perturbation experiment object# (may be run for both bdm or entropy)perturbation=PerturbationExperiment(bdm,X,metric='bdm')# Compute BDM change for all data pointsdelta_bdm=perturbation.run()# Compute BDM change for selected data points and keep the changes while running# One array provide indices of elements that are to be change.idx=np.array([[0,0],[10,10]],dtype=int)# Another array provide new values to assign.# Negative values mean that new values will be selected# randomly from the set of other possible values from the alphabet.values=np.array([-1,-1],dtype=int)delta_bdm=perturbation.run(idx,values,keep_changes=True)Authors & ContactSzymon Talaga <stalaga@protonmail.com>Kostas Tsampourakis <kostas.tsampourakis@gmail.com>DocumentationThe full documentation is athttp://pybdm-docs.rtfd.org.History0.1.0 (2019-09-22)First release on PyPI.