{ "cells": [ { "cell_type": "markdown", "id": "91e5d15f", "metadata": {}, "source": [ "# Post-hoc edge inference via shared-embedding link prediction (node2vec)\n", "\n", "This notebook demonstrates **post-hoc, shared-embedding** function -> function edge inference using `MagnitudeEdgeKGE` (now a node2vec-style link predictor; the class name is kept for backward compatibility).\n", "\n", "Workflow:\n", "1. Train a GSNN on a partial graph.\n", "2. Run `MagnitudeEdgeInferer` to accumulate activation/gradient magnitude correlations.\n", "3. Threshold MEI scores into inferred positive edges.\n", "4. Pool inferred edges with kept-graph edges into one augmented directed graph.\n", "5. Learn a single shared node embedding table by skip-gram with negative sampling on random walks.\n", "6. Score held-out edges by the dot product of node embeddings.\n", "\n", "Same converging-tier DAG setup as notebooks 13-16 (**12 inputs -> 24 function nodes -> 12 outputs**, **16 held-out** edges).\n", "\n", "No `complex2` dependency." ] }, { "cell_type": "code", "execution_count": 75, "id": "2389a1df", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The autoreload extension is already loaded. To reload it, use:\n", " %reload_ext autoreload\n" ] } ], "source": [ "from matplotlib import pyplot as plt\n", "import numpy as np\n", "import networkx as nx\n", "import torch\n", "\n", "from gsnn.models.GSNN import GSNN\n", "from gsnn.simulate.nx2pyg import nx2pyg\n", "from gsnn.simulate.simulate import simulate\n", "from gsnn.optim.MagnitudeEdgeInferer import MagnitudeEdgeInferer\n", "from gsnn.optim.MagnitudeEdgeKGE import MagnitudeEdgeKGE\n", "\n", "from sklearn.metrics import roc_auc_score, roc_curve\n", "\n", "torch.manual_seed(0)\n", "np.random.seed(0)\n", "\n", "device = 'cuda' if torch.cuda.is_available() else 'cpu'\n", "\n", "%load_ext autoreload\n", "%autoreload 2" ] }, { "cell_type": "markdown", "id": "2aeb5514", "metadata": {}, "source": [ "## Build ground-truth graph and simulate data" ] }, { "cell_type": "code", "execution_count": 76, "id": "c0719ba9", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "functions: 24 | held-out val/test: 8/8\n" ] } ], "source": [ "def build_convergence_graph(n_tier_a=6):\n", " n = n_tier_a\n", " G = nx.DiGraph()\n", " func_func_edges_TRUE = []\n", " input_nodes = [f'in{i}' for i in range(n)]\n", " tier_a = [f'f{i}' for i in range(n)]\n", " tier_b = [f'f{n + k}' for k in range(n - 1)]\n", " tier_c = [f'f{2 * n - 1}']\n", " function_nodes = tier_a + tier_b + tier_c\n", " output_nodes = [f'o{k}' for k in range(n)]\n", " for i, u in enumerate(input_nodes):\n", " G.add_edge(u, tier_a[i])\n", " for k in range(n - 1):\n", " b = tier_b[k]\n", " for parent in (tier_a[k], tier_a[k + 1]):\n", " G.add_edge(parent, b)\n", " func_func_edges_TRUE.append((parent, b))\n", " sink = tier_c[0]\n", " for b in tier_b:\n", " G.add_edge(b, sink)\n", " func_func_edges_TRUE.append((b, sink))\n", " for k, b in enumerate(tier_b):\n", " G.add_edge(b, output_nodes[k])\n", " G.add_edge(sink, output_nodes[n - 1])\n", " return G, input_nodes, function_nodes, output_nodes, func_func_edges_TRUE\n", "\n", "def default_held_out_edges(n_tier_a, b2sink_stride=2):\n", " n = n_tier_a\n", " sink = f'f{2 * n - 1}'\n", " held = [(f'f{k}', f'f{n + k}') for k in range(1, n - 1)]\n", " held += [(f'f{n + k}', sink) for k in range(0, n - 1, b2sink_stride)]\n", " return held\n", "\n", "N_TIER_A = 12\n", "G, input_nodes, function_nodes, output_nodes, func_func_edges_TRUE = build_convergence_graph(N_TIER_A)\n", "N_FUNC = len(function_nodes)\n", "HELD_OUT_EDGES = default_held_out_edges(N_TIER_A)\n", "\n", "x_train, x_test, y_train, y_test = simulate(\n", " G, n_train=2000, n_test=500,\n", " input_nodes=input_nodes, output_nodes=output_nodes,\n", " noise_scale=0.15, special_functions=None,\n", ")\n", "x_train = torch.tensor(x_train, dtype=torch.float32).to(device)\n", "x_test = torch.tensor(x_test, dtype=torch.float32).to(device)\n", "y_train = torch.tensor(y_train, dtype=torch.float32).to(device)\n", "y_test = torch.tensor(y_test, dtype=torch.float32).to(device)\n", "y_mu, y_std = y_train.mean(0), y_train.std(0)\n", "y_train = (y_train - y_mu) / (y_std + 1e-8)\n", "y_test = (y_test - y_mu) / (y_std + 1e-8)\n", "\n", "held_out_set = set(HELD_OUT_EDGES)\n", "G_partial = G.copy()\n", "G_partial.remove_edges_from(HELD_OUT_EDGES)\n", "data = nx2pyg(G_partial, input_nodes, function_nodes, output_nodes)\n", "kept_edges = [e for e in func_func_edges_TRUE if e not in held_out_set]\n", "kept_ff_set = set(kept_edges)\n", "\n", "sink = f'f{2 * N_TIER_A - 1}'\n", "left_merge = [e for e in HELD_OUT_EDGES if e[1] != sink]\n", "b2sink = [e for e in HELD_OUT_EDGES if e[1] == sink]\n", "rng = np.random.default_rng(0)\n", "rng.shuffle(left_merge); rng.shuffle(b2sink)\n", "edges_val = left_merge[:len(left_merge)//2] + b2sink[:len(b2sink)//2]\n", "edges_test = left_merge[len(left_merge)//2:] + b2sink[len(b2sink)//2:]\n", "held_out_benchmark = set(edges_val) | set(edges_test)\n", "\n", "print(f'functions: {N_FUNC} | held-out val/test: {len(edges_val)}/{len(edges_test)}')" ] }, { "cell_type": "markdown", "id": "78c12d13", "metadata": {}, "source": [ "## Train GSNN (no auxiliary edge inference)" ] }, { "cell_type": "code", "execution_count": 77, "id": "ea5836de", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "epoch 1 | test MSE 0.7987\n", "epoch 10 | test MSE 0.4809\n", "epoch 20 | test MSE 0.4842\n", "epoch 30 | test MSE 0.4804\n" ] } ], "source": [ "BATCH_SIZE = 64\n", "\n", "model_kwargs = dict(\n", " channels=8, layers=6, share_layers=False, bias=True,\n", " add_function_self_edges=True, norm='groupbatch', dropout=0.,\n", " nonlin=torch.nn.ELU, node_mlp=False, checkpoint=False,\n", ")\n", "\n", "model = GSNN(data.edge_index_dict, data.node_names_dict, **model_kwargs).to(device)\n", "\n", "train_loader = torch.utils.data.DataLoader(\n", " torch.utils.data.TensorDataset(x_train, y_train),\n", " batch_size=BATCH_SIZE, shuffle=True, drop_last=True,\n", ")\n", "infer_loader = torch.utils.data.DataLoader(\n", " torch.utils.data.TensorDataset(x_train, y_train),\n", " batch_size=BATCH_SIZE, shuffle=False, drop_last=True,\n", ")\n", "gsnn_optim = torch.optim.AdamW(model.parameters(), lr=1e-3, weight_decay=0)\n", "crit = torch.nn.MSELoss()\n", "\n", "n_epochs = 30\n", "for epoch in range(n_epochs):\n", " model.train()\n", " for x_batch, y_batch in train_loader:\n", " gsnn_optim.zero_grad()\n", " loss = crit(model(x_batch), y_batch)\n", " loss.backward()\n", " gsnn_optim.step()\n", " if epoch == 0 or (epoch + 1) % 10 == 0 or epoch == n_epochs - 1:\n", " model.eval()\n", " with torch.no_grad():\n", " mse = crit(model(x_test), y_test).item()\n", " print(f'epoch {epoch+1:2d} | test MSE {mse:.4f}')" ] }, { "cell_type": "markdown", "id": "addf9545", "metadata": {}, "source": [ "## Fit MagnitudeEdgeInferer and inspect inferred positives" ] }, { "cell_type": "code", "execution_count": 81, "id": "e74ba2c4", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "MEI samples: 1984\n", "\n", "Top 10 inferred edges by corr (non-kept):\n" ] }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
src_funcdst_funccorrp_valueq_value
0f4f160.8893840.00.0
1f2f140.8814590.00.0
2f2f30.8785370.00.0
3f10f220.8769560.00.0
4f1f130.8669490.00.0
5f18f80.8635820.00.0
6f3f150.8630150.00.0
7f18f190.8620770.00.0
8f10f110.8612640.00.0
9f4f50.8576330.00.0
\n", "
" ], "text/plain": [ " src_func dst_func corr p_value q_value\n", "0 f4 f16 0.889384 0.0 0.0\n", "1 f2 f14 0.881459 0.0 0.0\n", "2 f2 f3 0.878537 0.0 0.0\n", "3 f10 f22 0.876956 0.0 0.0\n", "4 f1 f13 0.866949 0.0 0.0\n", "5 f18 f8 0.863582 0.0 0.0\n", "6 f3 f15 0.863015 0.0 0.0\n", "7 f18 f19 0.862077 0.0 0.0\n", "8 f10 f11 0.861264 0.0 0.0\n", "9 f4 f5 0.857633 0.0 0.0" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "FDR-significant non-kept edges (alpha=0.05): 106\n" ] } ], "source": [ "mei = MagnitudeEdgeInferer(model, data, reduction='l1')\n", "mei.fit(infer_loader, crit=crit, device=device, verbose=False)\n", "\n", "res_corr = mei.evaluate(layer_agg='max', score='corr')\n", "res_partial = mei.evaluate(layer_agg='max', score='partial')\n", "\n", "print(f'MEI samples: {mei.n}')\n", "print('\\nTop 10 inferred edges by corr (non-kept):')\n", "display(res_corr[~res_corr['has_edge']].head(10)[\n", " ['src_func', 'dst_func', 'corr', 'p_value', 'q_value']\n", "])\n", "\n", "n_fdr = ((res_corr['q_value'] <= 0.05) & ~res_corr['has_edge']).sum()\n", "print(f'\\nFDR-significant non-kept edges (alpha=0.05): {n_fdr}')" ] }, { "cell_type": "markdown", "id": "f468a050", "metadata": {}, "source": [ "## Train MagnitudeEdgeKGE (shared embedding, kept + inferred edges pooled)\n", "\n", "Held-out val/test edges are excluded from the inferred positive set to prevent leakage.\n", "A single embedding table is learned by skip-gram with negative sampling on random walks\n", "over the augmented graph. All edges - kept and inferred - push the same embeddings.\n", "\n", "Random-walk transition probabilities are weighted by `max(MEI corr, 0) ** walk_alpha`\n", "so the continuous MEI signal influences walk frequency. Larger `walk_alpha` concentrates\n", "walks on high-correlation edges; `walk_alpha=0` is equivalent to uniform walks\n", "(`walk_corr_weighted=False`). Kept edges receive a weight of at least the strongest\n", "inferred-edge weight (or override via `kept_edge_weight`)." ] }, { "cell_type": "code", "execution_count": 92, "id": "f30ee157", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "KGE params: 768\n", "true edges: 17 | inferred edges: 62\n", "epoch 1/200 | pairs 29758 | loss 1.2292 | val AUC 0.701\n", "epoch 20/200 | pairs 29778 | loss 1.1846 | val AUC 0.681\n", "epoch 40/200 | pairs 29838 | loss 1.1777 | val AUC 0.703\n" ] }, { "ename": "KeyboardInterrupt", "evalue": "", "output_type": "error", "traceback": [ "\u001b[31m---------------------------------------------------------------------------\u001b[39m", "\u001b[31mKeyboardInterrupt\u001b[39m Traceback (most recent call last)", "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[92]\u001b[39m\u001b[32m, line 25\u001b[39m\n\u001b[32m 21\u001b[39m \n\u001b[32m 22\u001b[39m print(\u001b[33mf'KGE params: {sum(p.numel() for p in kge.parameters())}'\u001b[39m)\n\u001b[32m 23\u001b[39m print(\u001b[33mf'true edges: {kge.true_heads.numel()} | inferred edges: {kge.inferred_heads.numel()}'\u001b[39m)\n\u001b[32m 24\u001b[39m \n\u001b[32m---> \u001b[39m\u001b[32m25\u001b[39m history = kge.fit(\n\u001b[32m 26\u001b[39m n_epochs=\u001b[32m200\u001b[39m,\n\u001b[32m 27\u001b[39m batch_size=\u001b[32m2048\u001b[39m,\n\u001b[32m 28\u001b[39m validation_edges=edges_val,\n", "\u001b[36mFile \u001b[39m\u001b[32m/home/exacloud/gscratch/mcweeney_lab/evans/GSNN/gsnn/optim/MagnitudeEdgeKGE.py:42\u001b[39m, in \u001b[36mfit\u001b[39m\u001b[34m(self, n_epochs, batch_size, validation_edges, verbose, seed)\u001b[39m\n\u001b[32m 32\u001b[39m \u001b[38;5;28;01mclass\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mMagnitudeEdgeKGE\u001b[39;00m(nn.Module):\n\u001b[32m 33\u001b[39m \u001b[38;5;250m \u001b[39m\u001b[33;03m'''\u001b[39;00m\n\u001b[32m 34\u001b[39m \u001b[33;03m Post-hoc node2vec edge inferrer for function -> function edges.\u001b[39;00m\n\u001b[32m 35\u001b[39m \n\u001b[32m 36\u001b[39m \u001b[33;03m Consumes a fitted ``MagnitudeEdgeInferer``, mines inferred positive edges\u001b[39;00m\n\u001b[32m 37\u001b[39m \u001b[33;03m from its correlation scores, builds an augmented directed graph from\u001b[39;00m\n\u001b[32m 38\u001b[39m \u001b[33;03m (kept + inferred) edges, and trains a single node embedding table by\u001b[39;00m\n\u001b[32m 39\u001b[39m \u001b[33;03m skip-gram with negative sampling on random walks. Parameter count is\u001b[39;00m\n\u001b[32m 40\u001b[39m \u001b[33;03m ``O(N * d)``.\u001b[39;00m\n\u001b[32m 41\u001b[39m \n\u001b[32m---> \u001b[39m\u001b[32m42\u001b[39m \u001b[33;03m Parameters\u001b[39;00m\n\u001b[32m 43\u001b[39m \u001b[33;03m ----------\u001b[39;00m\n\u001b[32m 44\u001b[39m \u001b[33;03m mei : MagnitudeEdgeInferer\u001b[39;00m\n\u001b[32m 45\u001b[39m \u001b[33;03m Fitted inferrer with accumulated statistics (``mei.n >= 3``).\u001b[39;00m\n\u001b[32m 46\u001b[39m \u001b[33;03m embedding_dim : int\u001b[39;00m\n\u001b[32m 47\u001b[39m \u001b[33;03m Embedding dimension.\u001b[39;00m\n\u001b[32m 48\u001b[39m \u001b[33;03m score : {'corr', 'partial'}\u001b[39;00m\n\u001b[32m 49\u001b[39m \u001b[33;03m MEI score column used to mine inferred positives.\u001b[39;00m\n\u001b[32m 50\u001b[39m \u001b[33;03m layer_agg : {'mean', 'max'}\u001b[39;00m\n\u001b[32m 51\u001b[39m \u001b[33;03m MEI layer aggregation for the score matrix.\u001b[39;00m\n\u001b[32m 52\u001b[39m \u001b[33;03m mining_strategy : {'fdr', 'topk_per_target'}\u001b[39;00m\n\u001b[32m 53\u001b[39m \u001b[33;03m How to select inferred positives from the MEI score table.\u001b[39;00m\n\u001b[32m 54\u001b[39m \u001b[33;03m fdr_alpha : float\u001b[39;00m\n\u001b[32m 55\u001b[39m \u001b[33;03m BH-FDR threshold when ``mining_strategy='fdr'``.\u001b[39;00m\n\u001b[32m 56\u001b[39m \u001b[33;03m top_k_per_target : int\u001b[39;00m\n\u001b[32m 57\u001b[39m \u001b[33;03m Top sources per target when ``mining_strategy='topk_per_target'``.\u001b[39;00m\n\u001b[32m 58\u001b[39m \u001b[33;03m exclude_edges : iterable of (src, dst)\u001b[39;00m\n\u001b[32m 59\u001b[39m \u001b[33;03m Held-out val/test edges to remove from inferred positives (anti-leakage).\u001b[39;00m\n\u001b[32m 60\u001b[39m \u001b[33;03m walks_per_node : int\u001b[39;00m\n\u001b[32m 61\u001b[39m \u001b[33;03m Number of random walks starting from each node per epoch.\u001b[39;00m\n\u001b[32m 62\u001b[39m \u001b[33;03m walk_length : int\u001b[39;00m\n\u001b[32m 63\u001b[39m \u001b[33;03m Length of each random walk (number of nodes).\u001b[39;00m\n\u001b[32m 64\u001b[39m \u001b[33;03m window_size : int\u001b[39;00m\n\u001b[32m 65\u001b[39m \u001b[33;03m Skip-gram context window (sliding distance within a walk).\u001b[39;00m\n\u001b[32m 66\u001b[39m \u001b[33;03m n_negatives : int\u001b[39;00m\n\u001b[32m 67\u001b[39m \u001b[33;03m Negative samples per positive (center, context) pair.\u001b[39;00m\n\u001b[32m 68\u001b[39m \u001b[33;03m walk_undirected : bool\u001b[39;00m\n\u001b[32m 69\u001b[39m \u001b[33;03m If True, treat the augmented graph as undirected for walk traversal.\u001b[39;00m\n\u001b[32m 70\u001b[39m \u001b[33;03m Walks rarely die at sinks, so coverage is better. Skip-gram positives\u001b[39;00m\n\u001b[32m 71\u001b[39m \u001b[33;03m are still emitted symmetrically. Default True.\u001b[39;00m\n\u001b[32m 72\u001b[39m \u001b[33;03m lr, weight_decay : float\u001b[39;00m\n\u001b[32m 73\u001b[39m \u001b[33;03m Optimizer settings.\u001b[39;00m\n\u001b[32m 74\u001b[39m \u001b[33;03m '''\u001b[39;00m\n\u001b[32m 76\u001b[39m _NODE_TYPE = \u001b[33m'\u001b[39m\u001b[33mfunction\u001b[39m\u001b[33m'\u001b[39m\n\u001b[32m 78\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34m__init__\u001b[39m(\n\u001b[32m 79\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m 80\u001b[39m mei: MagnitudeEdgeInferer,\n\u001b[32m (...)\u001b[39m\u001b[32m 95\u001b[39m weight_decay: \u001b[38;5;28mfloat\u001b[39m = \u001b[32m1e-4\u001b[39m,\n\u001b[32m 96\u001b[39m ):\n", "\u001b[36mFile \u001b[39m\u001b[32m/home/exacloud/gscratch/mcweeney_lab/evans/external/miniforge3/envs/gsnn/lib/python3.11/site-packages/torch/_tensor.py:521\u001b[39m, in \u001b[36mTensor.backward\u001b[39m\u001b[34m(self, gradient, retain_graph, create_graph, inputs)\u001b[39m\n\u001b[32m 511\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m has_torch_function_unary(\u001b[38;5;28mself\u001b[39m):\n\u001b[32m 512\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m handle_torch_function(\n\u001b[32m 513\u001b[39m Tensor.backward,\n\u001b[32m 514\u001b[39m (\u001b[38;5;28mself\u001b[39m,),\n\u001b[32m (...)\u001b[39m\u001b[32m 519\u001b[39m inputs=inputs,\n\u001b[32m 520\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m521\u001b[39m \u001b[30;43mtorch\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mautograd\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mbackward\u001b[39;49m\u001b[30;43m(\u001b[39;49m\n\u001b[32m 522\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mself\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mgradient\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mretain_graph\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mcreate_graph\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43minputs\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43minputs\u001b[39;49m\n\u001b[32m 523\u001b[39m \u001b[30;43m\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n", "\u001b[36mFile \u001b[39m\u001b[32m/home/exacloud/gscratch/mcweeney_lab/evans/external/miniforge3/envs/gsnn/lib/python3.11/site-packages/torch/autograd/__init__.py:289\u001b[39m, in \u001b[36mbackward\u001b[39m\u001b[34m(tensors, grad_tensors, retain_graph, create_graph, grad_variables, inputs)\u001b[39m\n\u001b[32m 284\u001b[39m retain_graph = create_graph\n\u001b[32m 286\u001b[39m \u001b[38;5;66;03m# The reason we repeat the same comment below is that\u001b[39;00m\n\u001b[32m 287\u001b[39m \u001b[38;5;66;03m# some Python versions print out the first line of a multi-line function\u001b[39;00m\n\u001b[32m 288\u001b[39m \u001b[38;5;66;03m# calls in the traceback and some print out the last line\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m289\u001b[39m \u001b[30;43m_engine_run_backward\u001b[39;49m\u001b[30;43m(\u001b[39;49m\n\u001b[32m 290\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mtensors\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 291\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mgrad_tensors_\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 292\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mretain_graph\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 293\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mcreate_graph\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 294\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43minputs\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 295\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mallow_unreachable\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43;01mTrue\u001b[39;49;00m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 296\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43maccumulate_grad\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43;01mTrue\u001b[39;49;00m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 297\u001b[39m \u001b[30;43m\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n", "\u001b[36mFile \u001b[39m\u001b[32m/home/exacloud/gscratch/mcweeney_lab/evans/external/miniforge3/envs/gsnn/lib/python3.11/site-packages/torch/autograd/graph.py:769\u001b[39m, in \u001b[36m_engine_run_backward\u001b[39m\u001b[34m(t_outputs, *args, **kwargs)\u001b[39m\n\u001b[32m 767\u001b[39m unregister_hooks = _register_logging_hooks_on_whole_graph(t_outputs)\n\u001b[32m 768\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m769\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[30;43mVariable\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_execution_engine\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mrun_backward\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43;03m# Calls into the C++ engine to run the backward pass\u001b[39;49;00m\n\u001b[32m 770\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mt_outputs\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43margs\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43mkwargs\u001b[39;49m\n\u001b[32m 771\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m)\u001b[39;49m \u001b[38;5;66;03m# Calls into the C++ engine to run the backward pass\u001b[39;00m\n\u001b[32m 772\u001b[39m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[32m 773\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m attach_logging_hooks:\n", "\u001b[31mKeyboardInterrupt\u001b[39m: " ] } ], "source": [ "kge = MagnitudeEdgeKGE(\n", " mei,\n", " embedding_dim=32,\n", " score='corr',\n", " layer_agg='max',\n", " mining_strategy='fdr',\n", " top_k_per_target=0,\n", " fdr_alpha=0.00001,\n", " walks_per_node=20,\n", " walk_length=10,\n", " window_size=5,\n", " n_negatives=25,\n", " walk_undirected=True,\n", " walk_corr_weighted=True,\n", " walk_alpha=2.0,\n", " kept_edge_weight=None,\n", " lr=1e-1,\n", " weight_decay=1e-4,\n", " exclude_edges=held_out_benchmark,\n", ").to(device)\n", "\n", "print(f'KGE params: {sum(p.numel() for p in kge.parameters())}')\n", "print(f'true edges: {kge.true_heads.numel()} | inferred edges: {kge.inferred_heads.numel()}')\n", "\n", "history = kge.fit(\n", " n_epochs=200,\n", " batch_size=2048,\n", " validation_edges=edges_val,\n", " verbose=True,\n", ")\n", "kge.load_best()" ] }, { "cell_type": "markdown", "id": "9456bae2", "metadata": {}, "source": [ "## Validation AUC vs epoch" ] }, { "cell_type": "code", "execution_count": 86, "id": "b89046e0", "metadata": {}, "outputs": [ { "data": { "image/png": "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MGAAU6lU7KWXXmKDBw9ma9asYWvXrmXt27dnsbGxkvc/8MADLCAggLVs2ZK9+uqr7Oeff2bz5s1j/v7+bNy4cZL1cvf25+bmspiYGNaiRQu2fPlytmHDBnb//fezli1bMgBsy5YtkvVMTk6WrA//7vv378++/vprtmHDBnbTTTcxf39/dvr0aWG+H3/8kfn5+bGbbrqJrV27ln3zzTdswIABrFWrVsz6VM3XXfzZct5++20GgP3111+S6Rs2bGAA2LfffitMmzp1Kvvkk09YZmYmy8zMZC+//DLTarVs/vz5kvfeeOONNscHADZ37lzh7yNHjrDAwEDWuXNntmrVKrZ+/Xo2atQoYZ9lZ2cL87788svsrbfeYj/88APbunUr+/DDD1lKSgobNmyYMM+pU6fY3XffzQCw3bt3C/8qKysZY+bj64EHHhDmz8vLYy1atGDR0dHsww8/ZD/99BN76qmnGAD2+OOPC/NlZ2cL38/o0aPZunXr2Lp161i3bt1YeHg4Kyoqcrh/9Xo9S0pKYsnJyeyjjz5imzZtYi+//DJTq9Vs6tSpwnzl5eWsU6dOTKfTsXfffZdt3LiRPf3008L+WL58uTDvRx99xACwu+66i33//fds5cqVrH379iw5OVlybLny+5PzwAMPMJVKxVq1asUWLlzIfvnlF7Zx40aXlvviiy8yAGzChAnsm2++YT///DNbvHgxe/HFF4V50tPThfPyDz/8wD777DPWunVrptPphOMyPz+fBQQEsDlz5kjWsba2liUkJLAJEyYI0z7//HOmUCjYHXfcwdasWcO+++47Nm7cOKZUKtmmTZuE+eydI6uqqlhcXBy7//77JZ9VU1PDEhIS2D333ONwvxHvQ4Es8Xo8kAXAdDody8vLk53vt99+YwDYrFmzbF6rra2VBKgmk0l47YEHHhCWb/3v5ptvdrhub7zxBgPg8ILHA9lbb71VMv3rr78WLsxyTCYTq6mpYefOnWMA2Pr164XX+En6pZdekrxn9+7dDAB78803JdPPnz/PtFote/bZZxljjF29epVpNBp25513Sub79ddfGQCnAtlVq1YxAGz16tWS6Xv27GEA2NKlS4VpycnJTKvVsgsXLgjTsrKyGAAWHx/PysrKhOnr1q2zCbL4d/T2229LPuvVV19lANjOnTubbPufe+45plAoWFZWlmTeESNG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L+Dbb7/F8OHD8dJLLyEwMBDvv/++Tf7ioEGDEB4ejmnTpmHu3LlQqVRYuXKlzU0DAOEmZNGiRRgzZgyUSiW6d+8uG7j885//xGeffYaxY8diwYIFSE5Oxg8//IClS5fi8ccfR/v27Ru0XdYWLFiAzMxMDBo0CE8//TQ6dOiAyspKnD17Fhs2bMCHH36IxMRETJkyBW+99RamTJmCV199Fe3atcOGDRuwceNGyfL8/Pwwf/58PPbYY7j77rvx97//HUVFRZg/fz7i4+Ph51fX9tRUvz9nl9uqVSs8//zzePnll1FRUYH77rsPOp0OR48eRUFBAebPn4+wsDC8+OKLeP755zFlyhTcd999KCwsxPz586HRaDB37lzJZ3fs2BGpqalYuHAhzp8/j48//ljyenBwMN5991088MADuHLlCu6++27ExMQgPz8fBw8eRH5+vsPA2tr06dORlpYGhUKBJ554wuV9RbyEx7qZEeIkXrVgz549Nq/xXusTJkyQlKfavn07S0tLY4mJiUylUgmlgB5//HG2d+9eyTIcVS0AwE6ePGl33b7//ns2ZswY1qJFCxYQEMBiYmLYrbfeynbs2CHMw6sWfPPNN5L38h7T4tI7R48eZSNGjGAhISEsPDyc3XPPPSwnJ8emVzjvkZufny+7XsuWLWMDBgxgQUFBTKvVsjZt2rApU6ZItt1kMrGFCxeypKQkFhAQwLp3786+++472V7p9tTU1LA33niD9ejRg2k0GhYcHMw6duzIHnvsMcl+S05OZmPHjrV5PwD25JNPyu6X119/XZjGS6T9+eef7KabbmJarZZFRESwxx9/nJWWljb59vPvRaPRsIiICPbQQw+x9evXO121wHob+T4R97RnjLG1a9eybt26CaXGXnvtNfb000+z8PBwyXzOlt8SGzRoEANgt5f5smXLWIcOHZharWatW7dmCxcuZJ988olNlQFnqhYwZq4AMXDgQKZWq1lcXBz797//zT7++GOb5e3atYulpqaywMBAFh0dzR5++GG2f/9+m99GVVUVe/jhh1l0dDRTKBSS5cjty3PnzrFJkyaxyMhIplKpWIcOHdjrr78u6RUvd6w52iY5+fn57Omnn2YpKSlMpVKxiIgI1qdPHzZnzhzJsXnhwgV21113seDgYBYSEsLuuusutmvXLpvtZIyxjz/+mLVt25YFBASw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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "if 'val_auc' in history:\n", " fig, ax = plt.subplots(figsize=(7, 4))\n", " ax.plot(range(1, len(history['val_auc']) + 1), history['val_auc'], marker='o', ms=3)\n", " ax.axhline(0.5, color='k', ls=':', alpha=0.5, label='random')\n", " ax.set_xlabel('epoch'); ax.set_ylabel('val AUC')\n", " ax.set_title('KGE shared-embedding: validation edge recovery')\n", " ax.legend(); plt.tight_layout(); plt.show()" ] }, { "cell_type": "markdown", "id": "e2b7262e", "metadata": {}, "source": [ "## Head-to-head comparison on test held-out edges" ] }, { "cell_type": "code", "execution_count": 87, "id": "384a0fa5", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Test-set ROC-AUC:\n", " MEI corr : 0.872\n", " MEI partial : 0.873\n", " KGE joint (kept + inferred) : 0.463\n", " KGE inferred-only : 0.634\n", " KGE true-only : 0.190\n", "\n", "Within-target ranking (test held-out):\n", " MEI corr : MRR=0.672 top@1=0.625\n", " MEI partial : MRR=0.674 top@1=0.625\n", " KGE joint (kept + inferred) : MRR=0.083 top@1=0.000\n", " KGE inferred-only : MRR=0.125 top@1=0.000\n", " KGE true-only : MRR=0.065 top@1=0.000\n" ] } ], "source": [ "def roc_auc_for_edges(res_df, positive_edges, score_col='score'):\n", " pos_set = set(positive_edges)\n", " pos = res_df[res_df.apply(lambda r: (r['src_func'], r['dst_func']) in pos_set, axis=1)][score_col].dropna().values\n", " neg = res_df[~res_df.apply(lambda r: (r['src_func'], r['dst_func']) in pos_set, axis=1)]\n", " neg = neg[neg.apply(lambda r: (r['src_func'], r['dst_func']) not in kept_ff_set, axis=1)][score_col].dropna().values\n", " if len(pos) == 0 or len(neg) == 0:\n", " return float('nan')\n", " return roc_auc_score(\n", " np.concatenate([np.ones(len(pos)), np.zeros(len(neg))]),\n", " np.concatenate([pos, neg]),\n", " )\n", "\n", "def fit_kge_variant(name, *, edges_to_use='joint', n_epochs=200):\n", " \"\"\"Refit a KGE variant. ``edges_to_use`` controls the positive pool.\"\"\"\n", " k = MagnitudeEdgeKGE(\n", " mei,\n", " embedding_dim=32,\n", " score='corr',\n", " layer_agg='max',\n", " mining_strategy='fdr',\n", " fdr_alpha=0.05,\n", " walks_per_node=20, walk_length=10, window_size=5, n_negatives=5,\n", " walk_undirected=True, walk_corr_weighted=True, walk_alpha=2.0,\n", " lr=1e-2, weight_decay=1e-4,\n", " exclude_edges=held_out_benchmark,\n", " ).to(device)\n", " if edges_to_use == 'inferred':\n", " k.pos_heads = k.inferred_heads\n", " k.pos_tails = k.inferred_tails\n", " elif edges_to_use == 'true':\n", " k.pos_heads = k.true_heads\n", " k.pos_tails = k.true_tails\n", " pm = torch.zeros(k.N, k.N, dtype=torch.bool)\n", " if k.pos_heads.numel() > 0:\n", " pm[k.pos_heads, k.pos_tails] = True\n", " k.pos_mask = pm\n", " k._build_adjacency()\n", " k.fit(n_epochs=n_epochs, batch_size=2048, validation_edges=edges_val, verbose=False)\n", " k.load_best()\n", " return k\n", "\n", "res_kge_joint = kge.evaluate()\n", "kge_inferred_only = fit_kge_variant('inferred-only', edges_to_use='inferred')\n", "kge_true_only = fit_kge_variant('true-only', edges_to_use='true')\n", "res_kge_inf = kge_inferred_only.evaluate()\n", "res_kge_true = kge_true_only.evaluate()\n", "\n", "results = {\n", " 'MEI corr': (res_corr, 'corr'),\n", " 'MEI partial': (res_partial, 'corr'),\n", " 'KGE joint (kept + inferred)': (res_kge_joint, 'score'),\n", " 'KGE inferred-only': (res_kge_inf, 'score'),\n", " 'KGE true-only': (res_kge_true, 'score'),\n", "}\n", "\n", "print('Test-set ROC-AUC:')\n", "for name, (df, col) in results.items():\n", " print(f' {name:28s}: {roc_auc_for_edges(df, edges_test, score_col=col):.3f}')\n", "\n", "print('\\nWithin-target ranking (test held-out):')\n", "for name, (df, col) in results.items():\n", " score_col = 'score' if col == 'score' else col\n", " if col != 'score':\n", " df = df.rename(columns={'corr': 'score'})\n", " _, summary = MagnitudeEdgeKGE.evaluate_target_ranking(df, edges_test, score_col='score')\n", " print(f\" {name:28s}: MRR={summary['mrr']:.3f} top@1={summary['top@1']:.3f}\")" ] }, { "cell_type": "markdown", "id": "cc8329a9", "metadata": {}, "source": [ "## ROC curves" ] }, { "cell_type": "code", "execution_count": null, "id": "2df4755c", "metadata": {}, "outputs": [ { "data": { "image/png": "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HFutVqNRo0aZjpG98/sls/HCmbl586ZRsmRJ4+mnn77HK8z5GNk7vw8yGyPbrVs3o0mTJkZycvI9z3+nqVOnGoBx6NChHO8rUpioR1akCChVqhSvvfYaL7/8MvPnz7ffkf3hhx9y9OhRHnvsMX755Rf69++Pm5sbO3bs4P3338fHx4fvv//ePofsrX1OnTrFiBEjWLt2LQ888AD+/v5ERUWxbt065syZw8KFC+3jDLt27crmzZvvOU62Zs2aeHh48O2331K/fn28vb2pUKECFSpUYObMmfTu3ZuePXsyYsQIKlasSHR0NH/++Se//fYbS5YsAdKmeerXrx+NGzemVKlS/Pnnn8ybN4+2bdvae50aNWoEwLvvvkvv3r1xcnKicePGuLq63tc1njBhAt9//z2dOnXihRdeoHHjxthsNs6ePctPP/3E3/72N1q3bp3lvrNnz6Zv3768/fbb+Pv78+233+aoF/nNN99k5cqVhISE8I9//AM/Pz++/fZbVq1axXvvvYevry+QNka1bt26vPjii6SmplKqVCmWLl3K1q1bMxyzUaNG/PDDD0yfPp2goCDMZrO9pz8rjzzyCBMnTuSRRx4hOTk5wwpm//jHPzh//jxdu3alUqVK3Lhxg48++ggXFxc6d+6c7dd7N1OmTKF79+6EhITw4osv4urqyrRp0zh48CALFizItZW0vL29+eSTT3j88ceJjo5m0KBBlCtXjqtXr3LgwAGuXr3K9OnTAfjnP/9Jr1696N69O3/729+wWq28++67eHl5ER0dbT9mr169aN++PX/729+IjY0lKCiI7du38/XXXwNgNv//EX8fffQRHTp0oGPHjjz99NNUq1aNmzdvcuLECVasWGGfQaJ///72uaXLli3LmTNnmDp1KlWrVqV27dq5ci1ECixHJ2kRyb6sepgMI20GgipVqhi1a9dO18OakpJifPbZZ0br1q0Nb29vw83Nzahbt67x8ssv2+80v1Nqaqrx1VdfGV26dDH8/PwMZ2dno2zZskbv3r2N+fPnp+v1vXXXf3YsWLDAqFevnuHi4pKh9+nAgQPGQw89ZJQrV85wcXExAgICjC5duhgzZsywb/Pqq68aLVq0MEqVKmW4ubkZNWrUMF544YV0ryM5OdkYM2aMUbZsWcNkMmV6B//tstsjaxiGERcXZ/zf//2fUbduXcPV1dXw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69WrVylbtizdu3fniy++oF27diQkJPDNN9/w2muv/aVz1K1bl8uXL5OUlIS7uzt79uzh6tWrXLx40d4THB0dTdWqVbl69Sq1a9fGbDazevVq+vTpg81mY+bMmfTo0QOALl26UL16dZ577jmmTp2Ku7s7qampfPzxxzz55JPZ6pENCgoiKSmJTZs2ERwczMyZMxkwYECmwwJq1KjB2rVr7b3RK1euJDAwMN02s2fPZvTo0enaUlNTGTJkCH5+fnz++ecZ/jCwWq2cOnUqw7GkYNKsBVKobNy4kS+++ILIyEg8PDx48MEHeeSRRxRiRcShRo4cmeFGqltujZG99RESEnLP4/33v/8lISGBwMBAmjZtyt///ncA3njjDUwmE40aNaJ169aEhobap/PKKXd3d7p168bPP/8MpI0lHTJkSLrxsH5+fnTr1o158+bh4uLC0qVL+eCDD2jatClNmjTBbDbbbwYzmUysWrUKV1dXGjZsSGBgIE2aNCEyMtLea3ovZrOZb775hueff546deqwatUq+4wCAH369LEP05g0aRIxMTH2c0VFRfHPf/7Tvu3JkyfZu3cvDz/8cLpzLFq0iB9++IE9e/bQrFkzmjZtyvjx4+3Pb926ldatW+Pr65vDKyqOYDKyGnxSRMXGxuLr60tMTEy+hp+EuBg8308bqJ7w4lk8vXP2DWJJtvL585sBePKjzri43f1trwRLAq3ntwZg59CdeLp4/oWq84ctIYGjzYMAqPvbXsyeWde6du1atm/fToMGDejTp89d3zYTkaIhKSmJ06dPU7169WwHIsmenTt38s9//pOVK1c6upQCY8iQIYwZMybDPLqS+7L63s5JVis4782IZMJisZCYmGj/Qu7SpQvVqlWjbt26Dq5MRKTwa926NQMGDODmzZvp5pItrpKSkggODlaILUQUZKXAOnPmDMuXL8fT05ORI0diNptxcXFRiBURyUVjxoxxdAkFhru7e47mvRXHU5CVAiclJYWff/6ZXbt2YRgGKSkp3LhxQwsbiIiISDoKslKgnDp9mpXr1nHjxg0AmjdvTo8ePTQuTkRERDJQkJUCwWIYbI2P4/L8+ZhcXChZsiT9+/dPt+KMiIiIyO0UZKVAMANXUlMBaNWqFV27dsXNzc2xRYmIiEiBpnlk88n9zHJmGAaWZGsuVpP7DMPAlpCQo4/4a9dI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g4NZvHgxn332WZb1Pvfcc9SrV4+lS5dy5coVgoKCaNq0Ka1atQLgxo0bbNu2jatXr1KrVi1GjhxpXyoVoEKFCnTr1o358+czZswYIiMjWb9+fabBbPPmzbRp0yZd25o1a6hYsSINGzZk9OjRzJo1iy5dutzzOgPs3bv3rsvffv3113z44YeZPvfEE08wfvx4zp49m24Z+GrVqnH27Nm7njcpKYkFCxakWyHr999/Z+3atWzcuJF//vOfGfbZvHkzTZs2xcvLixdeeCHd8Ih27doxYcKEu56zsFKQLUT+OPiH/Ydc7dq16devH76+2V/uVkREclffvn1ZsmQJ48aNo3LlylluFxISQlRUFDabjUOHDtnbszO04E69e/fGz88PgLZt2/LHH39kut2yZcvYs2cPQUFpod9qtaabhrFfv37pbgh2d3fnkUceAdJWhNywYUO6Vavi4uI4cuQINWvWxNPT0/429UMPPcSTTz6ZZb3r16/nwIEDAJQrV46BAwfy888/24Pso48+CkDZsmWpUaMGp0+fThdkAZ5//nmeeuopxowZw8yZMxk6dGim1+38+fMEBASka5s1axajRo0C4LHHHuPNN9/k+vXrlCpVKstOoOx2Dg0fPpzhw4ffc7vbj5ed3v7vv/+e2rVr06hRIwAsFgtPPPEEc+bMyXQqzX79+vHQQw/h6enJn3/+SY8ePahUqZI91AcEBHD58mUsFkuRW9FTQbYQaRTYiGPHj9CgQQOaNGmiXlgRKZZMHh7U/W1vnp8jO1566SUaNmxIcHAwGzdupEqVKpQrV46KFSuya9cu+/jGjRs3EhERQYsWLe67ttvXpHdycsryxiHDMPi///s/e4i7051B0MvLy/57xWazYTKZ2L17d4bgcyuUZmb9+vX2m5AGDx7M66+/DmQMhrc/zs7radWqFe7u7mzevJkvvviCDRs2ZHp+T09PEhMT7Y+vXLnC6tWr2b17t73X3GKxMH/+fMaPH0/ZsmU5ffp0umNERUXZA35QUBDbt2/nhRdeyPR82emRrVKlChEREfb2M2fOUKVKlUz3uWXWrFmMHj3a/vjSpUucPHnSftPWjRs3MAyD69evM2vWLMqUKWPftn79+vTp04dff/3VHmSTkpJwcXEpciEWNEa2QLt48SKLlyzGak37pjabzQwdOpSmTZsqxIpIsWUymTB7eubp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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig, ax = plt.subplots(figsize=(7, 5))\n", "for name, (df, col) in results.items():\n", " pos_set = set(edges_test)\n", " pos = df[df.apply(lambda r: (r['src_func'], r['dst_func']) in pos_set, axis=1)][col].dropna().values\n", " neg = df[~df.apply(lambda r: (r['src_func'], r['dst_func']) in pos_set, axis=1)]\n", " neg = neg[neg.apply(lambda r: (r['src_func'], r['dst_func']) not in kept_ff_set, axis=1)][col].dropna().values\n", " if len(pos) == 0 or len(neg) == 0:\n", " continue\n", " y_true = np.concatenate([np.ones(len(pos)), np.zeros(len(neg))])\n", " y_score = np.concatenate([pos, neg])\n", " auc = roc_auc_score(y_true, y_score)\n", " fpr, tpr, _ = roc_curve(y_true, y_score)\n", " ax.plot(fpr, tpr, label=f'{name} (AUC={auc:.3f})')\n", "ax.plot([0, 1], [0, 1], 'k--', alpha=0.5)\n", "ax.set_xlabel('FPR'); ax.set_ylabel('TPR')\n", "ax.set_title('ROC: test held-out vs non-edges')\n", "ax.legend(fontsize=8); plt.tight_layout(); plt.show()" ] }, { "cell_type": "markdown", "id": "f5e42c2b", "metadata": {}, "source": [ "## Discussion\n", "\n", "`MagnitudeEdgeKGE` is a **post-hoc shared-embedding link predictor** on top of Tier-0 magnitude correlation:\n", "\n", "1. **MEI mining** - FDR-significant (or top-K) non-kept edges from `MagnitudeEdgeInferer` become inferred positives.\n", "2. **Structural prior** - kept function-function edges and inferred edges are pooled into a single augmented directed graph; every edge pushes the same node embedding table.\n", "3. **Anti-leakage** - pass held-out benchmark edges via `exclude_edges` so they are never trained as inferred positives.\n", "4. **Scalability** - parameter count is `O(N * d)` (one shared embedding table) rather than `O(N^2)`.\n", "\n", "Compare ablations:\n", "- **MEI corr / partial** - direct correlation scores (no embedding).\n", "- **KGE true-only** - structural link prediction baseline trained on kept edges only.\n", "- **KGE inferred-only** - MEI-mined positives only, no graph prior.\n", "- **KGE joint** - both pooled into one shared embedding space.\n", "\n", "The shared embedding will only beat raw MEI correlation when (a) the kept graph is large and densely structured (so transitivity through kept edges constrains test edges) and (b) MEI per-edge estimates are noisy enough that pooling helps. On small toy graphs MEI correlation is hard to beat because the mining step discards continuous score information." ] } ], "metadata": { "kernelspec": { "display_name": "gsnn", "language": "python", "name": "python3" }, "language_info": { "name": "python", "version": "3.11.6" } }, "nbformat": 4, "nbformat_minor": 5 }