aboutsummaryrefslogtreecommitdiff
path: root/.venv/lib/python3.12/site-packages/networkx/algorithms/link_prediction.py
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/networkx/algorithms/link_prediction.py')
-rw-r--r--.venv/lib/python3.12/site-packages/networkx/algorithms/link_prediction.py687
1 files changed, 687 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/networkx/algorithms/link_prediction.py b/.venv/lib/python3.12/site-packages/networkx/algorithms/link_prediction.py
new file mode 100644
index 00000000..3615f26d
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/networkx/algorithms/link_prediction.py
@@ -0,0 +1,687 @@
+"""
+Link prediction algorithms.
+"""
+
+from math import log
+
+import networkx as nx
+from networkx.utils import not_implemented_for
+
+__all__ = [
+ "resource_allocation_index",
+ "jaccard_coefficient",
+ "adamic_adar_index",
+ "preferential_attachment",
+ "cn_soundarajan_hopcroft",
+ "ra_index_soundarajan_hopcroft",
+ "within_inter_cluster",
+ "common_neighbor_centrality",
+]
+
+
+def _apply_prediction(G, func, ebunch=None):
+ """Applies the given function to each edge in the specified iterable
+ of edges.
+
+ `G` is an instance of :class:`networkx.Graph`.
+
+ `func` is a function on two inputs, each of which is a node in the
+ graph. The function can return anything, but it should return a
+ value representing a prediction of the likelihood of a "link"
+ joining the two nodes.
+
+ `ebunch` is an iterable of pairs of nodes. If not specified, all
+ non-edges in the graph `G` will be used.
+
+ """
+ if ebunch is None:
+ ebunch = nx.non_edges(G)
+ else:
+ for u, v in ebunch:
+ if u not in G:
+ raise nx.NodeNotFound(f"Node {u} not in G.")
+ if v not in G:
+ raise nx.NodeNotFound(f"Node {v} not in G.")
+ return ((u, v, func(u, v)) for u, v in ebunch)
+
+
+@not_implemented_for("directed")
+@not_implemented_for("multigraph")
+@nx._dispatchable
+def resource_allocation_index(G, ebunch=None):
+ r"""Compute the resource allocation index of all node pairs in ebunch.
+
+ Resource allocation index of `u` and `v` is defined as
+
+ .. math::
+
+ \sum_{w \in \Gamma(u) \cap \Gamma(v)} \frac{1}{|\Gamma(w)|}
+
+ where $\Gamma(u)$ denotes the set of neighbors of $u$.
+
+ Parameters
+ ----------
+ G : graph
+ A NetworkX undirected graph.
+
+ ebunch : iterable of node pairs, optional (default = None)
+ Resource allocation index will be computed for each pair of
+ nodes given in the iterable. The pairs must be given as
+ 2-tuples (u, v) where u and v are nodes in the graph. If ebunch
+ is None then all nonexistent edges in the graph will be used.
+ Default value: None.
+
+ Returns
+ -------
+ piter : iterator
+ An iterator of 3-tuples in the form (u, v, p) where (u, v) is a
+ pair of nodes and p is their resource allocation index.
+
+ Raises
+ ------
+ NetworkXNotImplemented
+ If `G` is a `DiGraph`, a `Multigraph` or a `MultiDiGraph`.
+
+ NodeNotFound
+ If `ebunch` has a node that is not in `G`.
+
+ Examples
+ --------
+ >>> G = nx.complete_graph(5)
+ >>> preds = nx.resource_allocation_index(G, [(0, 1), (2, 3)])
+ >>> for u, v, p in preds:
+ ... print(f"({u}, {v}) -> {p:.8f}")
+ (0, 1) -> 0.75000000
+ (2, 3) -> 0.75000000
+
+ References
+ ----------
+ .. [1] T. Zhou, L. Lu, Y.-C. Zhang.
+ Predicting missing links via local information.
+ Eur. Phys. J. B 71 (2009) 623.
+ https://arxiv.org/pdf/0901.0553.pdf
+ """
+
+ def predict(u, v):
+ return sum(1 / G.degree(w) for w in nx.common_neighbors(G, u, v))
+
+ return _apply_prediction(G, predict, ebunch)
+
+
+@not_implemented_for("directed")
+@not_implemented_for("multigraph")
+@nx._dispatchable
+def jaccard_coefficient(G, ebunch=None):
+ r"""Compute the Jaccard coefficient of all node pairs in ebunch.
+
+ Jaccard coefficient of nodes `u` and `v` is defined as
+
+ .. math::
+
+ \frac{|\Gamma(u) \cap \Gamma(v)|}{|\Gamma(u) \cup \Gamma(v)|}
+
+ where $\Gamma(u)$ denotes the set of neighbors of $u$.
+
+ Parameters
+ ----------
+ G : graph
+ A NetworkX undirected graph.
+
+ ebunch : iterable of node pairs, optional (default = None)
+ Jaccard coefficient will be computed for each pair of nodes
+ given in the iterable. The pairs must be given as 2-tuples
+ (u, v) where u and v are nodes in the graph. If ebunch is None
+ then all nonexistent edges in the graph will be used.
+ Default value: None.
+
+ Returns
+ -------
+ piter : iterator
+ An iterator of 3-tuples in the form (u, v, p) where (u, v) is a
+ pair of nodes and p is their Jaccard coefficient.
+
+ Raises
+ ------
+ NetworkXNotImplemented
+ If `G` is a `DiGraph`, a `Multigraph` or a `MultiDiGraph`.
+
+ NodeNotFound
+ If `ebunch` has a node that is not in `G`.
+
+ Examples
+ --------
+ >>> G = nx.complete_graph(5)
+ >>> preds = nx.jaccard_coefficient(G, [(0, 1), (2, 3)])
+ >>> for u, v, p in preds:
+ ... print(f"({u}, {v}) -> {p:.8f}")
+ (0, 1) -> 0.60000000
+ (2, 3) -> 0.60000000
+
+ References
+ ----------
+ .. [1] D. Liben-Nowell, J. Kleinberg.
+ The Link Prediction Problem for Social Networks (2004).
+ http://www.cs.cornell.edu/home/kleinber/link-pred.pdf
+ """
+
+ def predict(u, v):
+ union_size = len(set(G[u]) | set(G[v]))
+ if union_size == 0:
+ return 0
+ return len(nx.common_neighbors(G, u, v)) / union_size
+
+ return _apply_prediction(G, predict, ebunch)
+
+
+@not_implemented_for("directed")
+@not_implemented_for("multigraph")
+@nx._dispatchable
+def adamic_adar_index(G, ebunch=None):
+ r"""Compute the Adamic-Adar index of all node pairs in ebunch.
+
+ Adamic-Adar index of `u` and `v` is defined as
+
+ .. math::
+
+ \sum_{w \in \Gamma(u) \cap \Gamma(v)} \frac{1}{\log |\Gamma(w)|}
+
+ where $\Gamma(u)$ denotes the set of neighbors of $u$.
+ This index leads to zero-division for nodes only connected via self-loops.
+ It is intended to be used when no self-loops are present.
+
+ Parameters
+ ----------
+ G : graph
+ NetworkX undirected graph.
+
+ ebunch : iterable of node pairs, optional (default = None)
+ Adamic-Adar index will be computed for each pair of nodes given
+ in the iterable. The pairs must be given as 2-tuples (u, v)
+ where u and v are nodes in the graph. If ebunch is None then all
+ nonexistent edges in the graph will be used.
+ Default value: None.
+
+ Returns
+ -------
+ piter : iterator
+ An iterator of 3-tuples in the form (u, v, p) where (u, v) is a
+ pair of nodes and p is their Adamic-Adar index.
+
+ Raises
+ ------
+ NetworkXNotImplemented
+ If `G` is a `DiGraph`, a `Multigraph` or a `MultiDiGraph`.
+
+ NodeNotFound
+ If `ebunch` has a node that is not in `G`.
+
+ Examples
+ --------
+ >>> G = nx.complete_graph(5)
+ >>> preds = nx.adamic_adar_index(G, [(0, 1), (2, 3)])
+ >>> for u, v, p in preds:
+ ... print(f"({u}, {v}) -> {p:.8f}")
+ (0, 1) -> 2.16404256
+ (2, 3) -> 2.16404256
+
+ References
+ ----------
+ .. [1] D. Liben-Nowell, J. Kleinberg.
+ The Link Prediction Problem for Social Networks (2004).
+ http://www.cs.cornell.edu/home/kleinber/link-pred.pdf
+ """
+
+ def predict(u, v):
+ return sum(1 / log(G.degree(w)) for w in nx.common_neighbors(G, u, v))
+
+ return _apply_prediction(G, predict, ebunch)
+
+
+@not_implemented_for("directed")
+@not_implemented_for("multigraph")
+@nx._dispatchable
+def common_neighbor_centrality(G, ebunch=None, alpha=0.8):
+ r"""Return the CCPA score for each pair of nodes.
+
+ Compute the Common Neighbor and Centrality based Parameterized Algorithm(CCPA)
+ score of all node pairs in ebunch.
+
+ CCPA score of `u` and `v` is defined as
+
+ .. math::
+
+ \alpha \cdot (|\Gamma (u){\cap }^{}\Gamma (v)|)+(1-\alpha )\cdot \frac{N}{{d}_{uv}}
+
+ where $\Gamma(u)$ denotes the set of neighbors of $u$, $\Gamma(v)$ denotes the
+ set of neighbors of $v$, $\alpha$ is parameter varies between [0,1], $N$ denotes
+ total number of nodes in the Graph and ${d}_{uv}$ denotes shortest distance
+ between $u$ and $v$.
+
+ This algorithm is based on two vital properties of nodes, namely the number
+ of common neighbors and their centrality. Common neighbor refers to the common
+ nodes between two nodes. Centrality refers to the prestige that a node enjoys
+ in a network.
+
+ .. seealso::
+
+ :func:`common_neighbors`
+
+ Parameters
+ ----------
+ G : graph
+ NetworkX undirected graph.
+
+ ebunch : iterable of node pairs, optional (default = None)
+ Preferential attachment score will be computed for each pair of
+ nodes given in the iterable. The pairs must be given as
+ 2-tuples (u, v) where u and v are nodes in the graph. If ebunch
+ is None then all nonexistent edges in the graph will be used.
+ Default value: None.
+
+ alpha : Parameter defined for participation of Common Neighbor
+ and Centrality Algorithm share. Values for alpha should
+ normally be between 0 and 1. Default value set to 0.8
+ because author found better performance at 0.8 for all the
+ dataset.
+ Default value: 0.8
+
+
+ Returns
+ -------
+ piter : iterator
+ An iterator of 3-tuples in the form (u, v, p) where (u, v) is a
+ pair of nodes and p is their Common Neighbor and Centrality based
+ Parameterized Algorithm(CCPA) score.
+
+ Raises
+ ------
+ NetworkXNotImplemented
+ If `G` is a `DiGraph`, a `Multigraph` or a `MultiDiGraph`.
+
+ NetworkXAlgorithmError
+ If self loops exist in `ebunch` or in `G` (if `ebunch` is `None`).
+
+ NodeNotFound
+ If `ebunch` has a node that is not in `G`.
+
+ Examples
+ --------
+ >>> G = nx.complete_graph(5)
+ >>> preds = nx.common_neighbor_centrality(G, [(0, 1), (2, 3)])
+ >>> for u, v, p in preds:
+ ... print(f"({u}, {v}) -> {p}")
+ (0, 1) -> 3.4000000000000004
+ (2, 3) -> 3.4000000000000004
+
+ References
+ ----------
+ .. [1] Ahmad, I., Akhtar, M.U., Noor, S. et al.
+ Missing Link Prediction using Common Neighbor and Centrality based Parameterized Algorithm.
+ Sci Rep 10, 364 (2020).
+ https://doi.org/10.1038/s41598-019-57304-y
+ """
+
+ # When alpha == 1, the CCPA score simplifies to the number of common neighbors.
+ if alpha == 1:
+
+ def predict(u, v):
+ if u == v:
+ raise nx.NetworkXAlgorithmError("Self loops are not supported")
+
+ return len(nx.common_neighbors(G, u, v))
+
+ else:
+ spl = dict(nx.shortest_path_length(G))
+ inf = float("inf")
+
+ def predict(u, v):
+ if u == v:
+ raise nx.NetworkXAlgorithmError("Self loops are not supported")
+ path_len = spl[u].get(v, inf)
+
+ n_nbrs = len(nx.common_neighbors(G, u, v))
+ return alpha * n_nbrs + (1 - alpha) * len(G) / path_len
+
+ return _apply_prediction(G, predict, ebunch)
+
+
+@not_implemented_for("directed")
+@not_implemented_for("multigraph")
+@nx._dispatchable
+def preferential_attachment(G, ebunch=None):
+ r"""Compute the preferential attachment score of all node pairs in ebunch.
+
+ Preferential attachment score of `u` and `v` is defined as
+
+ .. math::
+
+ |\Gamma(u)| |\Gamma(v)|
+
+ where $\Gamma(u)$ denotes the set of neighbors of $u$.
+
+ Parameters
+ ----------
+ G : graph
+ NetworkX undirected graph.
+
+ ebunch : iterable of node pairs, optional (default = None)
+ Preferential attachment score will be computed for each pair of
+ nodes given in the iterable. The pairs must be given as
+ 2-tuples (u, v) where u and v are nodes in the graph. If ebunch
+ is None then all nonexistent edges in the graph will be used.
+ Default value: None.
+
+ Returns
+ -------
+ piter : iterator
+ An iterator of 3-tuples in the form (u, v, p) where (u, v) is a
+ pair of nodes and p is their preferential attachment score.
+
+ Raises
+ ------
+ NetworkXNotImplemented
+ If `G` is a `DiGraph`, a `Multigraph` or a `MultiDiGraph`.
+
+ NodeNotFound
+ If `ebunch` has a node that is not in `G`.
+
+ Examples
+ --------
+ >>> G = nx.complete_graph(5)
+ >>> preds = nx.preferential_attachment(G, [(0, 1), (2, 3)])
+ >>> for u, v, p in preds:
+ ... print(f"({u}, {v}) -> {p}")
+ (0, 1) -> 16
+ (2, 3) -> 16
+
+ References
+ ----------
+ .. [1] D. Liben-Nowell, J. Kleinberg.
+ The Link Prediction Problem for Social Networks (2004).
+ http://www.cs.cornell.edu/home/kleinber/link-pred.pdf
+ """
+
+ def predict(u, v):
+ return G.degree(u) * G.degree(v)
+
+ return _apply_prediction(G, predict, ebunch)
+
+
+@not_implemented_for("directed")
+@not_implemented_for("multigraph")
+@nx._dispatchable(node_attrs="community")
+def cn_soundarajan_hopcroft(G, ebunch=None, community="community"):
+ r"""Count the number of common neighbors of all node pairs in ebunch
+ using community information.
+
+ For two nodes $u$ and $v$, this function computes the number of
+ common neighbors and bonus one for each common neighbor belonging to
+ the same community as $u$ and $v$. Mathematically,
+
+ .. math::
+
+ |\Gamma(u) \cap \Gamma(v)| + \sum_{w \in \Gamma(u) \cap \Gamma(v)} f(w)
+
+ where $f(w)$ equals 1 if $w$ belongs to the same community as $u$
+ and $v$ or 0 otherwise and $\Gamma(u)$ denotes the set of
+ neighbors of $u$.
+
+ Parameters
+ ----------
+ G : graph
+ A NetworkX undirected graph.
+
+ ebunch : iterable of node pairs, optional (default = None)
+ The score will be computed for each pair of nodes given in the
+ iterable. The pairs must be given as 2-tuples (u, v) where u
+ and v are nodes in the graph. If ebunch is None then all
+ nonexistent edges in the graph will be used.
+ Default value: None.
+
+ community : string, optional (default = 'community')
+ Nodes attribute name containing the community information.
+ G[u][community] identifies which community u belongs to. Each
+ node belongs to at most one community. Default value: 'community'.
+
+ Returns
+ -------
+ piter : iterator
+ An iterator of 3-tuples in the form (u, v, p) where (u, v) is a
+ pair of nodes and p is their score.
+
+ Raises
+ ------
+ NetworkXNotImplemented
+ If `G` is a `DiGraph`, a `Multigraph` or a `MultiDiGraph`.
+
+ NetworkXAlgorithmError
+ If no community information is available for a node in `ebunch` or in `G` (if `ebunch` is `None`).
+
+ NodeNotFound
+ If `ebunch` has a node that is not in `G`.
+
+ Examples
+ --------
+ >>> G = nx.path_graph(3)
+ >>> G.nodes[0]["community"] = 0
+ >>> G.nodes[1]["community"] = 0
+ >>> G.nodes[2]["community"] = 0
+ >>> preds = nx.cn_soundarajan_hopcroft(G, [(0, 2)])
+ >>> for u, v, p in preds:
+ ... print(f"({u}, {v}) -> {p}")
+ (0, 2) -> 2
+
+ References
+ ----------
+ .. [1] Sucheta Soundarajan and John Hopcroft.
+ Using community information to improve the precision of link
+ prediction methods.
+ In Proceedings of the 21st international conference companion on
+ World Wide Web (WWW '12 Companion). ACM, New York, NY, USA, 607-608.
+ http://doi.acm.org/10.1145/2187980.2188150
+ """
+
+ def predict(u, v):
+ Cu = _community(G, u, community)
+ Cv = _community(G, v, community)
+ cnbors = nx.common_neighbors(G, u, v)
+ neighbors = (
+ sum(_community(G, w, community) == Cu for w in cnbors) if Cu == Cv else 0
+ )
+ return len(cnbors) + neighbors
+
+ return _apply_prediction(G, predict, ebunch)
+
+
+@not_implemented_for("directed")
+@not_implemented_for("multigraph")
+@nx._dispatchable(node_attrs="community")
+def ra_index_soundarajan_hopcroft(G, ebunch=None, community="community"):
+ r"""Compute the resource allocation index of all node pairs in
+ ebunch using community information.
+
+ For two nodes $u$ and $v$, this function computes the resource
+ allocation index considering only common neighbors belonging to the
+ same community as $u$ and $v$. Mathematically,
+
+ .. math::
+
+ \sum_{w \in \Gamma(u) \cap \Gamma(v)} \frac{f(w)}{|\Gamma(w)|}
+
+ where $f(w)$ equals 1 if $w$ belongs to the same community as $u$
+ and $v$ or 0 otherwise and $\Gamma(u)$ denotes the set of
+ neighbors of $u$.
+
+ Parameters
+ ----------
+ G : graph
+ A NetworkX undirected graph.
+
+ ebunch : iterable of node pairs, optional (default = None)
+ The score will be computed for each pair of nodes given in the
+ iterable. The pairs must be given as 2-tuples (u, v) where u
+ and v are nodes in the graph. If ebunch is None then all
+ nonexistent edges in the graph will be used.
+ Default value: None.
+
+ community : string, optional (default = 'community')
+ Nodes attribute name containing the community information.
+ G[u][community] identifies which community u belongs to. Each
+ node belongs to at most one community. Default value: 'community'.
+
+ Returns
+ -------
+ piter : iterator
+ An iterator of 3-tuples in the form (u, v, p) where (u, v) is a
+ pair of nodes and p is their score.
+
+ Raises
+ ------
+ NetworkXNotImplemented
+ If `G` is a `DiGraph`, a `Multigraph` or a `MultiDiGraph`.
+
+ NetworkXAlgorithmError
+ If no community information is available for a node in `ebunch` or in `G` (if `ebunch` is `None`).
+
+ NodeNotFound
+ If `ebunch` has a node that is not in `G`.
+
+ Examples
+ --------
+ >>> G = nx.Graph()
+ >>> G.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3)])
+ >>> G.nodes[0]["community"] = 0
+ >>> G.nodes[1]["community"] = 0
+ >>> G.nodes[2]["community"] = 1
+ >>> G.nodes[3]["community"] = 0
+ >>> preds = nx.ra_index_soundarajan_hopcroft(G, [(0, 3)])
+ >>> for u, v, p in preds:
+ ... print(f"({u}, {v}) -> {p:.8f}")
+ (0, 3) -> 0.50000000
+
+ References
+ ----------
+ .. [1] Sucheta Soundarajan and John Hopcroft.
+ Using community information to improve the precision of link
+ prediction methods.
+ In Proceedings of the 21st international conference companion on
+ World Wide Web (WWW '12 Companion). ACM, New York, NY, USA, 607-608.
+ http://doi.acm.org/10.1145/2187980.2188150
+ """
+
+ def predict(u, v):
+ Cu = _community(G, u, community)
+ Cv = _community(G, v, community)
+ if Cu != Cv:
+ return 0
+ cnbors = nx.common_neighbors(G, u, v)
+ return sum(1 / G.degree(w) for w in cnbors if _community(G, w, community) == Cu)
+
+ return _apply_prediction(G, predict, ebunch)
+
+
+@not_implemented_for("directed")
+@not_implemented_for("multigraph")
+@nx._dispatchable(node_attrs="community")
+def within_inter_cluster(G, ebunch=None, delta=0.001, community="community"):
+ """Compute the ratio of within- and inter-cluster common neighbors
+ of all node pairs in ebunch.
+
+ For two nodes `u` and `v`, if a common neighbor `w` belongs to the
+ same community as them, `w` is considered as within-cluster common
+ neighbor of `u` and `v`. Otherwise, it is considered as
+ inter-cluster common neighbor of `u` and `v`. The ratio between the
+ size of the set of within- and inter-cluster common neighbors is
+ defined as the WIC measure. [1]_
+
+ Parameters
+ ----------
+ G : graph
+ A NetworkX undirected graph.
+
+ ebunch : iterable of node pairs, optional (default = None)
+ The WIC measure will be computed for each pair of nodes given in
+ the iterable. The pairs must be given as 2-tuples (u, v) where
+ u and v are nodes in the graph. If ebunch is None then all
+ nonexistent edges in the graph will be used.
+ Default value: None.
+
+ delta : float, optional (default = 0.001)
+ Value to prevent division by zero in case there is no
+ inter-cluster common neighbor between two nodes. See [1]_ for
+ details. Default value: 0.001.
+
+ community : string, optional (default = 'community')
+ Nodes attribute name containing the community information.
+ G[u][community] identifies which community u belongs to. Each
+ node belongs to at most one community. Default value: 'community'.
+
+ Returns
+ -------
+ piter : iterator
+ An iterator of 3-tuples in the form (u, v, p) where (u, v) is a
+ pair of nodes and p is their WIC measure.
+
+ Raises
+ ------
+ NetworkXNotImplemented
+ If `G` is a `DiGraph`, a `Multigraph` or a `MultiDiGraph`.
+
+ NetworkXAlgorithmError
+ - If `delta` is less than or equal to zero.
+ - If no community information is available for a node in `ebunch` or in `G` (if `ebunch` is `None`).
+
+ NodeNotFound
+ If `ebunch` has a node that is not in `G`.
+
+ Examples
+ --------
+ >>> G = nx.Graph()
+ >>> G.add_edges_from([(0, 1), (0, 2), (0, 3), (1, 4), (2, 4), (3, 4)])
+ >>> G.nodes[0]["community"] = 0
+ >>> G.nodes[1]["community"] = 1
+ >>> G.nodes[2]["community"] = 0
+ >>> G.nodes[3]["community"] = 0
+ >>> G.nodes[4]["community"] = 0
+ >>> preds = nx.within_inter_cluster(G, [(0, 4)])
+ >>> for u, v, p in preds:
+ ... print(f"({u}, {v}) -> {p:.8f}")
+ (0, 4) -> 1.99800200
+ >>> preds = nx.within_inter_cluster(G, [(0, 4)], delta=0.5)
+ >>> for u, v, p in preds:
+ ... print(f"({u}, {v}) -> {p:.8f}")
+ (0, 4) -> 1.33333333
+
+ References
+ ----------
+ .. [1] Jorge Carlos Valverde-Rebaza and Alneu de Andrade Lopes.
+ Link prediction in complex networks based on cluster information.
+ In Proceedings of the 21st Brazilian conference on Advances in
+ Artificial Intelligence (SBIA'12)
+ https://doi.org/10.1007/978-3-642-34459-6_10
+ """
+ if delta <= 0:
+ raise nx.NetworkXAlgorithmError("Delta must be greater than zero")
+
+ def predict(u, v):
+ Cu = _community(G, u, community)
+ Cv = _community(G, v, community)
+ if Cu != Cv:
+ return 0
+ cnbors = nx.common_neighbors(G, u, v)
+ within = {w for w in cnbors if _community(G, w, community) == Cu}
+ inter = cnbors - within
+ return len(within) / (len(inter) + delta)
+
+ return _apply_prediction(G, predict, ebunch)
+
+
+def _community(G, u, community):
+ """Get the community of the given node."""
+ node_u = G.nodes[u]
+ try:
+ return node_u[community]
+ except KeyError as err:
+ raise nx.NetworkXAlgorithmError(
+ f"No community information available for Node {u}"
+ ) from err