{ "cells": [ { "cell_type": "markdown", "id": "above-pearl", "metadata": {}, "source": [ "# Data-driven Business and Behaviour Analytics (DBBA)\n", "# Lab session: 1 - First steps with NetworkX\n", "\n", "The Python package we will use to study and analyse networks is [NetworkX](https://networkx.org/documentation/stable/). Here we cover some basic examples." ] }, { "cell_type": "markdown", "id": "numerous-exclusion", "metadata": {}, "source": [ "To install the package, you can install the conda environment available on the website (the *.yml* file) following these instructions:\n", "- using your terminal, navigate to the folder containing the environment file\n", "- write on your terminal `conda env create -f dbba_env.yml`\n", "- always activate the environment before using your IDE or jupyter-notebook, using `conda activate dbba_env` on your terminal" ] }, { "cell_type": "markdown", "id": "flexible-valuation", "metadata": {}, "source": [ "*NOTE* If for any reason you cannot make the environment work, you can install the python packages normally by running `conda install networkx` or, from a jupyter-notebook," ] }, { "cell_type": "code", "execution_count": null, "id": "hungarian-presence", "metadata": {}, "outputs": [], "source": [ "!conda install networkx" ] }, { "cell_type": "markdown", "id": "owned-tucson", "metadata": {}, "source": [ "Once installed, to load the module into your Python session you have to use the `import` statement. Note also that you can use a short alias to enhance performance." ] }, { "cell_type": "code", "execution_count": 1, "id": "serious-indianapolis", "metadata": {}, "outputs": [], "source": [ "import networkx as nx" ] }, { "cell_type": "markdown", "id": "desperate-walter", "metadata": {}, "source": [ "After loading the package, we double-check the version to be safe we will use the last available version." ] }, { "cell_type": "code", "execution_count": 2, "id": "martial-stockholm", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'2.5'" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "nx.__version__" ] }, { "cell_type": "code", "execution_count": 3, "id": "innocent-ownership", "metadata": {}, "outputs": [], "source": [ "%matplotlib inline \n", "# this just to make the plots be plotted here creating no new windows " ] }, { "cell_type": "markdown", "id": "ranking-picking", "metadata": {}, "source": [ "## Creating and plotting our first network\n", "\n", "Here we create the basic object of the NetworkX library, the `Graph`, which is an undirected network. " ] }, { "cell_type": "code", "execution_count": 4, "id": "convenient-collins", "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# creating the Graph object\n", "G = nx.Graph()\n", "\n", "# Once created, the network is empy. Let's add some nodes!\n", "# We could do that in two different ways: first, adding them one by one\n", "G.add_node(1)\n", "G.add_node(3)\n", "\n", "# Second, creating a list of nodes and using it\n", "nodes_to_add = ['b', 'c', 'd']\n", "G.add_nodes_from(nodes_to_add)\n", "\n", "# Studying nodes only provides generally little information on them. The benefit of studying \n", "# networks lies in the connections that arise. Let's build some links in our network!\n", "# Again, we have two ways: first, adding links one by one\n", "G.add_edge('1', 'b')\n", "\n", "# or from a list of 2-dimensional tuples\n", "edges_to_add = [('3', 'c'), ('b', 'c'), ('c', 'd')]\n", "G.add_edges_from(edges_to_add)\n", "\n", "# note that the order (first or second place in a link) doesn't matter as we are dealing with undirected networks\n", "\n", "# draw the graph\n", "nx.draw(G, with_labels=True)" ] }, { "cell_type": "markdown", "id": "sharing-attendance", "metadata": {}, "source": [ "The plot can be customized in many ways by modifying the arguments in `draw`. [Here](https://networkx.org/documentation/stable//reference/generated/networkx.drawing.nx_pylab.draw.html#networkx.drawing.nx_pylab.draw) a comprehensive guide." ] }, { "cell_type": "code", "execution_count": 5, "id": "under-technical", "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "nx.draw(G,\n", " with_labels=True,\n", " node_color='red',\n", " node_size=1000,\n", " font_color='white',\n", " font_size=20,\n", " )" ] }, { "cell_type": "markdown", "id": "wired-muslim", "metadata": {}, "source": [ "## Examining the properties of a network\n", "\n", "A Graph object has several methods and properties which provide precious information." ] }, { "cell_type": "code", "execution_count": 6, "id": "stunning-james", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "NodeView((1, 3, 'b', 'c', 'd', '1', '3'))" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# List all of the nodes\n", "G.nodes()" ] }, { "cell_type": "code", "execution_count": 7, "id": "right-enforcement", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "EdgeView([('b', '1'), ('b', 'c'), ('c', '3'), ('c', 'd')])" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# List all of the edges\n", "G.edges()" ] }, { "cell_type": "markdown", "id": "sapphire-therapy", "metadata": {}, "source": [ "NodeView and EdgeView objects behave exactly like a list: you can iterate over them with a for loop." ] }, { "cell_type": "code", "execution_count": 8, "id": "abroad-circle", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('b', '1')\n", "('b', 'c')\n", "('c', '3')\n", "('c', 'd')\n" ] } ], "source": [ "for edge in G.edges:\n", " print(edge)" ] }, { "cell_type": "markdown", "id": "forward-latex", "metadata": {}, "source": [ "In some cases, it can be useful to retrieve how many links or nodes a network has." ] }, { "cell_type": "code", "execution_count": 9, "id": "ready-salon", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "7" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "G.number_of_nodes()" ] }, { "cell_type": "code", "execution_count": 10, "id": "acoustic-species", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "G.number_of_edges()" ] }, { "cell_type": "markdown", "id": "flying-wholesale", "metadata": {}, "source": [ "Or, for instance, which other nodes a node is connected to. Note: for performance reasons, `neighbors()` returns an iterator which we make a list using `list()`." ] }, { "cell_type": "code", "execution_count": 11, "id": "4c2a6c85-acb7-4889-925a-f2e221a61297", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "G.neighbors('c')" ] }, { "cell_type": "code", "execution_count": null, "id": "acquired-shark", "metadata": {}, "outputs": [], "source": [ "list(G.neighbors('c'))" ] }, { "cell_type": "markdown", "id": "bc3594eb-f637-4afc-ac33-ceeca5a91234", "metadata": {}, "source": [ "Or you can find convenient to loop over:" ] }, { "cell_type": "code", "execution_count": 12, "id": "01467836-5138-4d65-a500-f45fbdee901d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a\n", "c\n" ] } ], "source": [ "for neighbor in G.neighbors('b'):\n", " print(neighbor)" ] }, { "cell_type": "markdown", "id": "appreciated-shame", "metadata": {}, "source": [ "If we do not know whether a node is in a giant network or whether it is connected to another given node, we could use `has_node()` or `has_edge()`." ] }, { "cell_type": "code", "execution_count": 12, "id": "fourth-solid", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "G.has_node('f')" ] }, { "cell_type": "markdown", "id": "large-middle", "metadata": {}, "source": [ "Even if rough, an estimate of the importance of a given a node in a network is its degree, which we compute in the following way." ] }, { "cell_type": "code", "execution_count": 13, "id": "republican-integration", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "G.degree('d')" ] }, { "cell_type": "markdown", "id": "f0f3855a-d52a-42ae-9df8-bc6710e1242a", "metadata": { "tags": [] }, "source": [ "## NetworkX functions vs. Graph methods\n", "\n", "The previous data are available via graph *methods*, *i.e.* they are called from the graph object:\n", "\n", " G.()\n", "\n", "While several of the most-used NetworkX functions are provided as methods, many more of them are module functions and are called like this:\n", "\n", " nx.(G, )\n", "\n", "that is, with the graph provided as the first, and maybe only, argument. Here are a couple of examples of NetworkX module functions that provide information about a graph:" ] }, { "cell_type": "code", "execution_count": 14, "id": "dfc8dcff-cecd-41fd-a8a0-2520f1cb3357", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "nx.is_tree(G)" ] }, { "cell_type": "code", "execution_count": 15, "id": "341276eb-bf45-41ea-9e01-475068e1e2e4", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "nx.is_connected(G)" ] }, { "cell_type": "markdown", "id": "2d34ba0c-dabb-4338-aed4-b8467b74497c", "metadata": { "tags": [] }, "source": [ "# **EXERCISE 1**\n", "Often in the context of trees, a node with degree 1 is called a *leaf*. Write a function named `get_leaves` that takes a graph as an argument, loops through the nodes, and returns a list of nodes with degree 1." ] }, { "cell_type": "code", "execution_count": null, "id": "f27d4263-09f1-43d7-b061-5f86436e5828", "metadata": { "scrolled": true }, "outputs": [], "source": [ "def get_leaves(G):\n" ] }, { "cell_type": "code", "execution_count": null, "id": "daba2e3a-f585-406a-a235-5a5c7d6717ba", "metadata": { "scrolled": true }, "outputs": [], "source": [ "G = nx.Graph()\n", "G.add_edges_from([\n", " ('a', 'b'),\n", " ('a', 'd'),\n", " ('c', 'd'),\n", " ])\n", "assert set(get_leaves(G)) == {'c', 'b'}" ] }, { "cell_type": "markdown", "id": "rubber-bicycle", "metadata": {}, "source": [ "## Directed networks: the DiGraph object\n", "\n", "\n", "Some types of networks require more than a bunch of symmetric relationships e.g., a causality link or a air flight. NetworkX provides the `DiGraph` class for directed graphs with additional methods and properties specific to directed edges.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "super-collar", "metadata": {}, "outputs": [], "source": [ "DirG = nx.DiGraph()\n", "\n", "DirG.add_weighted_edges_from([(1, 2, 0.5), (3, 1, 0.75)]) # note: a link can be weighted \n", "# through the third element of the tuple" ] }, { "cell_type": "code", "execution_count": null, "id": "japanese-faculty", "metadata": {}, "outputs": [], "source": [ "DirG.out_degree(1, weight='weight')" ] }, { "cell_type": "code", "execution_count": null, "id": "together-missouri", "metadata": {}, "outputs": [], "source": [ "DirG.degree(1, weight='weight')" ] }, { "cell_type": "markdown", "id": "consistent-static", "metadata": {}, "source": [ "Being directed, the concepts of neighbour or of degree lose importance. New ideas (but easily translatable from the undirected case) of __predecessors/successors__ and __in-degree/out-degree__ came up, which only refers to __in-links/out-links__. " ] }, { "cell_type": "code", "execution_count": null, "id": "vocational-jersey", "metadata": {}, "outputs": [], "source": [ "list(DirG.successors(1))" ] }, { "cell_type": "code", "execution_count": null, "id": "vulnerable-waterproof", "metadata": {}, "outputs": [], "source": [ "DirG.in_degree(1)" ] }, { "cell_type": "markdown", "id": "informational-humor", "metadata": {}, "source": [ "## Reading and writing networks\n", "\n", "In real-world data, networks can be very large. Because of this, compact ways to store information related to nodes and links have to be found. NetworkX provides a few.\n", "\n", "### Adjacency list\n", "\n", "The adjacency list format consists of lines with node labels. The first label in a line is the source node. Further labels in the line are considered target nodes and are added to the graph along with an edge between the source node and target node.\n", "\n", "```\n", "a b c # source target target\n", "d e\n", "```\n", "\n", "### Edge list\n", "\n", "Similarly, `read_edgelist()` can read a list of edges, with the drawback of the impossibility of representing isolated nodes unless the node has a self-loop edge." ] }, { "cell_type": "markdown", "id": "d6c883d8-1231-4c68-a71c-5f2177e6a9a3", "metadata": { "tags": [] }, "source": [ "# **EXERCISE 2**\n", "\n", "Write a function `max_degree` that takes a graph as its argument, and returns a 2-tuple with the name and degree of the node with highest degree." ] }, { "cell_type": "code", "execution_count": null, "id": "5ebb643a-56a0-4702-8387-69be1707b45e", "metadata": {}, "outputs": [], "source": [ "def max_degree(G):\n", " " ] }, { "cell_type": "markdown", "id": "0d3ad4ed-93e7-499d-93c7-ddf6377e331d", "metadata": {}, "source": [ "# **EXERCISE 3**" ] }, { "cell_type": "markdown", "id": "dc64f142-0230-4edb-a4d4-9e637226b805", "metadata": {}, "source": [ "Build a correlation network based from the last year's FTSE 100 adjusted returns (ret_adjusted.csv), by using Pearson correlation. Filter it using the Minimum Spanning Tree algorithm (with `nx.minimum_spanning_tree()`. Identify the node with the maximum degree using the function just written. Check whether there are leaves." ] }, { "cell_type": "code", "execution_count": null, "id": "ca2b15a1", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "id": "4a2160ae", "metadata": {}, "source": [ "# **EXERCISE 4**" ] }, { "cell_type": "markdown", "id": "38b807a3", "metadata": {}, "source": [ "Repeat exercise 3 but using `nx.maximum_spanning_tree()` instead. Plot both networks, and compare them. Write a list of 5 nodes with highest degree in both cases. Are there any differences? If so, why? " ] }, { "cell_type": "code", "execution_count": null, "id": "29003807", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "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.13" } }, "nbformat": 4, "nbformat_minor": 5 }