Detect and measure the basic role of influence each node plays within a directed network.
It supports a raw list of nodes, a NetworkX DiGraph, as well as a method to be used in a distributed context for Big Data use cases.
This algorithm returns:
- The Basic Influence Role (BIR) of a node in a network
- The BIR's level
- The influence measure related to the role
- A global influence measure based on indegree and outdegree
- The influence ranking of the node
For in-depth theoretical details and more examples, please read the main repository intro.
All useful informations can be found in the following paragraphs:
pip install basic-influence-rolesImport BIRs package
import BIRsMethods to detect BIRs.
BIRs.detect_from_nodes(nodes=List[Dict])| Field | Type | Required | Description |
|---|---|---|---|
nodes |
[{...}] | yes | A list of all nodes' data as dict. |
nodes[i]['id'] |
any | yes | The name or id of the node. |
nodes[i]['indegree'] |
integer | yes | The number of incoming connections. |
nodes[i]['outdegree'] |
integer | yes | The number of outcoming connections. |
# The list of nodes with indegree and outdegree
nodes = [
{'id': 1, 'indegree': 13, 'outdegree': 5},
{'id': 2, 'indegree': 3, 'outdegree': 8},
{'id': 3, 'indegree': 0, 'outdegree': 22},
{'id': 4, 'indegree': 16, 'outdegree': 19},
{...}
]
# Measure the influence score and detect the basic influence roles
res = BIRs.detect_from_nodes(nodes)BIRs.detect_nx(nx.DiGraph)| Type | Required | Description |
|---|---|---|
| nx.DiGraph | yes | A NetworkX directed graph. |
# Create a random directed graph
G = nx.erdos_renyi_graph(100, 0.01, directed=True)
# Remove possible self-loop edges
G.remove_edges_from(nx.selfloop_edges(G))
# Detect basic influence roles of nodes
res = BIRs.detect_nx(G)In case of Big Data or Huge Networks you can distribute the load in this way:
BIRs.detect(indegree, outdegree, node_count)| Field | Type | Required | Description |
|---|---|---|---|
indegree |
integer | yes | The number of incoming connections. |
outdegree |
integer | yes | The number of outcoming connections. |
node_count |
integer | yes | The total number of nodes. |
data |
boolean | no | If True returns indegree and outdegree. |
# Get the total count of nodes
node_count = 8586987087
# For every node in a huge network (use here a distributed loop instead)
for indegree, outdegree in nodes:
# Get basic influence role of every node in network
res = BIRs.detect(indegree, outdegree, node_count, True)The output is a list of nodes reporting their id, role, role level, influence measure, influence ranking.
| Field | Type | Description |
|---|---|---|
id |
any | The id of node. |
role |
string | The basic influence role. |
role_influence |
float | The influence magnitude related to the node's role. |
role_level |
string | The level of role, a role subcategory. |
influence |
float | A normalized influence score based on indegree and outdegree. |
indegree |
integer | The number of incoming connections. |
outdegree |
integer | The number of outcoming connections. |
normalized_indegree |
float | The normalized number of incoming connections. |
normalized_outdegree |
float | The normalized number of outcoming connections. |
rank |
integer | The normalized influence ranking based on the value of influence field. |
[
{
'id': 4,
'role': 'hub',
'role_influence': 0.9210526315789473,
'role_level': 'strong',
'influence': 0.9210526315789473,
'indegree': 16,
'outdegree': 19,
'normalized_indegree': 0.8421052631578947,
'normalized_outdegree': 1.0,
'rank': 1
},
{
'id': 3,
'role': 'emitter',
'role_influence': 0.9473684210526315,
'role_level': 'strong',
'influence': 0.47368421052631576,
'indegree': 0,
'outdegree': 18,
'normalized_indegree': 0.0,
'normalized_outdegree': 0.9473684210526315
'rank': 2
},
...
]Given a list of BIRs, can be calculated the distribution of BIRs in a network, as a normalized frequency between roles and also between their levels.
BIRs.distribution(data=[])| Field | Type | Required | Description |
|---|---|---|---|
data |
[{...}] | yes | The list of roles, the output of BIRs' detection methods. |
# Create a random directed graph
G = nx.erdos_renyi_graph(100, 0.01, directed=True)
# Remove possible self-loop edges
G.remove_edges_from(nx.selfloop_edges(G))
# Detect basic influence roles of nodes
data = BIRs.detect_nx(G)
# Detect the distribution of BIRs
res = BIRs.distribution(data){
'reducer': {
'count': 12,
'frequency': 0.12,
'levels': {
'none': {'count': 0, 'frequency': 0.0},
'branch': {'count': 0, 'frequency': 0.0},
'weak': {'count': 7, 'frequency': 0.07},
'strong': {'count': 5, 'frequency': 0.05},
'top': {'count': 0, 'frequency': 0.0}
}
},
'amplifier': {
'count': 13,
'frequency': 0.13,
'levels': {
'none': {'count': 0, 'frequency': 0.0},
'branch': {'count': 0, 'frequency': 0.0},
'weak': {'count': 12, 'frequency': 0.12},
'strong': {'count': 1, 'frequency': 0.01},
'top': {'count': 0, 'frequency': 0.0}
}
},
'emitter': {
'count': 28,
'frequency': 0.28,
'levels': {
'none': {'count': 0, 'frequency': 0.0},
'branch': {'count': 18, 'frequency': 0.18},
'weak': {'count': 10, 'frequency': 0.1},
'strong': {'count': 0, 'frequency': 0.0},
'top': {'count': 0, 'frequency': 0.0}
}
},
...
}The package is battle tested with a coverage of 98%. Unit tests are inside the folder /test.
At first, install dev requirements:
pip install -r requirements-dev.txtTo run all unit tests with coverage, type:
PYTHONPATH=src python -m coverage run --source=src -m unittest discover test -vOr run the bash script:
./test.shTo run the coverage report:
coverage report -mIf you use this software in your work, please cite it as below:
Miceli, D. (2024). Basic Influence Roles (BIRs) [Computer software]. https://github.com/davidemiceli/basic-influence-roles
Or the BibTeX version:
@software{MiceliBasicInfluenceRoles2024,
author = {Miceli, Davide},
license = {MIT},
month = mar,
title = {{Basic Influence Roles (BIRs)}},
url = {https://github.com/davidemiceli/basic-influence-roles},
year = {2024}
}Basic Influence Roles is an open source project available under the MIT license.