stellargraph/stellargraph

View on GitHub
demos/link-prediction/gcn-link-prediction.ipynb

Summary

Maintainability
Test Coverage
{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "0",
   "metadata": {},
   "source": [
    "# Link prediction with GCN"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1",
   "metadata": {
    "nbsphinx": "hidden",
    "tags": [
     "CloudRunner"
    ]
   },
   "source": [
    "<table><tr><td>Run the latest release of this notebook:</td><td><a href=\"https://mybinder.org/v2/gh/stellargraph/stellargraph/master?urlpath=lab/tree/demos/link-prediction/gcn-link-prediction.ipynb\" alt=\"Open In Binder\" target=\"_parent\"><img src=\"https://mybinder.org/badge_logo.svg\"/></a></td><td><a href=\"https://colab.research.google.com/github/stellargraph/stellargraph/blob/master/demos/link-prediction/gcn-link-prediction.ipynb\" alt=\"Open In Colab\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\"/></a></td></tr></table>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2",
   "metadata": {},
   "source": [
    "In this example, we use our implementation of the [GCN](https://arxiv.org/abs/1609.02907) algorithm to build a model that predicts citation links in the Cora dataset (see below). The problem is treated as a supervised link prediction problem on a homogeneous citation network with nodes representing papers (with attributes such as binary keyword indicators and categorical subject) and links corresponding to paper-paper citations. \n",
    "\n",
    "To address this problem, we build a model with the following architecture. First we build a two-layer GCN model that takes labeled node pairs (`citing-paper` -> `cited-paper`)  corresponding to possible citation links, and outputs a pair of node embeddings for the `citing-paper` and `cited-paper` nodes of the pair. These embeddings are then fed into a link classification layer, which first applies a binary operator to those node embeddings (e.g., concatenating them) to construct the embedding of the potential link. Thus obtained link embeddings are passed through the dense link classification layer to obtain link predictions - probability for these candidate links to actually exist in the network. The entire model is trained end-to-end by minimizing the loss function of choice (e.g., binary cross-entropy between predicted link probabilities and true link labels, with true/false citation links having labels 1/0) using stochastic gradient descent (SGD) updates of the model parameters, with minibatches of 'training' links fed into the model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "3",
   "metadata": {
    "nbsphinx": "hidden",
    "tags": [
     "CloudRunner"
    ]
   },
   "outputs": [],
   "source": [
    "# install StellarGraph if running on Google Colab\n",
    "import sys\n",
    "if 'google.colab' in sys.modules:\n",
    "  %pip install -q stellargraph[demos]==1.3.0b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "4",
   "metadata": {
    "nbsphinx": "hidden",
    "tags": [
     "VersionCheck"
    ]
   },
   "outputs": [],
   "source": [
    "# verify that we're using the correct version of StellarGraph for this notebook\n",
    "import stellargraph as sg\n",
    "\n",
    "try:\n",
    "    sg.utils.validate_notebook_version(\"1.3.0b\")\n",
    "except AttributeError:\n",
    "    raise ValueError(\n",
    "        f\"This notebook requires StellarGraph version 1.3.0b, but a different version {sg.__version__} is installed.  Please see <https://github.com/stellargraph/stellargraph/issues/1172>.\"\n",
    "    ) from None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "5",
   "metadata": {},
   "outputs": [],
   "source": [
    "import stellargraph as sg\n",
    "from stellargraph.data import EdgeSplitter\n",
    "from stellargraph.mapper import FullBatchLinkGenerator\n",
    "from stellargraph.layer import GCN, LinkEmbedding\n",
    "\n",
    "\n",
    "from tensorflow import keras\n",
    "from sklearn import preprocessing, feature_extraction, model_selection\n",
    "\n",
    "from stellargraph import globalvar\n",
    "from stellargraph import datasets\n",
    "from IPython.display import display, HTML\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6",
   "metadata": {},
   "source": [
    "## Loading the CORA network data"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7",
   "metadata": {
    "tags": [
     "DataLoadingLinks"
    ]
   },
   "source": [
    "(See [the \"Loading from Pandas\" demo](../basics/loading-pandas.ipynb) for details on how data can be loaded.)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "8",
   "metadata": {
    "tags": [
     "DataLoading"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "The Cora dataset consists of 2708 scientific publications classified into one of seven classes. The citation network consists of 5429 links. Each publication in the dataset is described by a 0/1-valued word vector indicating the absence/presence of the corresponding word from the dictionary. The dictionary consists of 1433 unique words."
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "dataset = datasets.Cora()\n",
    "display(HTML(dataset.description))\n",
    "G, _ = dataset.load(subject_as_feature=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "StellarGraph: Undirected multigraph\n",
      " Nodes: 2708, Edges: 5429\n",
      "\n",
      " Node types:\n",
      "  paper: [2708]\n",
      "    Features: float32 vector, length 1440\n",
      "    Edge types: paper-cites->paper\n",
      "\n",
      " Edge types:\n",
      "    paper-cites->paper: [5429]\n",
      "        Weights: all 1 (default)\n",
      "        Features: none\n"
     ]
    }
   ],
   "source": [
    "print(G.info())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "10",
   "metadata": {},
   "source": [
    "We aim to train a link prediction model, hence we need to prepare the train and test sets of links and the corresponding graphs with those links removed.\n",
    "\n",
    "We are going to split our input graph into a train and test graphs using the EdgeSplitter class in `stellargraph.data`. We will use the train graph for training the model (a binary classifier that, given two nodes, predicts whether a link between these two nodes should exist or not) and the test graph for evaluating the model's performance on hold out data.\n",
    "Each of these graphs will have the same number of nodes as the input graph, but the number of links will differ (be reduced) as some of the links will be removed during each split and used as the positive samples for training/testing the link prediction classifier."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "11",
   "metadata": {},
   "source": [
    "From the original graph G, extract a randomly sampled subset of test edges (true and false citation links) and the reduced graph G_test with the positive test edges removed:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "12",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "** Sampled 542 positive and 542 negative edges. **\n"
     ]
    }
   ],
   "source": [
    "# Define an edge splitter on the original graph G:\n",
    "edge_splitter_test = EdgeSplitter(G)\n",
    "\n",
    "# Randomly sample a fraction p=0.1 of all positive links, and same number of negative links, from G, and obtain the\n",
    "# reduced graph G_test with the sampled links removed:\n",
    "G_test, edge_ids_test, edge_labels_test = edge_splitter_test.train_test_split(\n",
    "    p=0.1, method=\"global\", keep_connected=True\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "13",
   "metadata": {},
   "source": [
    "The reduced graph G_test, together with the test ground truth set of links (edge_ids_test, edge_labels_test), will be used for testing the model.\n",
    "\n",
    "Now repeat this procedure to obtain the training data for the model. From the reduced graph G_test, extract a randomly sampled subset of train edges (true and false citation links) and the reduced graph G_train with the positive train edges removed:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "14",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "** Sampled 488 positive and 488 negative edges. **\n"
     ]
    }
   ],
   "source": [
    "# Define an edge splitter on the reduced graph G_test:\n",
    "edge_splitter_train = EdgeSplitter(G_test)\n",
    "\n",
    "# Randomly sample a fraction p=0.1 of all positive links, and same number of negative links, from G_test, and obtain the\n",
    "# reduced graph G_train with the sampled links removed:\n",
    "G_train, edge_ids_train, edge_labels_train = edge_splitter_train.train_test_split(\n",
    "    p=0.1, method=\"global\", keep_connected=True\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "15",
   "metadata": {},
   "source": [
    "G_train, together with the train ground truth set of links (edge_ids_train, edge_labels_train), will be used for training the model."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "16",
   "metadata": {},
   "source": [
    "## Creating the GCN link model"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "17",
   "metadata": {},
   "source": [
    "Next, we create the link generators for the train and test link examples to the model. The link generators take the pairs of nodes (`citing-paper`, `cited-paper`) that are given in the `.flow` method to the Keras model, together with the corresponding binary labels indicating whether those pairs represent true or false links.\n",
    "\n",
    "The number of epochs for training the model:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "18",
   "metadata": {},
   "outputs": [],
   "source": [
    "epochs = 50"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "19",
   "metadata": {},
   "source": [
    "For training we create a generator on the `G_train` graph, and make an iterator over the training links using the generator's `flow()` method:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "20",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Using GCN (local pooling) filters...\n"
     ]
    }
   ],
   "source": [
    "train_gen = FullBatchLinkGenerator(G_train, method=\"gcn\")\n",
    "train_flow = train_gen.flow(edge_ids_train, edge_labels_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "21",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Using GCN (local pooling) filters...\n"
     ]
    }
   ],
   "source": [
    "test_gen = FullBatchLinkGenerator(G_test, method=\"gcn\")\n",
    "test_flow = test_gen.flow(edge_ids_test, edge_labels_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "22",
   "metadata": {},
   "source": [
    "Now we can specify our machine learning model, we need a few more parameters for this:\n",
    "\n",
    " * the `layer_sizes` is a list of hidden feature sizes of each layer in the model. In this example we use two GCN layers with 16-dimensional hidden node features at each layer.\n",
    " * `activations` is a list of activations applied to each layer's output\n",
    " * `dropout=0.3` specifies a 30% dropout at each layer. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "23",
   "metadata": {},
   "source": [
    "We create a GCN model as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "24",
   "metadata": {},
   "outputs": [],
   "source": [
    "gcn = GCN(\n",
    "    layer_sizes=[16, 16], activations=[\"relu\", \"relu\"], generator=train_gen, dropout=0.3\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "25",
   "metadata": {},
   "source": [
    "To create a Keras model we now expose the input and output tensors of the GCN model for link prediction, via the `GCN.in_out_tensors` method:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "26",
   "metadata": {},
   "outputs": [],
   "source": [
    "x_inp, x_out = gcn.in_out_tensors()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "27",
   "metadata": {},
   "source": [
    "Final link classification layer that takes a pair of node embeddings produced by the GCN model, applies a binary operator to them to produce the corresponding link embedding (`ip` for inner product; other options for the binary operator can be seen by running a cell with `?LinkEmbedding` in it), and passes it through a dense layer:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "28",
   "metadata": {},
   "outputs": [],
   "source": [
    "prediction = LinkEmbedding(activation=\"relu\", method=\"ip\")(x_out)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "29",
   "metadata": {},
   "source": [
    "The predictions need to be reshaped from `(X, 1)` to `(X,)` to match the shape of the targets we have supplied above."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "30",
   "metadata": {},
   "outputs": [],
   "source": [
    "prediction = keras.layers.Reshape((-1,))(prediction)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "31",
   "metadata": {},
   "source": [
    "Stack the GCN and prediction layers into a Keras model, and specify the loss"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "32",
   "metadata": {},
   "outputs": [],
   "source": [
    "model = keras.Model(inputs=x_inp, outputs=prediction)\n",
    "\n",
    "model.compile(\n",
    "    optimizer=keras.optimizers.Adam(lr=0.01),\n",
    "    loss=keras.losses.binary_crossentropy,\n",
    "    # not just \"acc\" due to https://github.com/tensorflow/tensorflow/issues/41361\n",
    "    metrics=[\"binary_accuracy\"],\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "33",
   "metadata": {},
   "source": [
    "Evaluate the initial (untrained) model on the train and test set:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "34",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  ['...']\n",
      "1/1 [==============================] - 0s 109ms/step - loss: 2.0672 - binary_accuracy: 0.5000\n",
      "  ['...']\n",
      "1/1 [==============================] - 0s 11ms/step - loss: 2.0854 - binary_accuracy: 0.5000\n",
      "\n",
      "Train Set Metrics of the initial (untrained) model:\n",
      "\tloss: 2.0672\n",
      "\tbinary_accuracy: 0.5000\n",
      "\n",
      "Test Set Metrics of the initial (untrained) model:\n",
      "\tloss: 2.0854\n",
      "\tbinary_accuracy: 0.5000\n"
     ]
    }
   ],
   "source": [
    "init_train_metrics = model.evaluate(train_flow)\n",
    "init_test_metrics = model.evaluate(test_flow)\n",
    "\n",
    "print(\"\\nTrain Set Metrics of the initial (untrained) model:\")\n",
    "for name, val in zip(model.metrics_names, init_train_metrics):\n",
    "    print(\"\\t{}: {:0.4f}\".format(name, val))\n",
    "\n",
    "print(\"\\nTest Set Metrics of the initial (untrained) model:\")\n",
    "for name, val in zip(model.metrics_names, init_test_metrics):\n",
    "    print(\"\\t{}: {:0.4f}\".format(name, val))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "35",
   "metadata": {},
   "source": [
    "Train the model:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "36",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  ['...']\n",
      "  ['...']\n",
      "Train for 1 steps, validate for 1 steps\n",
      "Epoch 1/50\n",
      "1/1 - 1s - loss: 2.0177 - binary_accuracy: 0.5000 - val_loss: 0.6800 - val_binary_accuracy: 0.6282\n",
      "Epoch 2/50\n",
      "1/1 - 0s - loss: 0.7811 - binary_accuracy: 0.6148 - val_loss: 2.7203 - val_binary_accuracy: 0.5304\n",
      "Epoch 3/50\n",
      "1/1 - 0s - loss: 3.0683 - binary_accuracy: 0.5512 - val_loss: 0.8094 - val_binary_accuracy: 0.6070\n",
      "Epoch 4/50\n",
      "1/1 - 0s - loss: 1.0147 - binary_accuracy: 0.6281 - val_loss: 0.6638 - val_binary_accuracy: 0.6144\n",
      "Epoch 5/50\n",
      "1/1 - 0s - loss: 0.6450 - binary_accuracy: 0.6383 - val_loss: 0.7782 - val_binary_accuracy: 0.5452\n",
      "Epoch 6/50\n",
      "1/1 - 0s - loss: 0.7345 - binary_accuracy: 0.5594 - val_loss: 0.8198 - val_binary_accuracy: 0.5360\n",
      "Epoch 7/50\n",
      "1/1 - 0s - loss: 0.7581 - binary_accuracy: 0.5420 - val_loss: 0.7800 - val_binary_accuracy: 0.5424\n",
      "Epoch 8/50\n",
      "1/1 - 0s - loss: 0.7302 - binary_accuracy: 0.5635 - val_loss: 0.6993 - val_binary_accuracy: 0.5793\n",
      "Epoch 9/50\n",
      "1/1 - 0s - loss: 0.6579 - binary_accuracy: 0.6178 - val_loss: 0.6471 - val_binary_accuracy: 0.6448\n",
      "Epoch 10/50\n",
      "1/1 - 0s - loss: 0.5960 - binary_accuracy: 0.6527 - val_loss: 0.6303 - val_binary_accuracy: 0.6651\n",
      "Epoch 11/50\n",
      "1/1 - 0s - loss: 0.6916 - binary_accuracy: 0.7049 - val_loss: 0.6082 - val_binary_accuracy: 0.6753\n",
      "Epoch 12/50\n",
      "1/1 - 0s - loss: 0.6069 - binary_accuracy: 0.7182 - val_loss: 0.6083 - val_binary_accuracy: 0.6633\n",
      "Epoch 13/50\n",
      "1/1 - 0s - loss: 0.5257 - binary_accuracy: 0.7131 - val_loss: 0.5991 - val_binary_accuracy: 0.6550\n",
      "Epoch 14/50\n",
      "1/1 - 0s - loss: 0.5381 - binary_accuracy: 0.7111 - val_loss: 0.5900 - val_binary_accuracy: 0.6688\n",
      "Epoch 15/50\n",
      "1/1 - 0s - loss: 0.5440 - binary_accuracy: 0.7305 - val_loss: 0.5756 - val_binary_accuracy: 0.6873\n",
      "Epoch 16/50\n",
      "1/1 - 0s - loss: 0.5004 - binary_accuracy: 0.7480 - val_loss: 0.5669 - val_binary_accuracy: 0.7011\n",
      "Epoch 17/50\n",
      "1/1 - 0s - loss: 0.5103 - binary_accuracy: 0.7572 - val_loss: 0.5710 - val_binary_accuracy: 0.7168\n",
      "Epoch 18/50\n",
      "1/1 - 0s - loss: 0.5410 - binary_accuracy: 0.7510 - val_loss: 0.5528 - val_binary_accuracy: 0.7389\n",
      "Epoch 19/50\n",
      "1/1 - 0s - loss: 0.5042 - binary_accuracy: 0.7602 - val_loss: 0.5363 - val_binary_accuracy: 0.7555\n",
      "Epoch 20/50\n",
      "1/1 - 0s - loss: 0.5035 - binary_accuracy: 0.7818 - val_loss: 0.5337 - val_binary_accuracy: 0.7565\n",
      "Epoch 21/50\n",
      "1/1 - 0s - loss: 0.4343 - binary_accuracy: 0.7900 - val_loss: 0.5315 - val_binary_accuracy: 0.7518\n",
      "Epoch 22/50\n",
      "1/1 - 0s - loss: 0.4395 - binary_accuracy: 0.7920 - val_loss: 0.5290 - val_binary_accuracy: 0.7509\n",
      "Epoch 23/50\n",
      "1/1 - 0s - loss: 0.4513 - binary_accuracy: 0.7838 - val_loss: 0.5253 - val_binary_accuracy: 0.7528\n",
      "Epoch 24/50\n",
      "1/1 - 0s - loss: 0.4329 - binary_accuracy: 0.8064 - val_loss: 0.5292 - val_binary_accuracy: 0.7528\n",
      "Epoch 25/50\n",
      "1/1 - 0s - loss: 0.3979 - binary_accuracy: 0.8289 - val_loss: 0.5225 - val_binary_accuracy: 0.7620\n",
      "Epoch 26/50\n",
      "1/1 - 0s - loss: 0.4230 - binary_accuracy: 0.8084 - val_loss: 0.5259 - val_binary_accuracy: 0.7685\n",
      "Epoch 27/50\n",
      "1/1 - 0s - loss: 0.4280 - binary_accuracy: 0.8340 - val_loss: 0.5319 - val_binary_accuracy: 0.7703\n",
      "Epoch 28/50\n",
      "1/1 - 0s - loss: 0.3886 - binary_accuracy: 0.8320 - val_loss: 0.5297 - val_binary_accuracy: 0.7786\n",
      "Epoch 29/50\n",
      "1/1 - 0s - loss: 0.3921 - binary_accuracy: 0.8525 - val_loss: 0.5542 - val_binary_accuracy: 0.7860\n",
      "Epoch 30/50\n",
      "1/1 - 0s - loss: 0.3724 - binary_accuracy: 0.8576 - val_loss: 0.5854 - val_binary_accuracy: 0.7878\n",
      "Epoch 31/50\n",
      "1/1 - 0s - loss: 0.3583 - binary_accuracy: 0.8525 - val_loss: 0.5993 - val_binary_accuracy: 0.7851\n",
      "Epoch 32/50\n",
      "1/1 - 0s - loss: 0.3930 - binary_accuracy: 0.8504 - val_loss: 0.5984 - val_binary_accuracy: 0.7934\n",
      "Epoch 33/50\n",
      "1/1 - 0s - loss: 0.4009 - binary_accuracy: 0.8627 - val_loss: 0.5854 - val_binary_accuracy: 0.7952\n",
      "Epoch 34/50\n",
      "1/1 - 0s - loss: 0.3854 - binary_accuracy: 0.8617 - val_loss: 0.5798 - val_binary_accuracy: 0.7989\n",
      "Epoch 35/50\n",
      "1/1 - 0s - loss: 0.3616 - binary_accuracy: 0.8873 - val_loss: 0.5744 - val_binary_accuracy: 0.7980\n",
      "Epoch 36/50\n",
      "1/1 - 0s - loss: 0.3418 - binary_accuracy: 0.8637 - val_loss: 0.5535 - val_binary_accuracy: 0.8044\n",
      "Epoch 37/50\n",
      "1/1 - 0s - loss: 0.3682 - binary_accuracy: 0.8730 - val_loss: 0.5457 - val_binary_accuracy: 0.8035\n",
      "Epoch 38/50\n",
      "1/1 - 0s - loss: 0.3270 - binary_accuracy: 0.8842 - val_loss: 0.5584 - val_binary_accuracy: 0.8044\n",
      "Epoch 39/50\n",
      "1/1 - 0s - loss: 0.2986 - binary_accuracy: 0.8955 - val_loss: 0.5798 - val_binary_accuracy: 0.8054\n",
      "Epoch 40/50\n",
      "1/1 - 0s - loss: 0.3134 - binary_accuracy: 0.8740 - val_loss: 0.6044 - val_binary_accuracy: 0.8026\n",
      "Epoch 41/50\n",
      "1/1 - 0s - loss: 0.3217 - binary_accuracy: 0.8832 - val_loss: 0.5901 - val_binary_accuracy: 0.7961\n",
      "Epoch 42/50\n",
      "1/1 - 0s - loss: 0.3200 - binary_accuracy: 0.8791 - val_loss: 0.6040 - val_binary_accuracy: 0.7943\n",
      "Epoch 43/50\n",
      "1/1 - 0s - loss: 0.3124 - binary_accuracy: 0.8740 - val_loss: 0.6031 - val_binary_accuracy: 0.7961\n",
      "Epoch 44/50\n",
      "1/1 - 0s - loss: 0.3157 - binary_accuracy: 0.8822 - val_loss: 0.6116 - val_binary_accuracy: 0.7998\n",
      "Epoch 45/50\n",
      "1/1 - 0s - loss: 0.3034 - binary_accuracy: 0.8852 - val_loss: 0.6333 - val_binary_accuracy: 0.7998\n",
      "Epoch 46/50\n",
      "1/1 - 0s - loss: 0.2818 - binary_accuracy: 0.8914 - val_loss: 0.6404 - val_binary_accuracy: 0.7998\n",
      "Epoch 47/50\n",
      "1/1 - 0s - loss: 0.2646 - binary_accuracy: 0.8914 - val_loss: 0.6476 - val_binary_accuracy: 0.8007\n",
      "Epoch 48/50\n",
      "1/1 - 0s - loss: 0.2637 - binary_accuracy: 0.8975 - val_loss: 0.6712 - val_binary_accuracy: 0.8063\n",
      "Epoch 49/50\n",
      "1/1 - 0s - loss: 0.2802 - binary_accuracy: 0.9047 - val_loss: 0.6873 - val_binary_accuracy: 0.8054\n",
      "Epoch 50/50\n",
      "1/1 - 0s - loss: 0.2481 - binary_accuracy: 0.9109 - val_loss: 0.7384 - val_binary_accuracy: 0.8035\n"
     ]
    }
   ],
   "source": [
    "history = model.fit(\n",
    "    train_flow, epochs=epochs, validation_data=test_flow, verbose=2, shuffle=False\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "37",
   "metadata": {},
   "source": [
    "Plot the training history:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "38",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 504x576 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "sg.utils.plot_history(history)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "39",
   "metadata": {},
   "source": [
    "Evaluate the trained model on test citation links:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "40",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  ['...']\n",
      "1/1 [==============================] - 0s 11ms/step - loss: 0.1937 - binary_accuracy: 0.9426\n",
      "  ['...']\n",
      "1/1 [==============================] - 0s 11ms/step - loss: 0.7384 - binary_accuracy: 0.8035\n",
      "\n",
      "Train Set Metrics of the trained model:\n",
      "\tloss: 0.1937\n",
      "\tbinary_accuracy: 0.9426\n",
      "\n",
      "Test Set Metrics of the trained model:\n",
      "\tloss: 0.7384\n",
      "\tbinary_accuracy: 0.8035\n"
     ]
    }
   ],
   "source": [
    "train_metrics = model.evaluate(train_flow)\n",
    "test_metrics = model.evaluate(test_flow)\n",
    "\n",
    "print(\"\\nTrain Set Metrics of the trained model:\")\n",
    "for name, val in zip(model.metrics_names, train_metrics):\n",
    "    print(\"\\t{}: {:0.4f}\".format(name, val))\n",
    "\n",
    "print(\"\\nTest Set Metrics of the trained model:\")\n",
    "for name, val in zip(model.metrics_names, test_metrics):\n",
    "    print(\"\\t{}: {:0.4f}\".format(name, val))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "41",
   "metadata": {
    "nbsphinx": "hidden",
    "tags": [
     "CloudRunner"
    ]
   },
   "source": [
    "<table><tr><td>Run the latest release of this notebook:</td><td><a href=\"https://mybinder.org/v2/gh/stellargraph/stellargraph/master?urlpath=lab/tree/demos/link-prediction/gcn-link-prediction.ipynb\" alt=\"Open In Binder\" target=\"_parent\"><img src=\"https://mybinder.org/badge_logo.svg\"/></a></td><td><a href=\"https://colab.research.google.com/github/stellargraph/stellargraph/blob/master/demos/link-prediction/gcn-link-prediction.ipynb\" alt=\"Open In Colab\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\"/></a></td></tr></table>"
   ]
  }
 ],
 "metadata": {
  "file_extension": ".py",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.9"
  },
  "mimetype": "text/x-python",
  "name": "python",
  "npconvert_exporter": "python",
  "pygments_lexer": "ipython3",
  "version": 3
 },
 "nbformat": 4,
 "nbformat_minor": 4
}