{ "info": { "author": "Carlo Nicolini", "author_email": "carlo.nicolini@iit.it", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6" ], "description": "# Networkqit: spectral entropies of complex networks\n\nAn information theoretic approach inspired by quantum statistical mechanics was recently proposed as a means to optimize network models and to assess their likelihood against synthetic and real-world networks.\nImportantly, this method does not rely on specific topological features or network descriptors, but leverages entropy-based measures of network distance.\nEntertaining the analogy with thermodynamics, **networkqit** provides a computational tool for the estimate of spectral entropy and fitting of model parameters.\nThese results enable the practical application of this novel and powerful framework to network model inference.\n\n\n## Documentation\n\nThe full documentation for this package under development and is currently being written, its current version is available at:\n\n
\n\n## Installation\n\nTo use the **networkqit** package we suggest to use `virtualenv`.\nThe **networkqit** package is pure Python, so it should work on Linux, Mac OSX and Windows.\nHere we report instructions for usage in a standard Ubuntu linux installation.\n\n## How to install on Linux\n\n1. Open a terminal, install `pip` and `virtualenv` and clone this repository\n \n```bash\nsudo apt-get install python3-pip\nsudo pip3 install virtualenv\nvirtualenv workspace\ncd workspace\ngit clone https://github.com/carlonicolini/networkqit\n```\n \n2. You cloned the repository. Now start the virtualenv session.\n \n```bash\nsource bin/activate\n```\n\n3. If you are inside the `virtualenv` session, check that the Python version you are using is the one provided by `virtualenv`.\n\n```bash\nwhich python3\n```\n\n4. Now install the networkqit package within the `virtualenv` environment.\n\n```bash\ncd networkqit\npython3 setup.py sdist\n```\n\nNow install the created Python package, that should come with all its dependencies `matplotlib`, `numpy`, `networkx`, `pandas`, `numdifftools`, `bctpy`\n\n```bash\ncd ..\npip3 install networkqit/dist/networkqit-0.1.tar.gz \n```\n\n# Getting started\nHere we discuss how to use **networkqit**.\n\n## Computing the spectral entropy of a network\n\nLet us start by studying the spectral entropy of the density matrix of the famous karate club graph.\nThis example shows how to generate the spectral entropy plots shown in our main paper.\n\n```python\nimport networkx as nx\nG = nx.karate_club_graph()\nA = nx.to_numpy_array(G)\nimport networkqit as nq\nimport numpy as np\nimport matplotlib.pyplot as plt\nplt.style.use('ggplot')\nbeta_range = np.logspace(-3,3,200)\nSbeta = nq.batch_compute_vonneumann_entropy(L=nq.graph_Laplacian(A),beta_range=beta_range)\nplt.semilogx(beta_range, Sbeta)\nplt.xlabel('$\\\\beta$')\nplt.ylabel('$S$')\nplt.title('Unnormalized spectral entropy')\nplt.show()\n```\n\nThe spectral entropy is always in the range `[0, log(N)]`, so if we simply divide by `log N` where $N$ is the number\nof nodes, we renormalize it in the `[0,1]` range.\n\n## Generative network models\n\n**networkqit** features a large number of network models, mainly those obtained from within the Maximum Entropy\nframework. You can create a number of models and call methods on them by a consistent nomenclature:\nHere we create an instance of the Undirected Binary Configuration model (UBCM), and sample 10 random networks from this\nensemble, based on the fitness parameters `x_i` created at random in the `[0,1]` domain.\n\n```python\nimport networkqit as nq\nN=10\nmodel = nq.UBCM(N=10)\nxi = np.random.random([N,])\nadj_graphs = model.sample_adjacency(xi, batch_size=5)\nprint(adj_graphs.shape)\n```\n\nThe call returns a `[5,N,N]` numpy array, where the last two dimensions embed with the adjacency matrix of the 5 random graphs.\nThe method `sample_adjacency` is available for every generative model implemented in **networkqit** and is at the base of the *maximize and sample* approach used for the optimization of the spectral entropy. \n\n# Classical optimization of spectral entropies\n\nNetworkqit can also work with network model fitting. The utilities to define model optimization are defined in the `algorithms` package, and here we describe how to run model optimization in the non-sparse limit (the one discussed in the PRE paper).\n\nThe following lines describe an example of optimization of the expected Laplacian model.\nWe first create the object ErdosRenyi that describes the expected Laplacian, adjacency and Laplacian gradient with\nrespect to the only continuous parameters $p$.\n\n```python\nimport networkx as nx\nimport networkqit as nq\nimport numpy as np\nG = nx.karate_club_graph()\nA = nx.to_numpy_array(G)\nL = nq.graph_Laplacian(A)\nbeta_range = np.logspace(-3,3,20)\nermodel = nq.ErdosRenyi(N=len(A))\n```\n\nWe can call the `ermodel` as if it is a simple function:\n\n```python\nprint(ermodel([0.5]))\n```\n\nThis returns the expected adjacency matrix, a `34x34` matrix with `0.5` off diagonal and `0` on diagonal.\nThe `ermodel` also allows to call methods like the expected Laplacian or the expected Laplacian gradients:\n\n```python\nprint(ermodel.expected_Laplacian_grad([0.5]))\n```\n\nOtherwise we can sample 10 independent networks from the Erdos-Renyi model, with the method `sample_adjacency`:\n\n```python\nprint(ermodel.sample_adjacency([0.5]), batch_size=10)\n```\n\nOnce the `ermodel` object is defined, we can optimize its parameters in the spectral entropies framework with the help of the class `ContinuousOptimizer`.\nWe initialize the observed adjacency matrix as `A` and the initial solution `x0=np.array([0.2])`. It is important to define `x0` as a numpy array.\nFinally the `beta_range` is a numpy array with the range of `beta` over which to optimize the model.\n\n```python\nsolver = nq.ContinuousOptimizer(A=A, x0=np.array([0.2]), beta_range=beta_range)\nsolver.setup(ermodel, ermodel.expected_Laplacian_grad, step_callback=None)\nsol = solver.run()\nprint(sol)\n```\n\n## Stochastic optimization of spectral entropy\n\n\nMost of the models do not allow an analytical treatment of their spectral likelihood.\nThis involves knowing exact analytical formulations of the Laplacian eigenvalues spectral density and this is still an unsolved problem for most of the useful network models.\nTo perform spectral likelihood optimization we can do stochastic optimization and find the parameters of the empirical graph such that the expected relative entropy averaged over the model ensemble \nis minimized. \nDoing this in **networkqit** is simple, as the library relies on the `autograd` package for the automatic calculation of complicated gradients of stochastic functions.\n\nWith the optimization method `Adam` which is borrowed from machine learning, we can optimize the expected relative entropy of the Erdos-Renyi model with respect to our model karate-club network,represented by **A** and see the effects of changing the inverse temperature parameter `beta` on the optimization process.\n\nAt every iteration, a `batch_size` number of random networks are sampled from the model, and their average spectral properties are used to compute an approximation to the expected relative entropy.\nIn this example we see how to optimze a model with `N (N-1)` free Bernoulli random variables that describe links in a graph.\nAt each stage in the `for` loop we replot the result, compared with the original network. We sample at each iteration of Adam a number of 32 independent networks, in order to form a good statistic for the calculation of the Laplacian spectrum.\n\nThis is the result of this optimization loop. Look how the spectral entropies of the model approximates the one of the empirical network.\n\n```python\nimport matplotlib.pyplot as plt\nfrom autograd import numpy as np\nimport networkqit as nq\nfrom networkqit import Adam\nA = nq.ring_of_custom_cliques([24,12,8])\nN = len(A)\nM = nq.IsingModel(N=N)\nL = nq.graph_Laplacian(A)\nbeta = 1\nopt = Adam(G=A, L=L, x0=np.random.random([N*N,]), model=M)\nrho = nq.compute_vonneuman_density(L=L, beta=beta)\nfor rep in range(10):\n sol = opt.run(beta, learning_rate=1E-3, batch_size=32, maxiter=1000)\n nq.plot_mle(A, M.expected_adjacency(sol['x']))\n plt.show()\n```\n\n\n\n\n\n## Classical maximum likelihood estimation\n\n**networkqit** is also featuring a number of Maximum Entropy random graph models, from the soft-configuration model, to the Erdos-Renyi, the Weighted Random graph model and the Enhanced Configuration model.\nYou can simply fit these models onto empirical data, with a few calls.\nFor example here we fit the Lagrange multipliers of the Undirected Configuration Model onto an empirical network `A` and then sample 100 networks from the optimal values of this model:\n\n```python\nimport networkqit as nq\nA = nq.ring_of_custom_cliques([24,12,8])\nM = nq.UBCM(N=len(A)) # defines the model class\nsol = M.fit(G=A, ftol=1E-9)\nM.sample_adjacency(theta=sol['x'], batch_size=100)\n```\n\n\n\nIn this case we don't plot the expected weights, as this model supports only binary networks, but if you prefer, we can fit the Undirected Enhanced Configuration Model:\n\n```python\nimport networkqit as nq\nA = nq.ring_of_custom_cliques([24,12,8])\nM = nq.UECM3(N=len(A)) # defines the model class\nsol = M.fit(G=A, ftol=1E-9)\nM.sample_adjacency(theta=sol['x'], batch_size=100)\n```\n\n\n\nAs you can see using the Enhanced Configuration model, both the weights and the link probabilities are correctly fitted in the model, even if this network is unweighted.\n\n# Citing \nTo cite **networkqit** please include the following publication in BibTeX format:\n\n @article{PhysRevE.98.022322,\n title = {Thermodynamics of network model fitting with spectral entropies},\n author = {Nicolini, Carlo and Vlasov, Vladimir and Bifone, Angelo},\n journal = {Phys. Rev. E},\n volume = {98},\n issue = {2},\n pages = {022322},\n numpages = {10},\n year = {2018},\n month = {Aug},\n publisher = {American Physical Society},\n doi = {10.1103/PhysRevE.98.022322},\n url = {https://link.aps.org/doi/10.1103/PhysRevE.98.022322}\n }\n\nIt is also vailable [at this link ](https://journals.aps.org/pre/abstract/10.1103/PhysRevE.98.022322)\n\n# TODO\n\nI would like to find someone helping in implementing XLA instead of autograd as the basic package for automatic differentiation. Indeed XLA has the possibility to extend calculations on the GPU and (in future) on MultiGPU or TPU systems, effortlessly. It would be possible to scale to much larger problems.", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/carlonicolini/networkqit", "keywords": "networks complex graph theory entropy physics", "license": "", "maintainer": "", "maintainer_email": "", "name": "networkqit", "package_url": "https://pypi.org/project/networkqit/", "platform": "", "project_url": "https://pypi.org/project/networkqit/", "project_urls": { "Homepage": "https://github.com/carlonicolini/networkqit" }, "release_url": "https://pypi.org/project/networkqit/0.20.0/", "requires_dist": null, "requires_python": "", "summary": "A package for fitting spectral entropies of complex networks", "version": "0.20.0" }, "last_serial": 5395965, "releases": { "0.13.2": [ { "comment_text": "", "digests": { "md5": "0a99d06126e2fa6cf022e44162b6cf78", "sha256": "70abde524e6bb24ae92552d76f4770a14ade3c9d37e141a06b5776c1734136dc" }, "downloads": -1, "filename": "networkqit-0.13.2.tar.gz", "has_sig": false, "md5_digest": "0a99d06126e2fa6cf022e44162b6cf78", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27599, "upload_time": "2018-11-12T15:16:17", "url": "https://files.pythonhosted.org/packages/f6/40/48d95bc6f1472bc3f8d6323e9dafa53eb7e1d7d23cb73e9a9b106c4e9487/networkqit-0.13.2.tar.gz" } ], "0.20.0": [ { "comment_text": "", "digests": { "md5": "aa533443d7a13cb34de263e6509522e3", "sha256": "a71873a8016218d6064d617f852c94369341b2afd63b76ff99f12e62c0f2fa09" }, "downloads": -1, "filename": "networkqit-0.20.0.tar.gz", "has_sig": false, "md5_digest": "aa533443d7a13cb34de263e6509522e3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 56109, "upload_time": "2019-06-13T13:38:14", "url": "https://files.pythonhosted.org/packages/33/c5/24a407720fecce51f72f687dac2778d50fa4830be66145560922fc921027/networkqit-0.20.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "aa533443d7a13cb34de263e6509522e3", "sha256": "a71873a8016218d6064d617f852c94369341b2afd63b76ff99f12e62c0f2fa09" }, "downloads": -1, "filename": "networkqit-0.20.0.tar.gz", "has_sig": false, "md5_digest": "aa533443d7a13cb34de263e6509522e3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 56109, "upload_time": "2019-06-13T13:38:14", "url": "https://files.pythonhosted.org/packages/33/c5/24a407720fecce51f72f687dac2778d50fa4830be66145560922fc921027/networkqit-0.20.0.tar.gz" } ] }