Giter VIP home page Giter VIP logo

hypernetx's Introduction

HyperNetX

Pytest Code style: black linting: pylint

The HyperNetX library provides classes and methods for the analysis and visualization of complex network data modeled as hypergraphs. The library generalizes traditional graph metrics.

HypernetX was developed by the Pacific Northwest National Laboratory for the Hypernets project as part of its High Performance Data Analytics (HPDA) program. PNNL is operated by Battelle Memorial Institute under Contract DE-ACO5-76RL01830.

  • Principal Developer and Designer: Brenda Praggastis
  • Development Team: Audun Myers, Mark Bonicillo
  • Visualization: Dustin Arendt, Ji Young Yun
  • Principal Investigator: Cliff Joslyn
  • Program Manager: Brian Kritzstein
  • Principal Contributors (Design, Theory, Code): Sinan Aksoy, Dustin Arendt, Mark Bonicillo, Helen Jenne, Cliff Joslyn, Nicholas Landry, Audun Myers, Christopher Potvin, Brenda Praggastis, Emilie Purvine, Greg Roek, Mirah Shi, Francois Theberge, Ji Young Yun

The code in this repository is intended to support researchers modeling data as hypergraphs. We have a growing community of users and contributors. Documentation is available at: https://pnnl.github.io/HyperNetX

For questions and comments contact the developers directly at: [email protected]

New Features in Version 2.0

HNX 2.0 now accepts metadata as core attributes of the edges and nodes of a hypergraph. While the library continues to accept lists, dictionaries and dataframes as basic inputs for hypergraph constructions, both cell properties and edge and node properties can now be easily added for retrieval as object attributes.

The core library has been rebuilt to take advantage of the flexibility and speed of Pandas Dataframes. Dataframes offer the ability to store and easily access hypergraph metadata. Metadata can be used for filtering objects, and characterize their distributions by their attributes.

Version 2.0 is not backwards compatible. Objects constructed using version 1.x can be imported from their incidence dictionaries.

What's New

  1. The Hypergraph constructor now accepts nested dictionaries with incidence cell properties, pandas.DataFrames, and 2-column Numpy arrays.
  2. Additional constructors accept incidence matrices and incidence dataframes.
  3. Hypergraph constructors accept cell, edge, and node metadata.
  4. Metadata available as attributes on the cells, edges, and nodes.
  5. User-defined cell weights and default weights available to incidence matrix.
  6. Meta data persists with restrictions and removals.
  7. Meta data persists onto s-linegraphs as node attributes of Networkx graphs.
  8. New hnxwidget available using pip install hnxwidget.

What's Changed

  1. The static and dynamic distinctions no longer exist. All hypergraphs use the same underlying data structure, supported by Pandas dataFrames. All hypergraphs maintain a state_dict to avoid repeating computations.
  2. Methods for adding nodes and hyperedges are currently not supported.
  3. The nwhy optimizations are no longer supported.
  4. Entity and EntitySet classes are being moved to the background. The Hypergraph constructor does not accept either.

Tutorials

Google Colab

Open In Colab Tutorial 1 - HNX Basics
Open In Colab Tutorial 2 - Visualization Methods
Open In Colab Tutorial 3 - LesMis Case Study
Open In Colab Tutorial 4 - LesMis Visualizations-Book Tour
Open In Colab Tutorial 5 - s-Centrality
Open In Colab Tutorial 6 - Homology mod2 for TriLoop Example

Jupyter Notebooks

Additional tutorials that can be run as Jupyter Notebooks are found under tutorials.

Installation

The recommended installation method for most users is to create a virtual environment and install HyperNetX from PyPi.

HyperNetX may be cloned or forked from Github.

Prerequisites

HyperNetX officially supports Python 3.8, 3.9, 3.10 and 3.11.

Create a virtual environment

Using venv

python -m venv venv-hnx
source venv-hnx/bin/activate

Using Anaconda

conda create -n venv-hnx python=3.11 -y
conda activate venv-hnx

Using virtualenv

virtualenv venv-hnx
source venv-hnx/bin/activate

For Windows Users

On both Windows PowerShell or Command Prompt, you can use the following command to activate your virtual environment:

.\env-hnx\Scripts\activate

To deactivate your environment, use:

.\env-hnx\Scripts\deactivate

Installing HyperNetX

Regardless of how you install HyperNetX, ensure that your environment is activated and that you are running Python >=3.8.

Installing from PyPi

pip install hypernetx

Installing from Source

Ensure that you have git installed.

git clone https://github.com/pnnl/HyperNetX.git
cd HyperNetX
make venv
source venv-hnx/bin/activate
pip install .

Development

Install an editable version

pip install -e .

Install an editable version with supported applications

pip install -e .['all']

# for zsh users
pip install -e .'[all]'

Install support for testing

ℹī¸ NOTE: This project has a pytest configuration file named 'pytest.ini'. By default, pytest will use those configuration settings to run tests.

make test-deps

# run tests
python -m pytest

# run tests and show coverage report
python -m pytest --cov=hypernetx

# Generate an HTML code coverage report and view it on a browser
coverage html
open htmlcov/index.html

Install support for tutorials

make tutorial-deps

# open Jupyter notebooks in a browser
make tutorials

Code Quality

HyperNetX uses a number of tools to maintain code quality:

  • Pylint
  • Black

Before using these tools, ensure that you install Pylint in your environment:

make lint-deps

Pylint

Pylint is a static code analyzer for Python-based projects. From the Pylint docs:

Pylint analyses your code without actually running it. It checks for errors, enforces a coding standard, looks for code smells, and can make suggestions about how the code could be refactored. Pylint can infer actual values from your code using its internal code representation (astroid). If your code is import logging as argparse, Pylint will know that argparse.error(...) is in fact a logging call and not an argparse call.

To run Pylint and view the results of Pylint, run the following command:

pylint hypernetx

You can also run Pylint on the command line to generate a report on the quality of the codebase and save it to a file named "pylint-results.txt":

pylint hypernetx --output=pylint-results.txt

For more information on configuration, see https://pylint.pycqa.org/en/latest/user_guide/configuration/index.html

Black

Black is a PEP 8 compliant formatter for Python-based project. This tool is highly opinionated about how Python should be formatted and will automagically reformat your code.

make format-deps
black hypernetx

Documentation

Build and view documentation locally

make docs-deps
cd docs
make html
open docs/build/html/index.html

Editing documentation

When editing documentation, you can auto-rebuild the documentation locally so that you can view your document changes live on the browser without having to rebuild every time you have a change.

make docs-deps
cd docs
make livehtml

This make script will run in the foreground on your terminal. You should see the following:

The HTML pages are in docs/html.
[I 230324 09:50:48 server:335] Serving on http://127.0.0.1:8000
[I 230324 09:50:48 handlers:62] Start watching changes
[I 230324 09:50:48 handlers:64] Start detecting changes
[I 230324 09:50:54 handlers:135] Browser Connected: http://127.0.0.1:8000/install.html
[I 230324 09:51:02 handlers:135] Browser Connected: http://127.0.0.1:8000/

Click on http://127.0.0.1:8000/install.html to open the docs on your browser. Since this will auto-rebuild, every time you change a document file, it will automatically render on your browser, allowing you to verify your document changes.

Continuous Integration

This project runs Continuous Integration (CI) using GitHub Actions. Normally, CI runs on pull requests, pushes to certain branches, and other events.

Maintainers of the GitHub repository can manually trigger CI using GitHub CLI. See instructions below on how to manually trigger CI on GitHub Actions:

# login to Github
gh auth login --with-token <  ~/.ssh/tokens/<path to my personal access token>

# Trigger CI
gh workflow run ci.yml --repo pnnl/HyperNetX --ref <name of branch that you want CI to run on> --field triggeredBy="<Your name>"

# Get the status of the workflow
gh run list --workflow=ci.yml --repo pnnl/HyperNetX

Versioning

This project uses commitizen to manage versioning. The files where "version" will be updated are listed in the '.cz.toml' file. To create a new version and the associated tag, run the following commands:

# Install commitizen tool to environment
make version-deps

# Updates version; values for '--increment' can be MAJOR, MINOR, or PATCH
# Autocreates a tag and commit for the updated version
cz bump  --increment MAJOR  --dry-run
cz bump  --increment MAJOR

Notice

This material was prepared as an account of work sponsored by an agency of the United States Government. Neither the United States Government nor the United States Department of Energy, nor Battelle, nor any of their employees, nor any jurisdiction or organization that has cooperated in the development of these materials, makes any warranty, express or implied, or assumes any legal liability or responsibility for the accuracy, completeness, or usefulness or any information, apparatus, product, software, or process disclosed, or represents that its use would not infringe privately owned rights. Reference herein to any specific commercial product, process, or service by trade name, trademark, manufacturer, or otherwise does not necessarily constitute or imply its endorsement, recommendation, or favoring by the United States Government or any agency thereof, or Battelle Memorial Institute. The views and opinions of authors expressed herein do not necessarily state or reflect those of the United States Government or any agency thereof.

   PACIFIC NORTHWEST NATIONAL LABORATORY
   operated by
   BATTELLE
   for the
   UNITED STATES DEPARTMENT OF ENERGY
   under Contract DE-AC05-76RL01830
   

License

Released under the 3-Clause BSD license (see License.rst)

hypernetx's People

Contributors

bonicim avatar bpraggastis avatar brendapraggastis avatar dlarendt avatar ftheberge avatar ghproek avatar hagberg avatar madelynshapiro avatar nicolburatti avatar noah-farris avatar sinangaksoy avatar szhorvat avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hypernetx's Issues

Hyperedges incorrectly being drawn around all nodes

When drawing a hypergraph with 95 nodes and 154 edges, many hyperedges are incorrectly encircling all of the 95 nodes. See the example provided below where no edges contain more than 3 nodes, but most of the 154 hyperedges are being drawn around all nodes.

Output:
hypernetx_error

Output (cropped):
hypernetx_error_cropped

import matplotlib.pyplot as plt
from hypernetx import *

edges = [
    ["10000546","10040991","10040998"],
    ["10000546","10040991","10043739"],
    ["10001708","10006436","10040991"],
    ["10001708","10021877","10040991"],
    ["10001708","10040991","10040998"],
    ["10001708","10040991","10046304"],
    ["10002086","10040991","10040998"],
    ["10002861","10040991","10040998"],
    ["10003018","10018073","10040991"],
    ["10003018","10040991","10040998"],
    ["10003216","10007963","10040991"],
    ["10003216","10011082","10040991"],
    ["10003216","10040991","10040998"],
    ["10003216","10040991","10057166"],
    ["10003816","10010761","10040991"],
    ["10003816","10012303","10040991"],
    ["10003816","10023213","10040991"],
    ["10003816","10040991","10040998"],
    ["10004994","10040991","10040998"],
    ["10004994","10040991","10041543"],
    ["10005908","10017977","10040991"],
    ["10005908","10018073","10040991"],
    ["10005908","10040991","10040998"],
    ["10005959","10013296","10040991"],
    ["10005959","10040991","10040998"],
    ["10006232","10006291","10040991"],
    ["10006232","10040991","10040998"],
    ["10006291","10040991","10040998"],
    ["10006436","10040991","10040998"],
    ["10007521","10040991","10040998"],
    ["10007963","10040991","10040998"],
    ["10009841","10040991","10040998"],
    ["10010761","10014982","10040991"],
    ["10010761","10040991","10040998"],
    ["10011082","10018073","10040991"],
    ["10011082","10040991","10040998"],
    ["10011082","10040991","10057166"],
    ["10011082","10040991","10079101"],
    ["10011954","10029305","10040991"],
    ["10011954","10040991","10040998"],
    ["10011954","10040991","10082206"],
    ["10012272","10040991","10040998"],
    ["10012272","10040991","10057167"],
    ["10012303","10040991","10040998"],
    ["10012375","10040991","10040998"],
    ["10012653","10034606","10040991"],
    ["10013296","10040991","10040998"],
    ["10013317","10040991","10040998"],
    ["10013317","10040991","10057166"],
    ["10014412","10017977","10040991"],
    ["10014412","10018073","10040991"],
    ["10014412","10038430","10040991"],
    ["10014412","10040991","10040998"],
    ["10014523","10040991","10040998"],
    ["10014982","10027665","10040991"],
    ["10014982","10040991","10040998"],
    ["10015917","10040991","10040998"],
    ["10017528","10017977","10040991"],
    ["10017528","10040991","10040998"],
    ["10017943","10040991","10040998"],
    ["10017969","10027665","10040991"],
    ["10017969","10040991","10040998"],
    ["10017977","10018027","10040991"],
    ["10017977","10018188","10040991"],
    ["10017977","10031013","10040991"],
    ["10017977","10040991","10040998"],
    ["10017977","10040991","10077546"],
    ["10017990","10017991","10040991"],
    ["10017990","10040991","10040998"],
    ["10017991","10040991","10040998"],
    ["10018012","10018073","10040991"],
    ["10018012","10040991","10040998"],
    ["10018027","10040991","10040998"],
    ["10018073","10019280","10040991"],
    ["10018073","10022114","10040991"],
    ["10018073","10040991","10040998"],
    ["10018073","10040991","10047066"],
    ["10018073","10040991","10068775"],
    ["10018073","10040991","10069888"],
    ["10018073","10040991","10074469"],
    ["10018073","10040991","10079101"],
    ["10018188","10021879","10040991"],
    ["10018188","10040991","10040998"],
    ["10018307","10040991","10040998"],
    ["10018424","10040991","10040998"],
    ["10018424","10040991","10057166"],
    ["10019231","10040991","10040998"],
    ["10019231","10040991","10047066"],
    ["10019280","10040991","10040998"],
    ["10019280","10040991","10057166"],
    ["10019654","10040991","10040998"],
    ["10019654","10040991","10047438"],
    ["10021877","10040991","10040998"],
    ["10021877","10040991","10046304"],
    ["10021879","10024970","10040991"],
    ["10021879","10040991","10040998"],
    ["10022114","10029305","10040991"],
    ["10022114","10040991","10040998"],
    ["10022396","10029305","10040991"],
    ["10022958","10040991","10040998"],
    ["10023213","10037546","10040991"],
    ["10023213","10040991","10040998"],
    ["10024324","10040991","10040998"],
    ["10024967","10040991","10040998"],
    ["10024970","10040991","10040998"],
    ["10025320","10040991","10040998"],
    ["10026753","10040991","10040998"],
    ["10027665","10040991","10040998"],
    ["10027946","10040991","10040998"],
    ["10028037","10040991","10040998"],
    ["10028302","10029317","10040991"],
    ["10028302","10040991","10040998"],
    ["10028377","10040991","10040998"],
    ["10028393","10040991","10040998"],
    ["10029107","10038666","10040991"],
    ["10029107","10040991","10040998"],
    ["10029305","10040991","10040998"],
    ["10029317","10040991","10040998"],
    ["10031013","10040991","10040998"],
    ["10033283","10038594","10040991"],
    ["10033283","10040991","10040998"],
    ["10034606","10040991","10040998"],
    ["10035227","10040991","10040998"],
    ["10037454","10038716","10040991"],
    ["10037454","10040991","10040998"],
    ["10037454","10040991","10057166"],
    ["10037546","10040991","10040998"],
    ["10037546","10040991","10057166"],
    ["10038430","10040991","10040998"],
    ["10038594","10040991","10040998"],
    ["10038666","10040991","10040998"],
    ["10038716","10040991","10040998"],
    ["10039628","10040991","10040998"],
    ["10039911","10040991","10040998"],
    ["10040792","10040991","10040998"],
    ["10040792","10040991","10047438"],
    ["10040798","10040991","10040998"],
    ["10040991","10040998"],
    ["10040991","10040998","10041543"],
    ["10040991","10040998","10043739"],
    ["10040991","10040998","10046304"],
    ["10040991","10040998","10046590"],
    ["10040991","10040998","10047066"],
    ["10040991","10040998","10047438"],
    ["10040991","10040998","10047635"],
    ["10040991","10040998","10057166"],
    ["10040991","10040998","10057167"],
    ["10040991","10040998","10068775"],
    ["10040991","10040998","10069888"],
    ["10040991","10040998","10074469"],
    ["10040991","10040998","10077546"],
    ["10040991","10040998","10079101"],
    ["10040991","10040998","10082206"],
    ["10040991","10047066","10074469"]
]

hpgph = Hypergraph(edges)

plt.figure(figsize=(80, 80))
draw(hpgph, ax=plt.subplot(111), with_edge_labels=True)

[joss] Documentation example does not complete after > 5 min runtime

First of all, I must say that it is very nice that the documentation of several functions comes with examples.

However, one of the first examples I tried did not complete after more than a 5 minute runtime (M2 MacBook Pro):

https://hypernetx.readthedocs.io/en/latest/algorithms/algorithms.html#algorithms.contagion.contagion_animation

When an example takes a very long time to run, this should be noted in the docs.

Ref: openjournals/joss-reviews#6016

No edge or node properties in static hypergraphs

I would like to store some edge properties. For hypernetx > 1.1 this should work.

For

H = hnx.Hypergraph()
H.add_edge(hnx.Entity('e1', {1, 2}, p='a property'))
H.edges['e1'].properties['p'] # returns 'a property'

I get what I expect. But for static hypergraphs, there are no properties:

H_static = H.convert_to_static(name='static')
H_static.edges.props # return {}

Am I doing something wrong?

add_edge and add_node_to_edge not included in Hypergraph class

Hello,
I am trying to manually add edges to a hypergraph 'H'. First, I tried H.edges.add(), but it didn't show it in the edges list. I then read the documentation and in entity.py it says to use Hypergraph.add_edge or Hypergraph.add_node_to_edge instead, but none of the two is defined in the Hypergraph class, so they are not callable by H. Am I missing something?

add_node_to_edge does not update the node's membership

When adding an existing node to an existing edge, the memberships property of the node stored in _nodes is not updated

Code to reproduce the issue:

system = hnx.Hypergraph()
edge0 = hnx.Entity('edge0')
edge1 = hnx.Entity('edge1')
node0 = hnx.Entity('node0')
node1 = hnx.Entity('node1')

system.add_edge(edge0)
system.add_edge(edge1)
system.add_node_to_edge(node0,edge0)
system.add_node_to_edge(node0,edge1)
system.add_node_to_edge(node1,edge1)

#Memberships seen from the nodes stored within _edges
print("Memberships seen from the nodes stored within _edges")
for el in system.edges:
    for edge in system.edges[el]:
        print(edge,system.edges[el][edge].memberships)
        
#Memberships seen from the nodes stored within _nodes
print("Memberships seen from the nodes stored within _nodes")
for el in system.nodes:
    print(el,system.nodes[el].memberships)

hnx.drawing.rubber_band.draw(system)

TeX in docstrings causes DeprecationWarning.

Describe the bug

On Python 3.11 when i import hypernetx i get a few warnings:

>>> import hypernetx as hnx
/Users/drj/prj/HyperNetX/hypernetx/algorithms/homology_mod2.py:1: DeprecationWarning: invalid escape sequence '\{'
  """
/Users/drj/prj/HyperNetX/hypernetx/algorithms/homology_mod2.py:544: DeprecationWarning: invalid escape sequence '\m'
  """
/Users/drj/prj/HyperNetX/hypernetx/algorithms/homology_mod2.py:737: DeprecationWarning: invalid escape sequence '\{'
  """
/Users/drj/prj/HyperNetX/hypernetx/algorithms/laplacians_clustering.py:42: DeprecationWarning: invalid escape sequence '\g'
  """

These are causes by the TeX code appearing inside Python docstrings. Probably the simplest approach would be to make the docstrings raw by changing """ to r""" at the beginning of the affected docstrings [edit: as has been done in s_centrality_measures.py for example].

In addition the affected docstring in laplacians_clustering.py looks like it needs some dollar signs, but i am not familiar with your post-processing documentation tools.

Whilst i found this during my review for JOSS, i do not require it to be fixed for acceptance.

Environment (please complete the following information):

  • macOS Darwin 20.6.0
  • Python 3.11.4 (main, Jun 20 2023, 16:52:35) [Clang 13.0.0 (clang-1300.0.29.30)] on darwin

Nodes in a Hypergarph via H.nodes

I tried to generate a hypergraph using node neighborhood information from a matrix K of size |N| x |N|. Using the simple graph edges list, if the length (distance) of two given nodes is less than or equal to k, then I put 1 in the K matrix, 0 otherwise. 1 denotes that the two given nodes are neighbors, and 0 denotes that nodes are not neighbors. After generating the K matrix, I used it to represent hyperedges where each row of K represents the neighborhood of a particular node. (a hyperedge).

The problem is, after generating a hypergraph, it shows the correct number of hyperedges using the H.edges method, however, it gives the wrong number of nodes using the H.nodes method. The total nodes are very less than the total nodes given by the H.nodes method,

Also, I tried the example graph given in the documentation of the library. It has 13 nodes and 8 hyperedges. H.nodes and H.edges methods show the correct number of nodes and edges for this graph.

Can't I use the defined K matrix for hypergraph generation?

is there an efficient way to construct a large hypergraph?

I'm trying to build a hypergraph which has ~3.8M nodes and ~7.1M hyperedges.

My first attempt was to build a dictionary of edge -> nodelist so I could do a simple Hypergraph(dict) as per the docs, but that made no apparent progress.

I then tried to add the edges, then add the nodes. But after ~8 minutes I'm was only at 48000 edges and based on log output the process was getting markedly slower as the hypergraph grew.

I'm now trying an approach where I create a list of Entity objects then add them to an EntitySet, but that latter step has been going for many minutes now.

Skimming the code it seems like all of these bottom out in for loops that add elements, often with several uniqueness tests.

Is there an alternate construction method that I'm missing? Or am I just outside the design bounds trying to build a hypergraph this large?

[joss] Support forum available?

Does HyperNetX have a support forum or chatroom that is more appropriate for general discussion and usage questions than GitHub issues? Or do you prefer such questions to be asked in the issue tracker?

Modularity function returns error: AttributeError: 'Entity' object has no attribute 'strength'

When I call print('qH =',hmod.modularity(H, K, strict)) it returns AttributeError: 'Entity' object has no attribute 'strength'

The full code:

import igraph as ig
import hypernetx as hnx
import hypernetx.algorithms.hypergraph_modularity as hmod

H = hnx.Hypergraph(lookup)
H = hmod.precompute_attributes(H)
#%%
K = hmod.kumar(H)
#%%
strict = hmod.strict
## Compute qH
print('qH =',hmod.modularity(H, K, strict))

Lookup is a dictionary of the form: {key1 : (hedge1, hedge2...), key2 : (hedge1, hedge3...)}

hmod.precompute_attributes removes or does not remove singletons based off of the OS (inconsistent behaviour)

Depending on which OS is being used the following will print different results:

import hypernetx as hnx
import hypernetx.algorithms.hypergraph_modularity as hmod
formulaDict,stringTree = readFile("./CDL-FMINCE/toybox.dimacs") # code by me
H=formulaToHypergraph(formulaDict)
HDual = H.dual()
H=hmod.precompute_attributes(H)
HDual = hmod.precompute_attributes(HDual)

#this should diverge based off of OS

print(len(list(H.nodes())))
print(len(list(HDual.nodes())))

On the linux systems the results are 544 and 590, while on Windows I get 175 and 221. I suspect the singletons get removed by the attribute computation on windows, but not on the linux systems...

I was using ANTLR4 with python integration to parse a dimacs (SAT) file and interpret it as a hypergraph. The resulting graph has 544 nodes and 590 edges before the attributes are computed.

Compared Systems

Ubuntu system:

  • Ubuntu 20.04.6 LTS
  • wsl 2
  • Python 3.8.10
  • pip installation manager

Debian

  • SMP Debian 5.10.127-1
  • Python 3.9.2
  • pip installation manager

Windows

  • Windows 10 Home
  • Python 3.11.3
  • Anaconda virtual environment (+VSCode)

[joss] Improve class signatures in documentation

Is your feature request related to a problem? Please describe.

Currently, class signatures in the documentation are hard to read due to type annotations crowding:

Captura de tela de 2023-11-14 22-48-50

In the example above, there are so many type annotations that it is hard to find the second paramater data

Describe the solution you'd like

Because the parameters are already described in the docstring, I belive that hiding the type annotations would lead to a better documentation. Sometimes less is more. The parameters for the class constructors should be obvious.

Additional context

openjournals/joss-reviews#6016, I do not consider this issue blocking for acceptance. But it would be a good improvement

Support for weighted Hyperedges (Jan 2022)

Hi,
I understand that support for Weighted Hyperedges was asked in this issue.

However, the last question, was not answered. Could someone please answer it?

Additionally, has there been any update regarding the weighted hyperedges now that it is early 2022?

HypernetX specific warnings should be in hypernetx classes

Is your feature request related to a problem? Please describe.

As per Tutorial 1, calling edge_distance (H.edge_distance(4, 6, s=2)) can generate a warning.

A mild improvement would be to make the warning a specific class in hypernetx (as the Exceptions are); this gives finer control over warnings to users.

(i do not require this to be fixed for my JOSS review)

Can I adjust how close hyperedges can be drawn in proximity to nodes?

I made the following diagram using Hypernetworkx's draw command.

image

The node fst_score node appears really close to the 233 hyperedge, making it hard to distinguish whether the node is a member of the hyperedge. Is there a setting an argument somewhere that would allow me to ensure that the hyperedges maintain a minimal distance from the nodes?

Overlapping node labels

When drawing hypergraphs using the rubber band layout, node labels often overlap. This is especially prevalent when using longer strings as node labels; however, this problem also often occurs with very short labels as well. Due to the overlap, many labels are unreadable. Are there any settings within HyperNetX or Matplotlib to correct this? If not, are there any known workarounds? Thanks!

[joss] Can HNX represent isolated nodes?

Until #137 is answered, I'll just ask questions here. I hope that's okay.

Can HNX represent isolated nodes? If yes, how can I construct a hypergraph with isolated nodes? If not, can you point to the section of the docs that explains this? I'm sure I'm missing something.

I noticed that when removing edges using .remove_edges() (docs missing), nodes with no remaining incident edges also disappear.

Ref: openjournals/joss-reviews#6016

Import error on module hypernetx.utils.toys

Hello,
I have the following error when I try to import hypernetx on Colab (with your tutorials) and also on my conda env:

ModuleNotFoundError                       Traceback (most recent call last)
<ipython-input-3-b7c66bb90caa> in <module>()
      3 import matplotlib.pyplot as plt
      4 import networkx as nx
----> 5 import hypernetx as hnx
      6 

4 frames
/usr/local/lib/python3.7/dist-packages/hypernetx/__init__.py in <module>()
      5 )
      6 from hypernetx.read_write import to_pickle, load_from_pickle
----> 7 from hypernetx.classes import *
      8 from hypernetx.reports import *
      9 from hypernetx.drawing import *

/usr/local/lib/python3.7/dist-packages/hypernetx/classes/__init__.py in <module>()
      1 from .entity import Entity, EntitySet
----> 2 from .hypergraph import Hypergraph
      3 from .staticentity import StaticEntity, StaticEntitySet

/usr/local/lib/python3.7/dist-packages/hypernetx/classes/hypergraph.py in <module>()
     11 from collections import OrderedDict, defaultdict
     12 from hypernetx.classes.entity import Entity, EntitySet
---> 13 from hypernetx.classes.staticentity import StaticEntity, StaticEntitySet
     14 from hypernetx.exception import HyperNetXError
     15 from hypernetx.utils.decorators import not_implemented_for

/usr/local/lib/python3.7/dist-packages/hypernetx/classes/staticentity.py in <module>()
      8 from hypernetx.exception import HyperNetXError
      9 from hypernetx.classes.entity import Entity, EntitySet
---> 10 from hypernetx.utils import HNXCount, DefaultOrderedDict, remove_row_duplicates
     11 from scipy.sparse import coo_matrix, csr_matrix, issparse
     12 import itertools as it

/usr/local/lib/python3.7/dist-packages/hypernetx/utils/__init__.py in <module>()
      2 from .decorators import not_implemented_for
      3 # from .toys import HarryPotter, LesMis, lesmis_hypergraph_from_df, book_tour, TransmissionProblem
----> 4 from .toys import *

ModuleNotFoundError: No module named 'hypernetx.utils.toys'

I'm doing something wrong?

AttributeError: module 'hypernetx.algorithms.hypergraph_modularity' has no attribute 'hypergraph_modularity'

Thanks for this library.

One issue I am having a the moment is the absence of 'hypergraph_modularity' as per the following error:
AttributeError: module 'hypernetx.algorithms.hypergraph_modularity' has no attribute 'hypergraph_modularity'.

The various imports have been fulfilled:
import pandas as pd
import numpy as np
import pickle
import random

import igraph as ig
import hypernetx as hnx
import hypernetx.algorithms.hypergraph_modularity as hmod
import hypernetx.algorithms.generative_models as gm

Any assistance on this would be greatly appreciated.

About s-walk, When I read the article, I have a question: for hyperedge-level s-walk, how to compute the path from a hyperedge to other hyperedge, the sequence included hypergraph's node, rather than only hyperedge?

Dear Author:

class SixByFive():
    """Example hypergraph with 6 nodes and 5 edges"""
    def __init__(self):
        mat = np.array([[1, 1, 1, 0, 0, 0], [1, 0, 1, 0, 1, 0], [1, 1, 0, 0, 1, 1], [0, 1, 1, 1, 0, 0], [1, 1, 1, 1, 0, 0]]).transpose()
        self.hypergraph = hnx.Hypergraph.from_numpy_array(mat)

H = SixByFive().hypergraph

def get_s_path(g, s, source):
    lg = g.get_linegraph(s=s, edges=True)
    print(list(lg.edges))
    try:
        path_dist = nx.single_source_shortest_path(lg, source)
    except (nx.NetworkXNoPath, nx.NodeNotFound):
        warnings.warn(f"No {s}-path between {source} and 1")
        edge_dist = np.inf

    return path_dist
path = get_s_path(H, s=3, source='e0')
print(path)
```python
![Snipaste_2023-11-11_03-41-45](https://github.com/pnnl/HyperNetX/assets/51594106/a76eeda7-9a50-4a38-aaff-8e934f13d62f)
![Snipaste_2023-11-11_03-33-53](https://github.com/pnnl/HyperNetX/assets/51594106/4493ddfd-1078-4708-acff-c54dabcc308c)
In 3-line graph, from e0 to e3, I want the path_dist: 'e3':['e0' 'v2', 'e3'}, 'e3': {'e0', 'v1', 'e3'}?

Tutorial 1 does not run.

I had to change the first line from

# !pip install hypernetx

to

!pip install hypernetx
!pip install celluloid
!pip install igraph

to get it to work

Steps to reproduce:

  1. create a new google account
  2. open the tutorial

I'm not familiar enough with codelab to give an easier reproduction than this, but I hope there is one.

EDIT: Another option to reproduce:

  1. uninstall celluloid & igraph (and anything that depends on them)
  2. run pip3 install hypernetx from terminal to trigger automatic installation of all of install_requires but not extras_require
  3. run import hypernetx from python

remove_edges() does not remove the specified edges

I passed a non-empty list containing the edge numbers to remove_edges(), all of which are present in the hypergraph, but it does not remove any edges in the hypergraph.

This is my code:

list_to_remove = [1, 2, 3]
HG_removed = HG.remove_edges(list_to_remove)

but when I check:
print(len(HG.edges())
and
print(len(HG_removed.edges())

they are both still at 1000.

Thanks in advance for the help!

Find all hyperedges for a node

Hi,
Maybe I am just blind (and/or stupid), but how can I identify (easily) all hyperedges of a given node n in a (static) hypergraph H in HyperNetX?

The solution I came up is:

[edge for edge, nodes in H.incidence_dict.items() if n in nodes]

But probably you had another, more performant solution in mind?
Thank you!

Not drawing the hypergraph

I tried the programs in the tutorial and also the code of the guy that reported the other issue and i get the following error:

/usr/local/lib/python3.7/site-packages/hypernetx/drawing/rubber_band.py:97: FutureWarning: arrays to stack must be passed as a "sequence" type such as list or tuple. Support for non-sequence iterables such as generators is deprecated as of NumPy 1.16 and will raise an error in the future.

I don't know if the problem is that I use python3

Overlapping of nodes in the draw diagram

Describe the bug
The draw function overlaps edges, making it seem that they share nodes.

To Reproduce
Steps to reproduce the behavior:

  1. Run the following code
import matplotlib.pyplot as plt
import hypernetx as hnx
articles = {
        'CA': ('1', '3', '5', '6', '13', '80', '92', '8', '24', '36', '63', '75', '86', '88', '91',
                '10', '33', '57', '84', '27', '50', '67', '18', '60', '69', '81', '23', '31', '45', '87',
                '4', '71', '16', '17', '30', '55', '62', '93', '2', '19', '48', '7', '14', '15', '44', '58'),
        'MRDM': ('1', '3', '5', '6', '13', '27', '38', '42', '67', '80',
                 '92', '9', '23', '29', '31', '34', '35', '45', '87', '88',
                 '33', '84', '18', '74', '98', '21', '82', '11', '19', '48',
                 '53', '61', '73', '85', '96', '97', '99', '7', '44', '95', '40', '76'),
        'DA': ('16', '17', '30', '62', '93', '50', '14', '15', '39', '40', '41', '76'),
        'Graphs': ('9', '23', '29', '31', '34', '35', '45', '87',), 
        'Onto': ('1', '3', '5', '6', '13', '27', '38', '42', '67', '80', '92', '50',), 
    }
H = hnx.Hypergraph(articles)
kwargs = {
        'with_node_labels': True,
        'with_node_counts': False,
        'with_edge_counts': False,
    }

hnx.drawing.draw(
    H_collapsed,
    edges_kwargs={
        'linewidths': 2,
    },
    nodes_kwargs={
    'facecolors': colors
    },
    edge_labels_kwargs={
        'fontsize': 16,
    },
    **kwargs)
plt.show()
  1. See the result:
    image
    As an example, the node 76 seems to be inside the edge Onto, but it's actually not.

Expected behavior
Edges should have node inside them only when they're actually part of them.

Environment (please complete the following information):

  • OS: Linux
  • Python Version Py3.9

Typos in CONTRIBUTING.md

Describe the bug

bursh up should be brush up (funny tho).

Near the bottom the link to CODE_OF_CONDUCT is broken: it needs a .md extension.

AttributeError on attribute 'dataframe' of Hypergraph

Hello,
I've recently started to use hypernetx and I found the following error if I try to access the dataframe associated with a Hypergraph. I simply created an instance 'H' of the Hypergraph class and added a multiedge. When I try to access it through 'H.dataframe', the python interpreter returns:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.10/site-packages/hypernetx/classes/hypergraph.py", line 588, in dataframe
    return self._dataframe
AttributeError: 'Hypergraph' object has no attribute '_dataframe'. Did you mean: 'dataframe'?

I have installed the last version of hypernetx available (hypernetx-2.0.0.post1) for python 3.10.8

Please provide support for weighted hypergraphs

Hi, this is a really good package :)

It would be loads more useful if you could provide support for weighted hypergraphs. It seems to be possible to create a weighted hypergraph at the moment like this:

import itertools
import hypernetx as hnx
import numpy as np

labels = "ABCD"
nodes = set(labels)
edges = list(
    itertools.chain(
        *[list(itertools.combinations(set(labels), ii)) for ii in range(2, len(labels))]
    )
)
hnx_edges = hnx.EntitySet(
    "Edges", 
    [hnx.Entity(
            "".join(ee), 
            ee,
            weight=np.random.rand() 
        ) for ee in edges]
)

h = hnx.Hypergraph(hnx_edges)
hnx.draw(h)
print(h.edges.elements)

but it's not possible to do any analysis with the weights as far as I can tell (see for example, the output of hnx.dist_stats(h) )

Are there any plans to add this type of functionality?

Thanks!

Automorphisms

Once I build the hypergraph is it possible to get a list of Automorphisms in the hypergraph?

The LICENSE is not clearly OSI compliant

Describe the bug

LICENSE is provided in LICENSE.rst but it not clearly OSI compliant.

Additional context

I am reviewing this package for JOSS openjournals/joss-reviews#6016 (comment)

It looks like the license is intended to be the BSD 3-clause license (at OSI here: https://opensource.org/license/bsd-3-clause/ ) but:

  • there is a typo at the end of the 2nd clause which currently reads "and/or other" but should read "and/or other materials provided with the distribution."
  • the third clause has been edited in a way as to make it unclear if it still matches the BSD 3-clause license. In particular "Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software" has been changed to "neither the name Battelle Memorial Institute or Battelle may be used in any form whatsoever without the express written consent of Battelle.".

The modification to clause 3 appears to be a substantial reduction in the grant.

I suggest that you either:

  • use the BSD 3-clause license directly; or,
  • provide enough material to reviewers to assure us that this license is in fact "the contents of an OSI approved software license"

Confusing sorting order in hypergraph nodes

Hi there,

I am experiencing a weird behaviour when retrieving the nodelist from the Hypergraph. It is so basic that I do wonder if, rather than being an issue, I am doing something wrong or if I am missing some option, but I can't figure it out.

Take, for instance, the first tutorial notebook. When one runs H.nodes, one is returned EntitySet(:Nodes,['BM', 'JU', 'MP', 'CN', 'TH', 'FN', 'JA', 'BR', 'GP', 'MA', 'JV', 'CH', 'CC'],{'weight': 1.0}). Notice the ordering of the nodes: that is the same order of, for instance, the H.adjacency_matrix() matrix.

On the other hand, if one runs list(H.nodes) or H.nodes.elements or even prints the nodes in a for node in H.nodes: loop, one gets a completely different ordering: ['FN', 'TH', 'JV', 'BM', 'JA', 'JU', 'CH', 'BR', 'CN', 'CC', 'GP', 'MP', 'MA'].

What am I missing? I think this is confusing, to say the least.

Thanks in advance,
G

AttributeError: module 'numpy' has no attribute '_no_nep50_warning'

Describe the bug
When I import the library I get the following error
AttributeError: module 'numpy' has no attribute '_no_nep50_warning'

To Reproduce
On Google Colab with T4 GPU

!pip install hypernetx
import torch
import numpy as np
import networkx as nx
import sys
import hypernetx as hnx

Expected behavior
AttributeError: module 'numpy' has no attribute '_no_nep50_warning'

Screenshots
Screen Shot 2023-06-22 at 2 02 38 PM

Import fails due to missing `decorator` package in clean install

Installing hypernetx in a clean virtual environment fails due to a missing package: decorator.

Step to reproduce (after initializing a new empty virtual environment):

pip install hypernetx

giving an error like this:

>>> import hypernetx as hnx
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/tmp/hnx-version/venv/lib/python3.8/site-packages/hypernetx/__init__.py", line 7, in <module>
    from hypernetx.classes import *
  File "/tmp/hnx-version/venv/lib/python3.8/site-packages/hypernetx/classes/__init__.py", line 2, in <module>
    from .hypergraph import Hypergraph
  File "/tmp/hnx-version/venv/lib/python3.8/site-packages/hypernetx/classes/hypergraph.py", line 13, in <module>
    from hypernetx.classes.staticentity import StaticEntity, StaticEntitySet
  File "/tmp/hnx-version/venv/lib/python3.8/site-packages/hypernetx/classes/staticentity.py", line 10, in <module>
    from hypernetx.utils import (
  File "/tmp/hnx-version/venv/lib/python3.8/site-packages/hypernetx/utils/__init__.py", line 8, in <module>
    from .decorators import not_implemented_for
  File "/tmp/hnx-version/venv/lib/python3.8/site-packages/hypernetx/utils/decorators.py", line 4, in <module>
    from decorator import decorator
ModuleNotFoundError: No module named 'decorator'

Of course, installing the decorator package manually fixes the issue and hypernetx imports fine. I think the decorator package should just be added to the install_requires entry in setup.cfg and setup.py since this package is required to even load the package at all.

Tested using Python versions 3.8 and 3.9, using hypernetx 1.2.2 (on Ubuntu).

Bad math syntax in hypgraph101.html documentation

Describe the bug

In (the compiled documentation file) hypergraph101.html there is an occurrence of :math:`s`-walk in the section "Walks Have Length and Width". I suspect that this is a syntax typo.

remove.singletons deletes weights

When I used algorithms.hypergraph_modularity.precompute_attributes , I realized that this function resets hyperedges weights to the unit weight. I seems that the problem comes from the first line H = HG.remove_singletons(). This function seems to not copy the original weights. When I delete this first line H = HG.remove_singletons() from the source code of precompute_attributes ,it works well.

[joss] degree_dist() is a misnomer

Nitpick: The degree_dist() method has a name that is perhaps not the best fit. What this function returns is not a distribution, but a list of degrees. In graph theory this is called a degree sequence, not a degree distribution. What is normally understood as a degree distribution is the fraction of times each degree appears in the degree sequence.

Ref openjournals/joss-reviews#6016

Same edge name ?

Is it possible for edges with the same name but different nodes to coexist. Something like this :

{
  "is" : ["red","apple","rotten"],
  "is" : ["black","pen"]
}

How do you achieve this ?

About the function "to_pickle", now the version 2.0.3 not support the save function?

scenes = {
    0: ('FN', 'TH'),
    1: ('TH', 'JV'),
    2: ('BM', 'FN', 'JA'),
    3: ('JV', 'JU', 'CH', 'BM'),
    4: ('JU', 'CH', 'BR', 'CN', 'CC', 'JV', 'BM'),
    5: ('TH', 'GP'),
    6: ('GP', 'MP'),
    7: ('MA', 'GP')
}

H = hnx.Hypergraph(scenes)
H
hnx.to_pickle(H, filename='1.pkl')

File D:\Anaconda\envs\mhyperG\lib\site-packages\hypernetx\read_write.py:10, in to_pickle(obj, filename)
8 """Writes object to a pickle file"""
9 with open(f"{filename}", "wb") as f:
---> 10 pickle.dump(obj, f)

TypeError: 'NoneType' object is not callable
How can I fix the bug?

Comparison between weighted and unweighted hypergraphs in clustering

Hello, thank you for sharing this excellent library.

I want to compare the performance of clustering on weighted and unweighted hypergraphs as described in K. Hayashi, S. Aksoy, C. Park, H. Park, "Hypergraph random walks, Laplacians, and clustering".
I tried to do this based on Tutorial 11.
However, I think some modifications need.
h = hnx.Hypergraph(hnx.StaticEntitySet(data=data, weights=w))
I think this code does not make a weighted hypergraph.
Instead, this should be revised as below.
h = hnx.Hypergraph(hnx.StaticEntitySet(data=data, weights=w), weights=w)

Additionally, I cannot get the satisfying result that weighted hypergraphs perform better than unweighted ones.
Thus, I want to ask whether the below code is a correct way to make clustering on an unweighted hypergraph and evaluate clustering algorithms by NMI scores.

# get data
categories = all_categories[[1,15]]
twenty_train = fetch_20newsgroups(subset='test', categories=categories, shuffle=True, random_state=42)
doc_types=dict()
for i,x in enumerate(twenty_train.filenames):
    doc_types[i]=x.split('/')[-2]
tfidf_vect = TfidfVectorizer()
X_tfidf = tfidf_vect.fit_transform(twenty_train.data)

# construct hypergraph
mat = coo_matrix(X_tfidf)
edges = mat.col
nodes = mat.row
data = np.array([edges,nodes]).T
weights = mat.data
# clustering on weighted hypergraph
h = hnx.Hypergraph(hnx.StaticEntitySet(data=data,weights=weights),weights=weights)
clusters=hnx.spec_clus(h,num_clus,weights=True)
# clustering on unweighted hypergraph
uwh =  hnx.Hypergraph(hnx.StaticEntitySet(data=data,weights=None))
uw_clusters = hnx.spec_clus(uwh,num_clus,weights=False)

# construct clustering label list
categoryindexing = {}
_labels = {} # answer
for i in range(X_tfidf.shape[0]):
    if doc_types[i] not in categoryindexing:
        categoryindexing[doc_types[i]] = len(categoryindexing)
    ci = categoryindexing[doc_types[i]]
    _labels[i] = ci
labels = [_labels[i] for i in range(X_tfidf.shape[0])]
_w_pred = {} #  labels from weighted hypergraph
for i in clusters:
    for v in clusters[i]:
        _w_pred[v] = i
w_pred = [_w_pred[i] for i in range(X_tfidf.shape[0])]
_uw_pred = {} # labels from unweighted hypergraph
for i in uw_clusters:
    for v in uw_clusters[i]:
        _uw_pred[v] = i
uw_pred = [_uw_pred[i] for i in range(X_tfidf.shape[0])]

# evaluation on NMI score
from sklearn.metrics.cluster import normalized_mutual_info_score as NMI_SCORE
score = NMI_SCORE(labels, w_pred)
print(score) # 0.73
score = NMI_SCORE(labels, uw_pred)
print(score) # 0.78

Dependencies are not correct

For pip install hypernetx, the packages igraph and celluloid are not installed by default. One has to do it manually. This is also the reason why the tutorial fails (#73).
What about adding them to setup.py?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤ī¸ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.