{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# [NTDS'17] assignment 1: Solution\n", "[ntds'17]: https://github.com/mdeff/ntds_2017\n", "\n", "[Effrosyni Simou](http://lts4.epfl.ch/simou), [EPFL LTS4](http://lts4.epfl.ch)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Objective of Exercise\n", "The aim of this exercise is to learn how to create your own, real network using data collected from the Internet and then to discover some properties of the collected network. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Resources\n", "You might want to have a look at the following resources before starting:\n", "\n", "* [Twitter REST API](https://dev.twitter.com/rest/public)\n", "* [Tweepy Documentation](http://tweepy.readthedocs.io/en/v3.5.0/)\n", "* [Tutorial \"Mining Twitter data with Python\"](https://marcobonzanini.com/2015/03/02/mining-twitter-data-with-python-part-1/)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 1. Collect a Twitter Network" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In order to collect data from Twitter you will need to generate access tokens. To do this you will need to register a [client application with Twitter](https://apps.twitter.com/). Once you are done you should have your tokens. You can now create a `credentials.ini` file as follows:\n", "```\n", "[twitter]\n", "consumer_key = YOUR-CONSUMER-KEY\n", "consumer_secret = YOUR-CONSUMER-SECRET\n", "access_token = YOUR-ACCESS-TOKEN\n", "access_secret = YOUR-ACCESS-SECRET\n", "```\n", "In this way you will have this information readily available to you. " ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "%matplotlib inline\n", "\n", "import random\n", "import configparser\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "from pprint import pprint\n", "import tweepy # you will need to install tweepy first" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Read the confidential token.\n", "credentials = configparser.ConfigParser()\n", "credentials.read('credentials.ini')\n", "\n", "#authentication\n", "auth = tweepy.OAuthHandler(credentials.get('twitter', 'consumer_key'), credentials.get('twitter', 'consumer_secret'))\n", "auth.set_access_token(credentials.get('twitter', 'access_token'), credentials.get('twitter', 'access_secret'))\n", "\n", "#construct API instance\n", "#deal with rate limits and notify when delayed because of rate limits\n", "api = tweepy.API(auth,wait_on_rate_limit=True, wait_on_rate_limit_notify=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now you are all set up to start collecting data from Twitter! " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this exercise we will construct a network with the following logic:\n", "\n", "1) We will chose a `user_id` in Twitter to be our first node. \n", "\n", "2) We will find (some) of the users who are both following `user_id` and are being followed by `user_id`. From now on we will call such users \"connections\" of `user_id`. We will place these user ids in a list called `first_nodes`. \n", "\n", "3) For every node in the list `first_nodes` we will then find (some) of the users who are following and are being followed by this node (aka the connections of this node). The user ids collected in this step will be placed in a list called `second_nodes`.\n", "\n", "4) The collection of the ids of all nodes (aka Twitter users) that we have collected so far will be placed in a list called `all_nodes`.\n", "\n", "5) Since we have only collected a subset of all possible \"connections\" for our nodes we have to check if there are any remaining inner connections that we have missed.\n", "\n", "The entire network is to be organized in a dictionary with entries that will have as key the Twitter id of the user (this is a number characterizing each user in Twitter) and as value the list of ids of his connections.\n", "\n", "So, let us begin. The first thing that you will have to do is to chose the node from which everything will start. I have chosen the Twitter account of [Applied Machine Learning Days](https://www.appliedmldays.org) that will take place in January 2018 in EPFL. You may change that if you wish to, but please make sure that the user you chose has both followers and friends and that he allows you to access this data." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": true }, "outputs": [], "source": [ "user = 'appliedmldays '\n", "user_id=api.get_user(user).id" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the following cell write a function that takes as an argument the Twitter id of a user and returns a list with the **ids** of his connections. Take into account the case where a user does not allow you to access this information.\n", "\n", "**Reminder:** By connections we mean users that are both followers and friends of a given user." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def find_connections(user_id):\n", " followers = []\n", " friends = []\n", " try:\n", " for page in tweepy.Cursor(api.followers_ids, user_id).pages():\n", " followers = followers + page \n", " for page in tweepy.Cursor(api.friends_ids, user_id).pages():\n", " friends = friends + page \n", " connections = list(set(friends).intersection(followers))\n", " except tweepy.TweepError: #raise exception when you cannot access the followers of a user\n", " # we get a tweep error when we can't view a user - skip them and move onto the next.\n", " print('Could not view user {}, skipping...'.format(user_id))\n", " connections = ['null']\n", " return connections" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "appliedmldays has 141 connections\n" ] } ], "source": [ "first_connections = find_connections(user_id)\n", "print('{}has {} connections'.format(user, len(first_connections)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Collect your `first_nodes` and `second_nodes` and organize your collected nodes and their connections in the dictionary called `network`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Hints:\n", "* Use `random.choice([1,3,4])` to randomly choose a number in `[1, 3, 4]`.\n", "* Use the `append` and `remove` methods to add and remove an element from a Python list.\n", "* The `pop` method removes the last item in the list." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "Rate limit reached. Sleeping for: 862\n", "Rate limit reached. Sleeping for: 895\n", "Rate limit reached. Sleeping for: 895\n", "Could not view user 530950089, skipping...\n", "Could not view user 716623862, skipping...\n", "Rate limit reached. Sleeping for: 890\n", "1\n", "Rate limit reached. Sleeping for: 895\n", "Could not view user 19888273, skipping...\n", "Could not view user 232974417, skipping...\n", "2\n", "Could not view user 51738744, skipping...\n", "Rate limit reached. Sleeping for: 864\n", "Rate limit reached. Sleeping for: 894\n", "3\n", "Rate limit reached. Sleeping for: 895\n", "Could not view user 19066345, skipping...\n", "4\n", "Rate limit reached. Sleeping for: 878\n", "Rate limit reached. Sleeping for: 896\n", "5\n", "Rate limit reached. Sleeping for: 896\n", "6\n", "Rate limit reached. Sleeping for: 890\n", "Rate limit reached. Sleeping for: 895\n", "Rate limit reached. Sleeping for: 896\n", "Could not view user 227423290, skipping...\n", "7\n", "Could not view user 404075638, skipping...\n", "Rate limit reached. Sleeping for: 870\n", "8\n", "Rate limit reached. Sleeping for: 878\n", "9\n" ] } ], "source": [ "network = {}\n", "first_nodes = []\n", "second_nodes = []\n", "how_many = 10#This is the number of connections you are sampling. \n", " #Keep small (e.g.3) for development, larger later (e.g. 10)\n", "n = min(how_many,len(first_connections))\n", "i=0\n", "while (i in range(0,n))&(first_connections != []):\n", " current_id = random.choice(first_connections)\n", " # remove the ID from the list, so we don't pick it again.\n", " first_connections.remove(current_id)\n", " first_nodes.append(current_id)\n", " second_connections = find_connections(current_id)\n", " '''avoid collecting: \n", " i) protected users as first nodes \n", " ii) nodes that are already collected in the second_nodes list as first nodes''' \n", " if (second_connections==['null'])|(current_id in second_nodes):\n", " first_nodes.pop()\n", " print(i)\n", " continue\n", " else:\n", " network[current_id] = []\n", " j=0\n", " m = min(how_many,len(second_connections))\n", " while (j in range(0,m))&(second_connections != []):\n", " new_current_id = random.choice(second_connections)\n", " # remove the ID from the list, so we don't pick it again.\n", " second_connections.remove(new_current_id)\n", " second_nodes.append(new_current_id)\n", " third_connections = find_connections(new_current_id)\n", " '''avoid collecting: \n", " i) protected users as second nodes \n", " ii) the root node as a second node\n", " ii) nodes that have already been collected in the first_nodes list as second nodes'''\n", " if (third_connections==['null'])|(new_current_id==user_id)|(new_current_id in first_nodes):\n", " second_nodes.pop()\n", " else:\n", " network[current_id].append(new_current_id)\n", " j=j+1\n", " \n", " if user_id not in network[current_id]:\n", " network[current_id].append(user_id) #make sure to include the root in the connections of the first nodes\n", " print(i)\n", " i = i+1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Be careful!** You should only keep a small value for the `how_many` parameter while you are developing your code. In order to answer to the questions you should raise the value of this parameter to `how_many=10` at least. This will take a while to execute because of the API rate limit (plan your time accordingly). You should also remember to submit your jupyter notebook with the **output shown for a large value of the `how_many` parameter**. " ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": true }, "outputs": [], "source": [ "network[user_id] = first_nodes" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{382393: [15308423,\n", " 1008442225,\n", " 355626264,\n", " 29694990,\n", " 700746896680161280,\n", " 5439642,\n", " 155636227,\n", " 861230886,\n", " 24414798,\n", " 21695487,\n", " 763052115392593920],\n", " 14177696: [2564697607,\n", " 381054288,\n", " 487673211,\n", " 13348402,\n", " 2258911,\n", " 559966263,\n", " 900843938,\n", " 14704764,\n", " 2815170184,\n", " 3656369897,\n", " 763052115392593920],\n", " 22403036: [15106933,\n", " 206719125,\n", " 1408838665,\n", " 167056343,\n", " 299757170,\n", " 3240168873,\n", " 20191120,\n", " 353925814,\n", " 73039079,\n", " 49580432,\n", " 763052115392593920],\n", " 335986035: [9704802,\n", " 2234372946,\n", " 22425612,\n", " 317637840,\n", " 69726522,\n", " 2505279536,\n", " 907581515240034305,\n", " 790266440582434816,\n", " 3036329200,\n", " 21991908,\n", " 763052115392593920],\n", " 582038911: [52793695,\n", " 493106882,\n", " 587217646,\n", " 114699841,\n", " 2899469745,\n", " 600084235,\n", " 487317771,\n", " 90373079,\n", " 366507950,\n", " 785864403099017216,\n", " 763052115392593920],\n", " 917752062: [238252411,\n", " 987389154,\n", " 309680769,\n", " 199809792,\n", " 921651570,\n", " 763052115392593920],\n", " 2533212240: [427235323,\n", " 18247347,\n", " 255051048,\n", " 2318509094,\n", " 100478960,\n", " 1467737210,\n", " 237939868,\n", " 1960705284,\n", " 1069045039,\n", " 2852000613,\n", " 763052115392593920],\n", " 2647217844: [3304728893,\n", " 564855281,\n", " 111020569,\n", " 2332292953,\n", " 420636848,\n", " 2713107342,\n", " 2767062349,\n", " 142995842,\n", " 2575338618,\n", " 763052115392593920],\n", " 763052115392593920: [2533212240,\n", " 22403036,\n", " 14177696,\n", " 335986035,\n", " 2647217844,\n", " 908033202173997056,\n", " 917752062,\n", " 802965874399477760,\n", " 582038911,\n", " 382393],\n", " 802965874399477760: [212201946,\n", " 2591062848,\n", " 841437061,\n", " 1934613283,\n", " 2247355933,\n", " 22862179,\n", " 518949783,\n", " 3989101,\n", " 4745719861,\n", " 757546980033921024,\n", " 763052115392593920],\n", " 908033202173997056: [91852037,\n", " 2897988570,\n", " 706885331224813568,\n", " 2826829095,\n", " 841437061,\n", " 763052115392593920]}\n" ] } ], "source": [ "pprint(network)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": true }, "outputs": [], "source": [ "s = network.values()\n", "nodes = set(val for dic in s for val in dic) \n", "second_nodes = list(set(second_nodes)) #remove possible duplicates from second nodes\n", "all_nodes = list(nodes)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "There are 10 first hop nodes\n", "There are 88 second hop nodes\n", "There are overall 99 nodes in the collected network\n" ] } ], "source": [ "print('There are {} first hop nodes'.format(len(first_nodes)))\n", "print('There are {} second hop nodes'.format(len(second_nodes)))\n", "print('There are overall {} nodes in the collected network'.format(len(all_nodes)))" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Initialize the dictionary entries for the second nodes \n", "for i in second_nodes:\n", " network[i] = []" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Find the inner connections between your collected nodes that you might have missed because you sampled the connections." ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "13\n", "1\n", "2\n", "2\n", "1\n", "3\n", "8\n", "4\n", "6\n", "5\n", "8\n", "6\n", "4\n", "7\n", "1\n", "8\n", "2\n", "9\n", "1\n", "10\n", "11\n", "Rate limit reached. Sleeping for: 878\n", "11\n", "1\n", "12\n", "1\n", "13\n", "5\n", "14\n", "5\n", "15\n", "6\n", "16\n", "1\n", "17\n", "1\n", "18\n", "2\n", "19\n", "2\n", "20\n", "2\n", "21\n", "2\n", "22\n", "11\n", "Rate limit reached. Sleeping for: 864\n", "23\n", "2\n", "24\n", "1\n", "25\n", "4\n", "26\n", "7\n", "27\n", "1\n", "28\n", "2\n", "29\n", "1\n", "30\n", "1\n", "31\n", "2\n", "32\n", "1\n", "33\n", "1\n", "34\n", "6\n", "35\n", "10\n", "36\n", "10\n", "37\n", "1\n", "Rate limit reached. Sleeping for: 857\n", "38\n", "2\n", "39\n", "2\n", "40\n", "4\n", "Rate limit reached. Sleeping for: 896\n", "41\n", "9\n", "42\n", "1\n", "43\n", "1\n", "44\n", "1\n", "45\n", "6\n", "Rate limit reached. Sleeping for: 881\n", "46\n", "2\n", "47\n", "7\n", "48\n", "5\n", "49\n", "1\n", "50\n", "2\n", "51\n", "5\n", "52\n", "1\n", "53\n", "1\n", "54\n", "1\n", "55\n", "5\n", "56\n", "5\n", "57\n", "1\n", "58\n", "3\n", "59\n", "3\n", "Rate limit reached. Sleeping for: 872\n", "60\n", "4\n", "61\n", "3\n", "62\n", "2\n", "63\n", "1\n", "64\n", "3\n", "65\n", "1\n", "66\n", "2\n", "67\n", "2\n", "68\n", "4\n", "69\n", "1\n", "70\n", "11\n", "71\n", "1\n", "72\n", "2\n", "73\n", "2\n", "74\n", "11\n", "Rate limit reached. Sleeping for: 878\n", "75\n", "2\n", "Rate limit reached. Sleeping for: 896\n", "76\n", "4\n", "77\n", "7\n", "Rate limit reached. Sleeping for: 896\n", "78\n", "3\n", "79\n", "1\n", "80\n", "1\n", "81\n", "15\n", "82\n", "1\n", "83\n", "1\n", "84\n", "1\n", "85\n", "2\n", "86\n", "17\n", "87\n", "3\n", "88\n", "1\n", "89\n", "2\n", "90\n", "1\n", "91\n", "14\n", "Rate limit reached. Sleeping for: 875\n", "92\n", "2\n", "93\n", "1\n", "94\n", "1\n", "95\n", "2\n", "Rate limit reached. Sleeping for: 897\n", "96\n", "4\n", "97\n", "1\n", "98\n", "1\n" ] } ], "source": [ "for i in range(0,len(all_nodes)):\n", " current_id = all_nodes[i]\n", " connections = find_connections(current_id)\n", " inner_connections = []+list(set(connections).intersection(set(all_nodes)))\n", " network[current_id] = list(set(network[current_id]+inner_connections))\n", " print(i)\n", " print(len(inner_connections))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 2. Discover some of the properties of the collected network" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2.1 Adjacency matrix" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Congradulations! You have now created a dictionary that describes a real Twitter network!\n", "We now want to transform this dictionary into the adjacency (or weight) matrix that you learned about in your first class. " ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": true }, "outputs": [], "source": [ "W = np.zeros([len(all_nodes),len(all_nodes)], dtype=int)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [], "source": [ "sorted_nodes = sorted(list(network.keys()))\n", "weights = {}\n", "for i in range(0,len(sorted_nodes)):\n", " current_id = sorted_nodes[i]\n", " weights[current_id] = sorted(network[current_id])\n" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": true }, "outputs": [], "source": [ "for i in range(0,len(sorted_nodes)):\n", " current_id = sorted_nodes[i]\n", " #print(current_id)\n", " my_list = weights[current_id]\n", " #print(my_list)\n", " for j in my_list:\n", " #print(j)\n", " W[i,sorted_nodes.index(j)] = 1\n", " W[sorted_nodes.index(j),i] = 1\n", " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Remember that a weight matrix should be symmetric. Check if it is:" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(array([], dtype=int64), array([], dtype=int64))" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.nonzero(W-W.transpose())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Question 1:**\n", "It might happen that $W \\neq W^{T} $ for some $(i,j)$. Explain why this might be the case." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Your answer here:**\n", "\n", "Your weight matrix could be non-symmetric if:\n", "\n", "* You had not chosen all of your collected nodes to be non-protected users.\n", "* You had not used the Cursor object in order to collect all the connections of the nodes.\n", "\n", "In this implementation, the weight matrix is created in such a way that it will always be symmetric." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Impose your weight matrix to be symmetric." ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Make W is symmetric\n", "bigger = W.transpose() > W" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": true }, "outputs": [], "source": [ "W = W - W*bigger + W.transpose()*bigger" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Plot the weight matrix of your collected network.\n", "\n", "Hint: use `plt.spy()` to visualize a matrix." ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\nDmKGbxgd5P8B1CaXraJ4FfcAAAAASUVORK5CYII=\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.spy(W, markersize=1)\n", "plt.title('Adjacency Matrix W')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Question 2:**\n", "What is the maximum number of links $L_{max}$ in a network with $N$ nodes (where $N$ is the number of nodes in your collected network)? How many links $L$ are there in your collected network? Comment on how $L$ and $L_{max}$ compare." ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": true }, "outputs": [], "source": [ "L = W.sum()/2" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "176.0\n" ] } ], "source": [ "print(L)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Your answer here:** The maximum number of links in a network with $N$ nodes is $L_{max}=N(N-1)/2$. This will be the case of a complete graph. Therefore, the maximum number of links for a network with $N=99$ nodes will be $L_{max}=4851$. The number of links in the collected network is $L=176$. We can see that $L << L_{max}$ and therefore we can conclude that the network is very sparse $L=O(N)$. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2.2 Degrees distribution" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Plot a histogram of the degree distribution. " ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": true }, "outputs": [], "source": [ "d = W.sum(axis=0)" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[17 2 2 1 1 1 15 1 1 1 10 3 1 1 14 1 2 2 1 1 3 1 9 3 5\n", " 2 5 2 2 4 1 2 2 1 1 2 5 1 2 2 11 1 5 1 3 6 1 2 2 2\n", " 1 2 4 11 1 1 4 1 1 6 1 4 4 5 1 7 1 7 2 5 6 1 1 11 1\n", " 4 3 10 7 4 1 1 2 2 2 1 1 3 1 2 8 8 1 13 2 1 11 2 6]\n" ] } ], "source": [ "print(d)" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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\nAAAASUVORK5CYII=\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "weights = np.ones_like(d)/float(len(all_nodes))\n", "plt.hist(d, weights = weights);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Question 3:** Comment on the plot. What do you observe? Would you expect a similar degree disribution in the complete Twitter network?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Your answer here:** We observe that the majority of the nodes in the collected network have a degree equal to 1. This is not the case for the whole Twitter network, but it is a result of the way that we collected the network. \n", "\n", "However, we can see that the network seems to have a degree distribution of a scale-free network, i.e. the degree distribution follows a power law. This will become more apparent as the value of the parameter ``how_many`` increases." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2.3 Average degree" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Calculate the average degree of your collected network." ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": true }, "outputs": [], "source": [ "d_avg = np.sum(d)/len(d)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3.55555555556\n" ] } ], "source": [ "print(d_avg)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2.4 Diameter of the collected network" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Question 4:** What is the diameter of the collected network? Please justify." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Your answer here:** The diameter is by definition the longest shortest path between two nodes in a network. \n", "\n", "Because of the way that we constructed the network, the longest possible paths are between two nodes of the list ``second_nodes``. \n", "\n", "Specifically, the path between any two nodes in the list ``second_nodes`` can be as in the following cases A, B, C and D :\n", "\n", "Case A:\n", "second node -> first node -> root -> first node -> second node\n", "\n", "Therefore, the length of the shortest path in this case will be equal to 4.\n", "\n", "Case B:\n", "It may happen that some of the first nodes will be connected and therefore the path between some of the second nodes will be:\n", "\n", "second node -> first node -> first node -> second node\n", "\n", "Therefore, the length of the shortest path in this case will be equal to 3.\n", "\n", "Case C:\n", "Some of the second nodes will obviously be connected through the same first node and therefore the path between them will be:\n", "\n", "second node -> first node -> second node\n", "\n", "Therefore, the length of the shortest path in this case will be equal to 2.\n", "\n", "Case D:\n", "Also it might happen that some of the second nodes will be directly connected to one another and therefore the path between those two second nodes will be second node -> second node.\n", "\n", "Therefore, the length of the shortest path in this case will be equal to 1.\n", "\n", "However, as we saw in Question 2, the collected network is very sparse and therefore at least one pair of second nodes will exist such that the shortest path between them is equal to 4. As a result, the diameter of the network will be $d=4$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2.5 Pruning the collected network" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You might notice that some nodes have very few connections and hence our matrix is very sparse. Prune the collected network so that you keep only the nodes that have a degree that is greater than the average degree and plot the new adjacency matrix." ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": false }, "outputs": [], "source": [ "Wpruned = W[d>d_avg][:,d>d_avg]" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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\nAElFTkSuQmCC\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.spy(Wpruned, markersize=1)\n", "plt.title('Adjacency Matrix W');" ] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Python [Root]", "language": "python", "name": "Python [Root]" }, "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.5.2" } }, "nbformat": 4, "nbformat_minor": 1 }