henribonamy commited on
Commit
6a03f6d
·
verified ·
1 Parent(s): 197b2d3

Upload netfm/evaluate/baselines.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. netfm/evaluate/baselines.py +67 -0
netfm/evaluate/baselines.py ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import networkx as nx
3
+ from sklearn.metrics import roc_auc_score, average_precision_score
4
+ from torch_geometric.data import Data
5
+ from torch_geometric.utils import to_networkx
6
+
7
+
8
+ def common_neighbors_scores(
9
+ G: nx.Graph, edges: list[tuple[int, int]]
10
+ ) -> np.ndarray:
11
+ """Compute Common Neighbors score for each edge pair."""
12
+ return np.array([len(list(nx.common_neighbors(G, u, v))) for u, v in edges])
13
+
14
+
15
+ def jaccard_scores(
16
+ G: nx.Graph, edges: list[tuple[int, int]]
17
+ ) -> np.ndarray:
18
+ """Compute Jaccard coefficient for each edge pair."""
19
+ preds = nx.jaccard_coefficient(G, edges)
20
+ return np.array([p for _, _, p in preds])
21
+
22
+
23
+ def adamic_adar_scores(
24
+ G: nx.Graph, edges: list[tuple[int, int]]
25
+ ) -> np.ndarray:
26
+ """Compute Adamic-Adar index for each edge pair."""
27
+ preds = nx.adamic_adar_index(G, edges)
28
+ return np.array([p for _, _, p in preds])
29
+
30
+
31
+ def preferential_attachment_scores(
32
+ G: nx.Graph, edges: list[tuple[int, int]]
33
+ ) -> np.ndarray:
34
+ """Compute Preferential Attachment score for each edge pair."""
35
+ preds = nx.preferential_attachment(G, edges)
36
+ return np.array([p for _, _, p in preds])
37
+
38
+
39
+ def evaluate_link_prediction_baselines(
40
+ data: Data,
41
+ pos_edges: np.ndarray,
42
+ neg_edges: np.ndarray,
43
+ ) -> dict[str, dict[str, float]]:
44
+ """Run all heuristic baselines for link prediction."""
45
+ G = to_networkx(data, to_undirected=True)
46
+
47
+ pos_list = list(zip(pos_edges[0], pos_edges[1]))
48
+ neg_list = list(zip(neg_edges[0], neg_edges[1]))
49
+ all_edges = pos_list + neg_list
50
+ labels = np.concatenate([np.ones(len(pos_list)), np.zeros(len(neg_list))])
51
+
52
+ results = {}
53
+ for name, scorer in [
54
+ ("common_neighbors", common_neighbors_scores),
55
+ ("jaccard", jaccard_scores),
56
+ ("adamic_adar", adamic_adar_scores),
57
+ ("preferential_attachment", preferential_attachment_scores),
58
+ ]:
59
+ scores = scorer(G, all_edges)
60
+ if np.std(scores) < 1e-10:
61
+ results[name] = {"auc": 0.5, "ap": 0.5}
62
+ continue
63
+ results[name] = {
64
+ "auc": roc_auc_score(labels, scores),
65
+ "ap": average_precision_score(labels, scores),
66
+ }
67
+ return results