Last active
July 2, 2023 08:57
-
-
Save Orbifold/190a2d8caaf299799b002954d4ff5e27 to your computer and use it in GitHub Desktop.
Cora explorations
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"id": "dbeead4f", | |
"metadata": {}, | |
"source": [{ | |
"cells": [{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"id": "dbeead4f", | |
"metadata": {}, | |
"source": [ | |
"# Cora\n", | |
"\n", | |
"A collection of Cora explorations. The focus is on machine learning and not visualization here. Jupyter notebooks are not adequate for visualization, see however the [yFiles Jupyter plugin](https://www.yworks.com/products/yfiles-graphs-for-jupyter).\n", | |
"\n", | |
"*Author*: Francois Vanderseypen, Orbifold Consulting (https://orbifold.net).<br>\n", | |
"*Article*: https://graphsandnetworks.com/the-cora-dataset<br>\n", | |
"*Last update*: July 2023.<br>" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "f59e42e0", | |
"metadata": {}, | |
"source": [ | |
"## Download data\n", | |
"\n", | |
"This part is common to all packages, it downloads and unpacks the necessary data:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 58, | |
"id": "a06b6d68", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import os\n", | |
"import pandas as pd\n", | |
"data_dir = os.path.expanduser(\"~/cora\")\n", | |
"if not os.path.exists(data_dir):\n", | |
" os.makedirs(data_dir)\n", | |
"import requests\n", | |
"\n", | |
" \n", | |
"cora_tgz = os.path.join(data_dir, \"cora.tgz\")\n", | |
"response = requests.get(\"https://temprl.com/cora.tgz\", stream = True)\n", | |
"with open(cora_tgz,'wb') as output:\n", | |
" output.write(response.content)\n", | |
"\n", | |
"import tarfile\n", | |
"with tarfile.open(cora_tgz) as z:\n", | |
" for member in z:\n", | |
" if member.isdir():\n", | |
" continue\n", | |
" fname = member.name.rsplit('/',1)[1]\n", | |
" z.makefile(member,data_dir + '/' + fname)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "aa3525da", | |
"metadata": {}, | |
"source": [ | |
"## NetworkX" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "9bd8820a", | |
"metadata": {}, | |
"source": [ | |
"NetworkX is the most common graph package in Python. It does not perform any machine learning but it has a very complete graph analysis API and performs well on small and medium datasets." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 59, | |
"id": "60559b49", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import networkx as nx\n", | |
"\n", | |
"edge_data = pd.read_csv(os.path.join(data_dir, \"cora.cites\"), sep='\\t', header=None, names=[\"target\", \"source\"])\n", | |
"edge_data[\"label\"] = \"cites\"" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "70c0a3a1", | |
"metadata": {}, | |
"source": [ | |
"The edge list is just a source-target couple and there is no payload:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 60, | |
"id": "ba16ed6c", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<div>\n", | |
"<style scoped>\n", | |
" .dataframe tbody tr th:only-of-type {\n", | |
" vertical-align: middle;\n", | |
" }\n", | |
"\n", | |
" .dataframe tbody tr th {\n", | |
" vertical-align: top;\n", | |
" }\n", | |
"\n", | |
" .dataframe thead th {\n", | |
" text-align: right;\n", | |
" }\n", | |
"</style>\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th>target</th>\n", | |
" <th>source</th>\n", | |
" <th>label</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>741</th>\n", | |
" <td>3191</td>\n", | |
" <td>1127530</td>\n", | |
" <td>cites</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>4347</th>\n", | |
" <td>162080</td>\n", | |
" <td>1109830</td>\n", | |
" <td>cites</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>3549</th>\n", | |
" <td>69198</td>\n", | |
" <td>231198</td>\n", | |
" <td>cites</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>209</th>\n", | |
" <td>114</td>\n", | |
" <td>91975</td>\n", | |
" <td>cites</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>4766</th>\n", | |
" <td>289085</td>\n", | |
" <td>689152</td>\n", | |
" <td>cites</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" target source label\n", | |
"741 3191 1127530 cites\n", | |
"4347 162080 1109830 cites\n", | |
"3549 69198 231198 cites\n", | |
"209 114 91975 cites\n", | |
"4766 289085 689152 cites" | |
] | |
}, | |
"execution_count": 60, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"edge_data.sample(frac=1).head(5)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 61, | |
"id": "658349e2", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"Gnx = nx.from_pandas_edgelist(edge_data, edge_attr=\"label\")\n", | |
"nx.set_node_attributes(Gnx, \"paper\", \"label\")" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 62, | |
"id": "f3e560f3", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"{'label': 'paper'}" | |
] | |
}, | |
"execution_count": 62, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
" Gnx.nodes[1103985]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 63, | |
"id": "a9cafdda", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"feature_names = [\"w_{}\".format(ii) for ii in range(1433)]\n", | |
"column_names = feature_names + [\"subject\"]\n", | |
"node_data = pd.read_csv(os.path.join(data_dir, \"cora.content\"), sep='\\t', header=None, names=column_names)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "42c07961", | |
"metadata": {}, | |
"source": [ | |
"The payload on the node consists of the weights with the subject label:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 64, | |
"id": "c27ee8a9", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<div>\n", | |
"<style scoped>\n", | |
" .dataframe tbody tr th:only-of-type {\n", | |
" vertical-align: middle;\n", | |
" }\n", | |
"\n", | |
" .dataframe tbody tr th {\n", | |
" vertical-align: top;\n", | |
" }\n", | |
"\n", | |
" .dataframe thead th {\n", | |
" text-align: right;\n", | |
" }\n", | |
"</style>\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th>w_0</th>\n", | |
" <th>w_1</th>\n", | |
" <th>w_2</th>\n", | |
" <th>w_3</th>\n", | |
" <th>w_4</th>\n", | |
" <th>w_5</th>\n", | |
" <th>w_6</th>\n", | |
" <th>w_7</th>\n", | |
" <th>w_8</th>\n", | |
" <th>w_9</th>\n", | |
" <th>...</th>\n", | |
" <th>w_1424</th>\n", | |
" <th>w_1425</th>\n", | |
" <th>w_1426</th>\n", | |
" <th>w_1427</th>\n", | |
" <th>w_1428</th>\n", | |
" <th>w_1429</th>\n", | |
" <th>w_1430</th>\n", | |
" <th>w_1431</th>\n", | |
" <th>w_1432</th>\n", | |
" <th>subject</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>31336</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>1</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>Neural_Networks</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1061127</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>0</td>\n", | |
" <td>1</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>Rule_Learning</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1106406</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>Reinforcement_Learning</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>13195</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>Reinforcement_Learning</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>37879</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>Probabilistic_Methods</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"<p>5 rows × 1434 columns</p>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" w_0 w_1 w_2 w_3 w_4 w_5 w_6 w_7 w_8 w_9 ... w_1424 \\\n", | |
"31336 0 0 0 0 0 0 0 0 0 0 ... 0 \n", | |
"1061127 0 0 0 0 0 0 0 0 0 0 ... 0 \n", | |
"1106406 0 0 0 0 0 0 0 0 0 0 ... 0 \n", | |
"13195 0 0 0 0 0 0 0 0 0 0 ... 0 \n", | |
"37879 0 0 0 0 0 0 0 0 0 0 ... 0 \n", | |
"\n", | |
" w_1425 w_1426 w_1427 w_1428 w_1429 w_1430 w_1431 w_1432 \\\n", | |
"31336 0 1 0 0 0 0 0 0 \n", | |
"1061127 1 0 0 0 0 0 0 0 \n", | |
"1106406 0 0 0 0 0 0 0 0 \n", | |
"13195 0 0 0 0 0 0 0 0 \n", | |
"37879 0 0 0 0 0 0 0 0 \n", | |
"\n", | |
" subject \n", | |
"31336 Neural_Networks \n", | |
"1061127 Rule_Learning \n", | |
"1106406 Reinforcement_Learning \n", | |
"13195 Reinforcement_Learning \n", | |
"37879 Probabilistic_Methods \n", | |
"\n", | |
"[5 rows x 1434 columns]" | |
] | |
}, | |
"execution_count": 64, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"node_data.head(5)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "61af1435", | |
"metadata": {}, | |
"source": [ | |
"There are seven subjects:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 65, | |
"id": "5f405208", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"{'Case_Based',\n", | |
" 'Genetic_Algorithms',\n", | |
" 'Neural_Networks',\n", | |
" 'Probabilistic_Methods',\n", | |
" 'Reinforcement_Learning',\n", | |
" 'Rule_Learning',\n", | |
" 'Theory'}" | |
] | |
}, | |
"execution_count": 65, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"set(node_data[\"subject\"])" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "098bc658", | |
"metadata": {}, | |
"source": [ | |
"If you don't like the weights in multiple columns you can merge them:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 66, | |
"id": "5ff5a8b3", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"weight_column_names = node_data.columns[0:-1]\n", | |
"node_data['content'] = node_data[weight_column_names].apply(\n", | |
" lambda x: ','.join(x.dropna().astype(str)),\n", | |
" axis=1\n", | |
")\n", | |
"node_data.drop(weight_column_names, axis=1, inplace=True)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 84, | |
"id": "870e3fae", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<div>\n", | |
"<style scoped>\n", | |
" .dataframe tbody tr th:only-of-type {\n", | |
" vertical-align: middle;\n", | |
" }\n", | |
"\n", | |
" .dataframe tbody tr th {\n", | |
" vertical-align: top;\n", | |
" }\n", | |
"\n", | |
" .dataframe thead th {\n", | |
" text-align: right;\n", | |
" }\n", | |
"</style>\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th>subject</th>\n", | |
" <th>content</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>31336</th>\n", | |
" <td>Neural_Networks</td>\n", | |
" <td>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1061127</th>\n", | |
" <td>Rule_Learning</td>\n", | |
" <td>0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,...</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1106406</th>\n", | |
" <td>Reinforcement_Learning</td>\n", | |
" <td>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>13195</th>\n", | |
" <td>Reinforcement_Learning</td>\n", | |
" <td>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>37879</th>\n", | |
" <td>Probabilistic_Methods</td>\n", | |
" <td>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" subject \\\n", | |
"31336 Neural_Networks \n", | |
"1061127 Rule_Learning \n", | |
"1106406 Reinforcement_Learning \n", | |
"13195 Reinforcement_Learning \n", | |
"37879 Probabilistic_Methods \n", | |
"\n", | |
" content \n", | |
"31336 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,... \n", | |
"1061127 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,... \n", | |
"1106406 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,... \n", | |
"13195 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,... \n", | |
"37879 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,... " | |
] | |
}, | |
"execution_count": 84, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"node_data.head()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "a1e65089", | |
"metadata": {}, | |
"source": [ | |
"Note that the content is not an embedding but is the encoded article content." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 87, | |
"id": "706dde3c", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"node_data['content'] = node_data['content'].apply(lambda x: np.array([int(i) for i in x.split(',')]))\n", | |
"# node_data.astype({'subject': 'str','content':'str'})" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "30af6bfb", | |
"metadata": {}, | |
"source": [ | |
"### Poor man's path to link prediction: Jaccard" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "ae086f04", | |
"metadata": {}, | |
"source": [ | |
"Long before graph machine learning came along, people were predicting edges using very simple algorithms. The Jaccard index (algorithm) basically looks at how the immediate neighborhood of two nodes overlap and the more they overlap the more they are likely to be connected. The idea stems from social network analysis where the more friends you share with somebody, the more likely you know each other." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "fecc7d71", | |
"metadata": {}, | |
"source": [ | |
"The following is a manual calculation for some:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "6c6e78ac", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"for u,v in list(Gnx.edges)[12:20]:\n", | |
" cnbors = list(nx.common_neighbors(Gnx, u, v))\n", | |
" union_size = len(set(Gnx[u]) | set(Gnx[v])) \n", | |
" print(u,v, len(cnbors)/union_size)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "19be9453", | |
"metadata": {}, | |
"source": [ | |
"Using NetworkX you can do the whole graph in one go:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "60c3f13d", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"jaccard_predictions = list(nx.jaccard_coefficient(Gnx))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "e1a7c6e6", | |
"metadata": {}, | |
"source": [ | |
"Filtering out the most likely candidates:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "0453540a", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"jaccard_predictions_top = [(t[0],t[1]) for t in jaccard_predictions if t[2]>0.8]" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "ce922f59", | |
"metadata": {}, | |
"source": [ | |
"Note that none of these are existing edges in the graph:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "de9a9463", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"[t for t in jaccard_predictions_top if Gnx.has_edge(*t)]" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "cb53b0aa", | |
"metadata": {}, | |
"source": [ | |
"There are plenty of nodes which have a fully common neighborhood leading to a probability equal to one. The only case with a partially overlapping neighborhood is the following:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "e2337f85", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
" [t for t in jaccard_predictions if t[2]>0.8 and t[2]!=1]" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "463be756", | |
"metadata": {}, | |
"source": [ | |
"You can see that they differ in a single node:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "b460e857", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"print(\"Common: \",sorted(nx.common_neighbors(Gnx, 14428, 14430)))\n", | |
"print(\"14428:\", list(nx.neighbors(Gnx,14428)))\n", | |
"print(\"14430:\", list(nx.neighbors(Gnx,14430)))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "03d71b71", | |
"metadata": {}, | |
"source": [ | |
"The main problem with Jaccard is the fact that it does not take the payload into account, only the immediate topology is looked at. Even the topology, it's only the first hop and maybe node neighborhoods on a higher level have a lot in common.\n", | |
"This makes Jaccard indicative rather than reliable." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "cc174736", | |
"metadata": {}, | |
"source": [ | |
"### Cosine similarity of the payload\n", | |
"\n", | |
"We can look at the payload only and see whether the existing links are correlated with the payload.\n", | |
"The content can be seen a vectors and if we take the cosine similarity we get:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 108, | |
"id": "f5598ee9", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"from random import sample\n", | |
"import numpy as np\n", | |
"sample_size = 1000\n", | |
"connected_sample=sample(list(Gnx.edges), sample_size)\n", | |
"disconnected_sample=sample(list(nx.complement(Gnx).edges), sample_size)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 100, | |
"id": "66726843", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"assert len([e for e in disconnected_sample if Gnx.has_edge(*e)])==0" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "30637e4e", | |
"metadata": {}, | |
"source": [ | |
"The cosine similarity is simply the dot product of the normalized vectors:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 101, | |
"id": "67b684a0", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"def cosine(u,v):\n", | |
" uc = node_data.loc[u][\"content\"]\n", | |
" vc = node_data.loc[v][\"content\"]\n", | |
" return np.dot(uc, vc)/(np.linalg.norm(uc)*np.linalg.norm(vc))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "3095e532", | |
"metadata": {}, | |
"source": [ | |
"So, for the connected subset we get:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 109, | |
"id": "42b5311b", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"connected_cosine = pd.DataFrame({\"source\":[e[0] for e in connected_sample],\"target\":[e[1] for e in connected_sample]})\n", | |
"connected_cosine[\"cosine\"]= connected_cosine.apply(lambda row: cosine(row.source,row.target), axis=1)\n", | |
"# connected_cosine" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 110, | |
"id": "e2a558c7", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"<Axes: >" | |
] | |
}, | |
"execution_count": 110, | |
"metadata": {}, | |
"output_type": "execute_result" | |
}, | |
{ | |
"data": { | |
"image/png": "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9eqrr1pLly61vvSlL1nHHHOMdfjw4ew1F110kTV8+HDro48+st5//33r+OOPt6688sooHimW3H///Va3bt2s119/3dqwYYP1z3/+0+rQoYP1u9/9LnsN1bM/pk2bZv3iF7+wXn75ZQuA9corr9jOm6jXAwcOWBUVFdbVV19tLV++3Hruueesdu3aWX/6058Clb1ghZFRo0ZZN998c/bvVCpl9enTx5oyZUqEpWq97Ny50wJgzZ4927Isy9q/f79VUlJi/fOf/8xes3LlSguANXfuXMuymj+cZDJpVVZWZq959NFHrU6dOln19fX5fYCYU1NTY51wwgnWjBkzrPPOOy8rjFA9m+O2226zzj77bOn5dDpt9erVy/rNb36TPbZ//36rrKzMeu655yzLsqwVK1ZYAKyPP/44e82bb75pJRIJa9u2beEVvhVx6aWXWt/97ndtx7761a9aV199tWVZVM+m4IURU/X6yCOPWEceeaSt77jtttusgQMHBipvQZppGhoasHDhQowdOzZ7LJlMYuzYsZg7d26EJWu9HDhwAADQtWtXAMDChQvR2Nhoq+NBgwahf//+2TqeO3cuhg0bhoqKiuw148aNQ3V1NT799NM8lj7+3Hzzzbj00ktt9QlQPZvk3//+N0aOHIlvfOMb6NmzJ0499VQ8/vjj2fMbNmxAZWWlra47d+6M0aNH2+q6S5cuGDlyZPaasWPHIplMYt68efl7mBhz5plnYubMmVizZg0AYOnSpZgzZw4uvvhiAFTPYWGqXufOnYtzzz0XpaWl2WvGjRuH1atXY9++fb7L1yo2yjPN7t27kUqlbJ0zAFRUVGDVqlURlar1kk6nceutt+Kss87C0KFDAQCVlZUoLS1Fly5dbNdWVFSgsrIye43oHWTOEc08//zzWLRoET7++GPHOapnc6xfvx6PPvooJk2ahDvvvBMff/wxfvSjH6G0tBTjx4/P1pWoLtm67tmzp+18cXExunbtSnXdwu23347q6moMGjQIRUVFSKVSuP/++3H11VcDANVzSJiq18rKShxzzDGONDLnjjzySF/lK0hhhDDLzTffjOXLl2POnDlRF6XNsWXLFtxyyy2YMWMGysvLoy5OmyadTmPkyJF44IEHAACnnnoqli9fjsceewzjx4+PuHRthxdffBHPPPMMnn32WZx00klYsmQJbr31VvTp04fquYApSDNN9+7dUVRU5FhxUFVVhV69ekVUqtbJxIkT8frrr+Pdd9/FUUcdlT3eq1cvNDQ0YP/+/bbr2Tru1auX8B1kzhHNZpidO3fitNNOQ3FxMYqLizF79mz8/ve/R3FxMSoqKqieDdG7d28MGTLEdmzw4MHYvHkzgFxdufUbvXr1ws6dO23nm5qasHfvXqrrFn72s5/h9ttvx7e+9S0MGzYM11xzDX784x9jypQpAKiew8JUvYbVnxSkMFJaWooRI0Zg5syZ2WPpdBozZ87EmDFjIixZ68GyLEycOBGvvPIK3nnnHYfabsSIESgpKbHV8erVq7F58+ZsHY8ZMwbLli2zNf4ZM2agU6dOjkGhULnggguwbNkyLFmyJPtv5MiRuPrqq7O/qZ7NcNZZZzmWp69ZswZHH300AOCYY45Br169bHVdXV2NefPm2ep6//79WLhwYfaad955B+l0GqNHj87DU8SfQ4cOIZm0Dz1FRUVIp9MAqJ7DwlS9jhkzBu+99x4aGxuz18yYMQMDBw70baIBUNhLe8vKyqynnnrKWrFihXXDDTdYXbp0sa04IOTceOONVufOna1Zs2ZZO3bsyP47dOhQ9pof/OAHVv/+/a133nnHWrBggTVmzBhrzJgx2fOZJadf+MIXrCVLlljTp0+3evToQUtOPWBX01gW1bMp5s+fbxUXF1v333+/9dlnn1nPPPOM1b59e+vpp5/OXjN16lSrS5cu1muvvWZ98skn1pe//GXh0shTTz3VmjdvnjVnzhzrhBNOKPglpyzjx4+3+vbtm13a+/LLL1vdu3e3fv7zn2evoXr2R01NjbV48WJr8eLFFgDrwQcftBYvXmxt2rTJsiwz9bp//36roqLCuuaaa6zly5dbzz//vNW+fXta2huEP/zhD1b//v2t0tJSa9SoUdZHH30UdZFaDQCE/5588snsNYcPH7Zuuukm68gjj7Tat29vfeUrX7F27NhhS2fjxo3WxRdfbLVr187q3r279ZOf/MRqbGzM89O0LnhhhOrZHP/5z3+soUOHWmVlZdagQYOsP//5z7bz6XTauuuuu6yKigqrrKzMuuCCC6zVq1fbrtmzZ4915ZVXWh06dLA6depkTZgwwaqpqcnnY8Sa6upq65ZbbrH69+9vlZeXW8cee6z1i1/8wrZUlOrZH++++66wXx4/frxlWebqdenSpdbZZ59tlZWVWX379rWmTp0auOwJy2LC3hEEQRAEQeSZgvQZIQiCIAgiPpAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpPx/sFquoEdWNM8AAAAASUVORK5CYII=", | |
"text/plain": [ | |
"<Figure size 640x480 with 1 Axes>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"connected_cosine.cosine.plot()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "0baec06b", | |
"metadata": {}, | |
"source": [ | |
"With an average cosine:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 111, | |
"id": "618ebbec", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"0.16600344225511338" | |
] | |
}, | |
"execution_count": 111, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"np.average(connected_cosine.cosine)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 112, | |
"id": "a7bdd2ac", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"disconnected_cosine = pd.DataFrame({\"source\":[e[0] for e in disconnected_sample],\"target\":[e[1] for e in disconnected_sample]})\n", | |
"disconnected_cosine[\"cosine\"]= disconnected_cosine.apply(lambda row: cosine(row.source,row.target), axis=1)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "fc647f1f", | |
"metadata": {}, | |
"source": [ | |
"Visual inspection reveals that the disconnected nodes have on average a lower consine:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 113, | |
"id": "572b9faf", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"<Axes: >" | |
] | |
}, | |
"execution_count": 113, | |
"metadata": {}, | |
"output_type": "execute_result" | |
}, | |
{ | |
"data": { | |
"image/png": "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/nnWv39/9vjjjzsqe84KI1dccQW75ZZbUn9Ho1E2ZswYtnDhQh9Llb3U1tYyAGzVqlWMMcaamppYv3792IsvvphKs3v3bgaAVVRUMMbiH044HGbV1dWpNI8++igbPHgw6+rqyuwDBJzW1lZ23nnnseXLl7NPfvKTKWGE6tk9fvazn7Grr75aeD4Wi7HRo0ez+++/P3WsqamJFRYWsueff54xxtiuXbsYALZ+/fpUmn//+98sFAqxY8eOeVf4LOLaa69l3/3ud3XHvvrVr7IbbriBMUb17BZGYcStev3Tn/7Ehg0bpus7fvazn7Hzzz/fUXlzcpkmEolg48aNKC0tTR0Lh8MoLS1FRUWFjyXLXpqbmwEAw4cPBwBs3LgR3d3dujqeOHEixo8fn6rjiooKXHzxxSgpKUmlmTlzJlpaWrBz584Mlj743HLLLbj22mt19QlQPbvJv/71L0ybNg3f+MY3MGrUKFx66aV48sknU+cPHTqE6upqXV0PGTIE06dP19X10KFDMW3atFSa0tJShMNhrF27NnMPE2CuvPJKlJeXY9++fQCArVu3YvXq1fj85z8PgOrZK9yq14qKCnziE59AQUFBKs3MmTOxd+9enDx50nb5smKjPLepr69HNBrVdc4AUFJSgj179vhUquwlFovhtttuw1VXXYWLLroIAFBdXY2CggIMHTpUl7akpATV1dWpNLx3kDxHxFmyZAk2bdqE9evXp52jenaPgwcP4tFHH0VZWRluv/12rF+/Hj/84Q9RUFCA2bNnp+qKV5fauh41apTufH5+PoYPH051neDnP/85WlpaMHHiROTl5SEajeK+++7DDTfcAABUzx7hVr1WV1fjrLPOSssjeW7YsGG2ypeTwgjhLrfccgt27NiB1atX+12UPkdVVRVuvfVWLF++HEVFRX4Xp08Ti8Uwbdo0/PrXvwYAXHrppdixYwcee+wxzJ492+fS9R1eeOEFPPvss3juuedw4YUXYsuWLbjtttswZswYquccJieXaUaOHIm8vLw0j4OamhqMHj3ap1JlJ/PmzcPrr7+OFStW4IwzzkgdHz16NCKRCJqamnTptXU8evRo7jtIniPiyzC1tbW47LLLkJ+fj/z8fKxatQq///3vkZ+fj5KSEqpnlzj99NMxadIk3bELLrgAlZWVAHrryqzfGD16NGpra3Xne3p60NjYSHWd4Cc/+Ql+/vOf45vf/CYuvvhifOc738GPfvQjLFy4EADVs1e4Va9e9Sc5KYwUFBRg6tSpKC8vTx2LxWIoLy/HjBkzfCxZ9sAYw7x58/Dyyy/j3XffTVPbTZ06Ff369dPV8d69e1FZWZmq4xkzZmD79u26xr98+XIMHjw4bVDIVT7zmc9g+/bt2LJlS+q/adOm4YYbbkj9pnp2h6uuuirNPX3fvn0488wzAQBnnXUWRo8eravrlpYWrF27VlfXTU1N2LhxYyrNu+++i1gshunTp2fgKYJPR0cHwmH90JOXl4dYLAaA6tkr3KrXGTNm4L333kN3d3cqzfLly3H++efbXqIBkNuuvYWFheyZZ55hu3btYv/93//Nhg4dqvM4IMT84Ac/YEOGDGErV65kJ06cSP3X0dGRSvP973+fjR8/nr377rtsw4YNbMaMGWzGjBmp80mX089+9rNsy5YtbNmyZey0004jl1MLtN40jFE9u8W6detYfn4+u++++9hHH33Enn32WVZcXMz+/ve/p9IsWrSIDR06lL366qts27Zt7Mtf/jLXNfLSSy9la9euZatXr2bnnXdezrucapk9ezYbO3ZsyrX3pZdeYiNHjmQ//elPU2monu3R2trKNm/ezDZv3swAsIceeoht3ryZHTlyhDHmTr02NTWxkpIS9p3vfIft2LGDLVmyhBUXF5NrrxP+8Ic/sPHjx7OCggJ2xRVXsDVr1vhdpKwBAPe/p59+OpWms7OT3XzzzWzYsGGsuLiYfeUrX2EnTpzQ5XP48GH2+c9/nvXv35+NHDmS/c///A/r7u7O8NNkF0ZhhOrZPV577TV20UUXscLCQjZx4kT2xBNP6M7HYjH2y1/+kpWUlLDCwkL2mc98hu3du1eXpqGhgV1//fVs4MCBbPDgwWzOnDmstbU1k48RaFpaWtitt97Kxo8fz4qKitjZZ5/N7rjjDp2rKNWzPVasWMHtl2fPns0Yc69et27dyq6++mpWWFjIxo4dyxYtWuS47CHGNGHvCIIgCIIgMkxO2owQBEEQBBEcSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJX/n9XfdMsKBNREQAAAABJRU5ErkJggg==", | |
"text/plain": [ | |
"<Figure size 640x480 with 1 Axes>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"disconnected_cosine.cosine.plot()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "16d4f01a", | |
"metadata": {}, | |
"source": [ | |
"On average the cosine similarity is three times higher for connected nodes:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 115, | |
"id": "10361735", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"2.8722134876583296" | |
] | |
}, | |
"execution_count": 115, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"np.average(connected_cosine.cosine)/np.average(disconnected_cosine.cosine)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "70d7e475", | |
"metadata": {}, | |
"source": [ | |
"This shows that connectivity is correlated with the payload of the nodes and can be used to predict links." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "c3ce4f38", | |
"metadata": {}, | |
"source": [ | |
"Let's see how predictive this is. Looking at the plot you can see that cosine similarity above 0.1 seems to be a threshold:\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 145, | |
"id": "57cf7449", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"cosine_threshold = 0.1\n", | |
"connected_cosine[\"cosine_prediction\"]= connected_cosine.apply(lambda row: row.cosine>cosine_threshold, axis=1)\n", | |
"disconnected_cosine[\"cosine_prediction\"]= disconnected_cosine.apply(lambda row: row.cosine>cosine_threshold, axis=1)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "a3df371d", | |
"metadata": {}, | |
"source": [ | |
"The confusion matrix for this prediction can be assembled as follows:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 146, | |
"id": "fc21cead", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"image/png": "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", | |
"text/plain": [ | |
"<Figure size 640x480 with 2 Axes>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"import seaborn as sn\n", | |
"import pandas as pd\n", | |
"import matplotlib.pyplot as plt\n", | |
"confusion_01 = disconnected_cosine[\"cosine_prediction\"].sum()\n", | |
"confusion_00 = sample_size - confusion_01\n", | |
"confusion_11 = connected_cosine[\"cosine_prediction\"].sum()\n", | |
"confusion_10 = sample_size - confusion_11\n", | |
"array = np.array([[confusion_00, confusion_01],\n", | |
" [confusion_10, confusion_11]\n", | |
" ])*100/sample_size\n", | |
"\n", | |
"df_cm = pd.DataFrame(array, range(2), range(2))\n", | |
"# plt.figure(figsize=(10,7))\n", | |
"sn.set(font_scale=1.4) # for label size\n", | |
"sn.heatmap(df_cm, annot=True, annot_kws={\"size\": 16}) # font size\n", | |
"\n", | |
"plt.show()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "d7c2c045", | |
"metadata": {}, | |
"source": [ | |
"This shows that prediction the edges purely on the basis of the node content is not too bad. " | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "507a5531", | |
"metadata": {}, | |
"source": [ | |
"### Combined Jaccard and cosine similarity\n", | |
"\n", | |
"It's natural to wonder whether the topological similarity improves the cosine prediction.\n", | |
"There are various ways the probabilities could be combined. Let's use the optimistic approach and take the maximum:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 164, | |
"id": "0e0d5c92", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"combined_threshold = 0.1\n", | |
"\n", | |
"connected_cosine[\"jaccard\"]= connected_cosine.apply(lambda row: list(nx.jaccard_coefficient(Gnx, [(row.source, row.target)]))[0][2], axis=1)\n", | |
"connected_cosine[\"combined_prediction\"]= connected_cosine.apply(lambda row: max(row.cosine,row.jaccard)>combined_threshold, axis=1)\n", | |
"\n", | |
"disconnected_cosine[\"jaccard\"]= disconnected_cosine.apply(lambda row: list(nx.jaccard_coefficient(Gnx, [(row.source, row.target)]))[0][2], axis=1)\n", | |
"disconnected_cosine[\"combined_prediction\"]= disconnected_cosine.apply(lambda row: max(row.cosine,row.jaccard)>combined_threshold, axis=1)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 165, | |
"id": "9710d284", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"image/png": "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", | |
"text/plain": [ | |
"<Figure size 640x480 with 2 Axes>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"confusion_01 = disconnected_cosine[\"combined_prediction\"].sum()\n", | |
"confusion_00 = sample_size - confusion_01\n", | |
"confusion_11 = connected_cosine[\"combined_prediction\"].sum()\n", | |
"confusion_10 = sample_size - confusion_11\n", | |
"array = np.array([[confusion_00, confusion_01],\n", | |
" [confusion_10, confusion_11]\n", | |
" ])*100/sample_size\n", | |
"\n", | |
"df_cm = pd.DataFrame(array, range(2), range(2))\n", | |
"# plt.figure(figsize=(10,7))\n", | |
"sn.set(font_scale=1.4) # for label size\n", | |
"sn.heatmap(df_cm, annot=True, annot_kws={\"size\": 16}) # font size\n", | |
"\n", | |
"plt.show()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "57644303", | |
"metadata": {}, | |
"source": [ | |
"This gives **an accuracy of 0.76** (= (78+74)/200). Altogether not a bad score for this simplistic approach." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "558d0ab2", | |
"metadata": {}, | |
"source": [ | |
"## Node2Vec\n", | |
"\n", | |
"The node2vec embedding learns low-dimensional representations for nodes in a graph through the use of random walks through a graph starting at a target node. The random walk effectively assembles 'sentences' and this allows one to use the Word2Vec mechanics. " | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "c810d04f", | |
"metadata": {}, | |
"source": [ | |
"Let's create a basic node2vec embedding:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 168, | |
"id": "2ac8451e", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"application/vnd.jupyter.widget-view+json": { | |
"model_id": "393df34b5b9141dda2adea339944e580", | |
"version_major": 2, | |
"version_minor": 0 | |
}, | |
"text/plain": [ | |
"Computing transition probabilities: 0%| | 0/2708 [00:00<?, ?it/s]" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
}, | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"Generating walks (CPU: 1): 100%|██████████| 50/50 [00:07<00:00, 6.78it/s]\n", | |
"Generating walks (CPU: 2): 100%|██████████| 50/50 [00:07<00:00, 6.78it/s]\n", | |
"Generating walks (CPU: 3): 100%|██████████| 50/50 [00:07<00:00, 6.72it/s]\n", | |
"Generating walks (CPU: 4): 100%|██████████| 50/50 [00:07<00:00, 6.75it/s]\n" | |
] | |
} | |
], | |
"source": [ | |
"from node2vec import Node2Vec\n", | |
"node2vec = Node2Vec(Gnx, dimensions=64, walk_length=30, num_walks=200, workers=4) \n", | |
"\n", | |
"# Embed nodes\n", | |
"model = node2vec.fit(window=10, min_count=1, batch_words=4) \n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "656d9f40", | |
"metadata": {}, | |
"source": [ | |
"This will compute the cosine similarity based on the embedding." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 186, | |
"id": "2bf529ae", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"def vector_cosine(u,v): \n", | |
" uc = model.wv[str(u)]\n", | |
" vc = model.wv[str(v)]\n", | |
" return np.dot(uc, vc)/(np.linalg.norm(uc)*np.linalg.norm(vc))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "2f464e61", | |
"metadata": {}, | |
"source": [ | |
"Just like in the previous approaches we'll add it to the dataframe and compute the confusion matrix:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 199, | |
"id": "de4ea4a9", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"embedding_threshold = 0.8\n", | |
"\n", | |
"connected_cosine[\"embedding\"]= connected_cosine.apply(lambda row: vector_cosine(row.source, row.target), axis=1)\n", | |
"connected_cosine[\"embedding_prediction\"]= connected_cosine.apply(lambda row: row.embedding>embedding_threshold, axis=1)\n", | |
"\n", | |
"disconnected_cosine[\"embedding\"]= disconnected_cosine.apply(lambda row: vector_cosine(row.source, row.target), axis=1)\n", | |
"disconnected_cosine[\"embedding_prediction\"]= disconnected_cosine.apply(lambda row: row.embedding>embedding_threshold, axis=1)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 200, | |
"id": "e6610194", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAh0AAAGlCAYAAABeEURiAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA8fElEQVR4nO3dd1yW9f7H8TfIVsCBOCEnbsyN4rbSUtNCUfNo08xMaU/LxlHTsuEox0mxoSRl2S8rFffMkaM0coCKKDhAEVRubuD3B3kXAcp1iTdgr+d58Dh1XV+u+8s5pu8+n+/3ezlkZ2dnCwAA4AZzLO4JAACAfwdCBwAAsAtCBwAAsAtCBwAAsAtCBwAAsAtCBwAAsAtCBwAAsAtCBwAAsAun4p5AYWWciSnuKQAlknv1TsU9BaDEsVrib/hnFNWfS84+dYrkOaUBlQ4AAGAXpabSAQBAiZKVWdwzKHUIHQAAmJGdVdwzKHVorwAAALug0gEAgBlZVDqMInQAAGBCNu0VwwgdAACYQaXDMNZ0AAAAu6DSAQCAGbRXDCN0AABgBud0GEZ7BQAA2AWVDgAAzKC9YhihAwAAM9i9YhjtFQAAYBdUOgAAMIHDwYwjdAAAYAbtFcNorwAAALug0gEAgBm0VwwjdAAAYAaHgxlG6AAAwAwqHYaxpgMAANgFlQ4AAMxg94phhA4AAMygvWIY7RUAAGAXVDoAADCD9ophhA4AAEzIzmbLrFG0VwAAgF1Q6QAAwAwWkhpG6AAAwAzWdBhGewUAANgFlQ4AAMygvWIYoQMAADN44ZthhA4AAMyg0mEYazoAAIBdUOkAAMAMdq8YRugAAMAM2iuG0V4BAAB2QaUDAAAzaK8YRugAAMAMQodhtFcAAIBdUOkAAMAEXm1vHKEDAAAzaK8YRnsFAADYBZUOAADM4JwOwwgdAACYQXvFMEIHAABmUOkwjDUdAADALqh0AABgBu0VwwgdAACYQXvFMNorAADALqh0AABgBu0VwwgdAACYQegwjPYKAACwCyodAACYwUJSwwgdAACYQXvFMNorAADALqh0AABgBu0VwwgdAACYQXvFMEIHAABmUOkwjDUdAADALqh0AABgBu0VwwgdAACYQegwjPYKAACwCyodAACYkZ1d3DModQgdAACYQXvFMNorAADALqh0AABgRgmpdGRmZuqzzz7T119/rSNHjsjJyUlNmjTRQw89pO7du+cam5WVpcWLFysiIkJHjx6Vq6urgoKCFBYWptq1a+d5dnp6uhYsWKBvv/1W8fHx8vT0VNeuXTV27Fj5+voaniuVDgAAzMjOKpqv6/Tss89q0qRJunDhggYNGqTevXtr3759GjVqlD799NNcY1977TWNHz9emZmZuu+++xQcHKyVK1cqJCRE0dHRucZarVY98cQTmjp1qry9vTV8+HAFBgYqMjJSISEhSkhIMDxXh+zs0rESJuNMTHFPASiR3Kt3Ku4pACWO1RJ/wz/j0uevFMlz3P8zwfT3/vzzzxo+fLjq1KmjyMhIlStXTpJ0+PBhDRgwQJmZmVq3bp0qVKig9evXa8SIEerYsaNmz54tJ6ecZseGDRs0YsQINW7cWEuWLLE9e9GiRXr99dcVEhKiiRMn2q4vXrxYr776qu644w5Nnz7d0HypdAAAYEZWVtF8XYc9e/ZIknr37m0LHJJUt25dBQUFKT09Xfv27ZMkhYeHS5LCwsJsgUOSOnXqpK5du2rfvn3avXu37Xp4eLgcHR319NNP5/rM0NBQBQQEKCoqSomJiYbmS+gAAMCM7Oyi+boOFSpUkCTFx+et7FwJBBUrVpTVatX27dvl7e2tZs2a5RkbHBwsSdq8ebMk6eTJkzpy5IgCAgLk4+OT7/isrCxt3brV0HxZSAoAgBlFtJC0R48eV72/atWqAu/17NlT06ZN09KlS9W0aVP16dNHFotFc+fO1b59+9SpUyc1btxYR48elcViUYMGDeTg4JDnOf7+/pKkmJicpQyxsbGSpFq1auX7uX5+frnGFxaVDgAASikvLy9FRESoXbt2evPNN9W2bVt17NhRCxYs0KBBgzRz5kxJUnJysiTJ29u7wOdI0oULFwo1/sr1K+MLi0oHAABmFFGl42qVjGuxWCyaOXOmfv75Z9WvX19BQUG6ePGi1q5dqyVLlsjHx0djx46V1WqVJDk7O+f7HBcXF0k5W2QlKSMjI9f1a40vLEIHAABmFMF21+s1efJkff311woJCdGbb75pWyCanJyshx9+WDNnzlSNGjUUEBAg6a8w8U8Wi0WS5OHhIUlyc3PLdf1a4wuL9goAAKVQVlaWIiMj5eLionHjxuXakVKhQgWNGzdOkvTll1+qfPnykgpuh6SkpEj6q81yrfbJ+fPnc40vLCodAACYkJ1VvMdcnT17Vunp6apVq1a+FYcGDRpIkk6cOKEaNWrIzc1Nx44dy/dZV67Xq1dPUs6W279f/6e4uLhc4wuLSgcAAGYU8zkd3t7ecnFxUUJCgtLS0vLcv7IDxdfXV46OjmrdurWSk5PznDwqSZs2bZIktWnTxvY9tWvXVnR0tJKSkvId7+joqFatWhmaM6EDAIBSyMXFRXfccYcuX76syZMnK+tvASYtLU1vv/22JOnuu++WlHOol5SzDuTvazU2bNigtWvXKjAwUM2bN7ddDw0NldVq1ZQpU/T3w8sXL16sAwcOqGfPnobfv8Ix6EApxzHoQF72OAb94sdjiuQ5HqOMHSX+d0lJSRo6dKhiYmIUEBCg4OBgXbx4UevWrVNCQoK6d++u6dOn29Z7jB07VsuXL1edOnXUvXt3JSYm6scff5S7u7s+//xzNWzY0PbsjIwMDRs2TLt27VKzZs0UFBSk2NhYRUVFqVq1aoqIiFDVqlUNzZfQAZRyhA4gL7uEjplPFMlzPEbPuK7vT01N1SeffKLly5crLi5OZcqUUf369XXvvfdq0KBBcnT8q6lhtVoVHh6uJUuWKC4uTt7e3mrdurXGjBljW8fxdxcvXtTs2bO1bNkyJSQkqHLlygoODtaYMWNUpUoVw3MldAClHKEDyMsuoWP640XyHI8xHxXJc0oD1nTchLbv2qtmHe/SV9/9VKzziFq3ScNGPaMOvQaqfc8BeiTsZW3dsavA8dt27tHIp8epfc8Bat29v/r/5zHNmr9Qlw0ePgMUFxcXF/2yc6WslnjVrVuruKcDlDhsmb3JxB49rufHT1ZxF7DmLIjQtDkL5O7upnYtm+tyerq279qjn3fu1hsvhunePj1zjV++eoOefW2SJKl500aqWN5bv+7/QzP+95lWrt2kBR9NUbmyZYvjRwEKbcJbLyqwWePingbspYhOJP03odJxE/l5527dP/o5nT6bd3tTUZn5yedqGnynvl22ssAx0QdjNG3OAvn6VNK3n83SjCmv638fTtL86ZPl5uaqie99rFOnz9rGnzufonETpqqMo6PmvD9Bn8+aqmlvv6YfI+epU/s2+uNQjOYsiLhhPxNQFLp1DVZY2IjingbsqQS8Zba0IXTcBM4mn9Nb787QiCdfUUrKBVWrYmwLU1FbELFEkvTYg/epRrW/Fhq1bN5U9w++V5fT07X422W261HrNunS5XT1vqOb2rdpYbvu5uqqxx8aKknasHWHnWYPGOft7aVP/ve+Dh6K1cmTicU9HaDEInTcBOYuiNCX3yyTf41q+mTa22rbMvCq41MupOrD2eHqO2SEWna7W8F3hurx58brlz2/Fcl8NmzZLknq3rl9nnu3de4gSVq3eZvtWkjfXlr+VbjCRj6QZ/zFS5ckSU5lyhTJ3IAbYcb0iapevYoefDBM6en5v6sCN6FiPhysNGJNx02gZo1qGvfsaIX07SVnJyct+X55gWMTTp3WQ2Ne1LHjJ1TF10cd27VWyoUL2rh1hzZu3aHxz49VSN+eBX7/tZw5m6Rz51NUobyXfCpWyHO/Ti0/OTg46PCRY8rMzFSZMmXk4OCQqyJyxanTZzV15jxJ0t133mZ6TsCNNGhQPw0ZfI8mTPxA27YXvFAaN6FiPga9NDIcOiwWi6KiorRlyxbFxMQoJSVFFotFHh4e8vT0VP369dW6dWvdfvvtuV4+gxvnPwP7FXrsi2++o2PHT+j+IffqyccelPOf/x/t3Retx555Vf+dOkO3Nm2ourVvMTWXU2dy1pP4VKqY730XFxd5eZbT+ZQLSk27KG8vzzxj5iyI0OZtO7X7t5yjeh8ZNsjQzwjYS82a1TVj2kTt/GWv3vrv+8U9HaDEM5QKNm3apFdeeUWJiYkF7o7Ytm2bFi5cqGrVqmnChAlq3z5viR3FY+++aO3Y9asa1KujZx5/ONeBMYFNGmrkA0P0zvS5+jzyO41/PuekvTtC7teJhFN5njVu4nsaN/E929/3u/M2TRj3jC5duixJcnd1LXAebq4uOi/p4sVL+YaOH6PW6WDMEUmSi4uzEk+fUfK586pYobyJnxq4ceZ/8oHc3d304ENhslqtxT0d2FsJeLV9aVPo0LF3716NHDlSzs7OGjp0qIKDg+Xv7y8vLy+5uLjIYrEoJSVFx44d08aNG7VkyRKNHDlSCxcuVNOmTW/kz4BC2vbLXklS6xbNcgWOKzq2a6V3ps/Vjl17bdd6dO6gpHPnbX9/4HCsDh4+ouZNG6lm9b+Ov721WSNJkmOZnOc6ODhccz5ZBQTXWe+9pfJeXjp85Jje/3ie/u+nVdoffVBfhc+Qs7NzIX5S4MZ76smR6tYtWM89/6b27z9Q3NNBcaC9YlihQ8dHH30kZ2dnLVq0KNfZ7H9XuXJl1a1bV926ddPAgQM1ZMgQzZgxQ7NmzSqyCcO8k4k5FYsvIpfqi8ilBY5LOHXa9tcvhI3MdW/mJ5/r4OEjGnj3nerf+/Y83+vh7i5JunyVxXRX7nm4u+V7v0plH0lS4wb19NE7byj04bE6ePiIlq1Ym+9nAvbWtGlDvfXm81q/fos++HBOcU8HKDUKHTp27dqlPn36FBg4/qlhw4bq06ePVq9ebXpyKFpX3kDYtFGAbvGrUeC4wlQpClKlciVJ0pmk5HzvWywWpVxIlbOzU76tlX9ydnZWrx6ddfDwEe0/cIjQgRJhwlsvyc3NTVlZ2Qqf/2Guez4+OeuZpkx+VampaZr09jRFRx8qjmniBsv+l+08KQqFDh2ZmZny9Lz2HxJ/V65cOaWlpRmeFG6MK4s7O7RtqbGP3n9DPqO8t5d8KlXQmbPJOnc+ReW9vXLdP3zkmLKzs1Wv9i22Fs+3y1Zq687dGnJvHzVv2ijPM13+bKnQM0dJUa6chySpa9cOBY7pd3cvSdK8eYsIHTcr2iuGFfqcjrp162rlypVKL+R7MFJTU/XTTz+pTp06pieHotXm1maSpI1bd9qqHn8XtW6T+t73qN569/reeNgxqLUkafWGLXnurVq3WZLUqX0b27Xog4f1/fLVWvL9inyft+nnnZKkxg3qX9e8gKLS4/aBcnKpke/XkSNxkqQGjYLl5FJD69bn/ecAN4nsrKL5+hcpdOh44IEHFBcXp0GDBmnFihVKTU3Nd9ylS5e0evVqDR06VAkJCRo6dGiRTRbXp03LQDWsX0f7/zioqTM/UUZGhu3eseMnNOmDWYo9Gqda/jULfMboh/+j3zb9eNU2x+B7+sjR0VHT5ixQ7NHjtuu7ft2vBV9+I1cXF9034G7b9QF336kyZRz1zbIVuYJKZmamZvzvM23dsVtVfH101+1dTf7kAICSoNDtlTvvvFNHjhzR9OnTFRYWJkmqWLGivL295ezsrIyMDKWkpCgpKcm2nfbBBx9USEjIjZk5DHNwcNC7b76kh8e+qAURS/Rj1Do1alBX6ekW7dj9m6xWq27vGqz7Qvpe1+c0bRSgR4cP0qzwRRrwwGi1a32rLJYMbd+1R1lZ2Xr7tedyHRxWr84ten7Mo3r7w9ka++KbatooQL4+lRR98LBOJJxShfJemjbptQIXngJAsaC9YpihczpGjRqlO+64Q+Hh4dq6dauOHz+us2f/enFXmTJl5O/vr3bt2mngwIFslS2BavnXVOT8GZq/8Gut2bBFW7bvUlkPdzVtFKABfXupT8/uKlMER44/MWK4at/ip88jl2r7L3vk5uaqNi2a69H7B+d7TPvQgf1Uv25tzV/4lfb89ruiD8aoqq+P7htwtx75T6h8/1ygCgAlBgtJDXPIvo53oFutVp07d05Wq1Wurq7y9PS8YaeQZpyJuSHPBUo79+qdinsKQIljtcTf8M9Ie31IkTyn7OuLiuQ5pcF1JQQnJyf5+PgU1VwAACg9aK8YxstRAAAw41+286Qo8Gp7AABgF1Q6AAAwg/aKYYQOAABM4Bh042ivAAAAu6DSAQCAGbRXDCN0AABgBqHDMEIHAABmsGXWMNZ0AAAAu6DSAQCAGbRXDCN0AABgQjahwzDaKwAAwC6odAAAYAaVDsMIHQAAmMGJpIbRXgEAAHZBpQMAADNorxhG6AAAwAxCh2G0VwAAgF1Q6QAAwITsbCodRhE6AAAwg/aKYYQOAADMIHQYxpoOAABgF1Q6AAAwgXevGEfoAADADEKHYbRXAACAXVDpAADADF69YhihAwAAE1jTYRztFQAAYBdUOgAAMINKh2GEDgAAzGBNh2G0VwAAgF1Q6QAAwAQWkhpH6AAAwAzaK4YROgAAMIFKh3Gs6QAAAHZBpQMAADNorxhG6AAAwIRsQodhtFcAAIBdUOkAAMAMKh2GEToAADCB9opxhA4AAEq57du3a+7cudq9e7cyMjLk5+ene++9V/fdd59cXFxs47KysrR48WJFRETo6NGjcnV1VVBQkMLCwlS7du08z01PT9eCBQv07bffKj4+Xp6enuratavGjh0rX19fw/N0yM7OLhUbjTPOxBT3FIASyb16p+KeAlDiWC3xN/wzzvTsUiTP8Vm+7rq+f/HixXrttddUrlw59erVS+7u7lq7dq2OHTumO++8U++//74cHBwkSePGjVNkZKQCAgLUuXNnJSQk6KeffpKrq6sWLlyohg0b2p5rtVo1atQorV+/Xi1btlTr1q11+PBhrVq1Sr6+voqMjFTVqlUNzZXQAZRyhA4gL3uEjtO3F03oqLzSfOiIiYlRv3795OPjo88++0w1a9aUlFOhGD58uHbv3q358+erQ4cOWr9+vUaMGKGOHTtq9uzZcnLKaXZs2LBBI0aMUOPGjbVkyRLbsxctWqTXX39dISEhmjhxou364sWL9eqrr+qOO+7Q9OnTDc2X3SsAAJRSn376qSwWi1555RVb4JAkV1dXPfXUUwoJCZHVapUkhYeHS5LCwsJsgUOSOnXqpK5du2rfvn3avXu37Xp4eLgcHR319NNP5/rM0NBQBQQEKCoqSomJiYbmS+gAAMCE7Kyi+boeq1evtq2z+KegoCBNnDhRnTt3ltVq1fbt2+Xt7a1mzZrlGRscHCxJ2rx5syTp5MmTOnLkiAICAuTj45Pv+KysLG3dutXQfAkdAACYUNyhIzk5WYmJiapbt65SUlL01ltvqUuXLmrWrJnuuusuhYeHKysr5wPi4+NlsVjk7+9vW9/xd/7+/pJy2jWSFBsbK0mqVatWvp/t5+eXa3xhsXsFAAAzsvP+4W1Gjx49rnp/1apV+V6/0tqwWCwaMGCAMjIy1K1bN2VnZ2v16tWaNGmSfv31V02dOlXJycmSJG9v73yf5eXlJUm6cOGCJF1z/JXrV8YXFqEDAIBSKC0tTZK0f/9+NW3aVPPmzbOFgSeffFJDhw7V999/rx49eti2tzo7O+f7rCvbatPT0yVJGRkZua5fa3xhEToAADChqA4HW7U2/0rGtZQpU8b21y+//HKuqkSlSpX05JNPKiwsTN99951Gjx4t6a8w8U8Wi0WS5OHhIUlyc3PLdf1a4wuL0AEAgAnZWUXTXjHL09NTkuTg4JDv4tCmTZtKko4ePary5ctLKrgdkpKSIumvNsu12ifnz5/PNb6wWEgKAEAp5OfnJ2dnZ2VnZ+dbwbiyVdbd3V01atSQm5ubjh07lu+zrlyvV6+eJKlu3bq5rv9TXFxcrvGFRegAAMCE4t694uLiohYtWkiSNm7cmOf+nj17JEmNGjWSo6OjWrdureTkZEVHR+cZu2nTJklSmzZtJEm+vr6qXbu2oqOjlZSUlO94R0dHtWrVytCcCR0AAJiQne1QJF/XY/jw4ZKkqVOn6syZM7brp0+f1owZM+Tg4KDQ0FBJsv335MmTc63V2LBhg9auXavAwEA1b97cdj00NFRWq1VTpkzR3w8vX7x4sQ4cOKCePXsafv8Kx6ADpRzHoAN52eMY9Pj23YvkOTW2rL6u7//vf/+rzz77TOXLl1evXr0kSVFRUTpz5owef/xxhYWF2caOHTtWy5cvV506ddS9e3clJibqxx9/lLu7uz7//PNc717JyMjQsGHDtGvXLjVr1kxBQUGKjY1VVFSUqlWrpoiICN69AvzbEDqAvOwROo63K5rQUfPn6wsdkvTDDz/oiy++0P79++Xg4KAGDRro/vvvt4WQK6xWq8LDw7VkyRLFxcXJ29tbrVu31pgxY2zrOP7u4sWLmj17tpYtW6aEhARVrlxZwcHBGjNmjKpUqWJ4noQOoJQjdAB52SN0xLW5+qFeheW33dyW2dKINR0AAMAuOKcDAAATSkefoGQhdAAAYEJxHw5WGhE6AAAwgdBhHGs6AACAXVDpAADABNZ0GEfoAADABNorxtFeAQAAdkGlAwAAE673vSn/RoQOAABMuJ43xP5b0V4BAAB2QaUDAAATsmivGEboAADABNZ0GEd7BQAA2AWVDgAATOCcDuMIHQAAmMCJpMYROgAAMIFKh3Gs6QAAAHZBpQMAABPYMmscoQMAABPYMmsc7RUAAGAXVDoAADCB3SvGEToAADCBNR3G0V4BAAB2QaUDAAATWEhqHKEDAAATWNNhHO0VAABgF1Q6AAAwgYWkxpWa0NG5+cPFPQWgRLrw1VPFPQXgX4k1HcaVmtABAEBJQqXDONZ0AAAAu6DSAQCACWxeMY7QAQCACbRXjKO9AgAA7IJKBwAAJrB7xThCBwAAJmQV9wRKIdorAADALqh0AABgQrZorxhF6AAAwIQs9swaRnsFAADYBZUOAABMyKK9YhihAwAAE1jTYRyhAwAAE9gyaxxrOgAAgF1Q6QAAwATaK8YROgAAMIH2inG0VwAAgF1Q6QAAwAQqHcYROgAAMIE1HcbRXgEAAHZBpQMAABOyKHQYRugAAMAEjkE3jvYKAACwCyodAACYwJvtjSN0AABgAltmjSN0AABgQpYDazqMYk0HAACwCyodAACYwJoO4wgdAACYwJoO42ivAABwE4mJidGtt96qfv365bmXlZWliIgI9e/fXy1atFBQUJCefPJJxcbG5vus9PR0zZkzR3fddZeaN2+ujh07aty4cTp16pSpuRE6AAAwIcuhaL6KktVq1XPPPadLly7le/+1117T+PHjlZmZqfvuu0/BwcFauXKlQkJCFB0dnedZTzzxhKZOnSpvb28NHz5cgYGBioyMVEhIiBISEgzPj/YKAAAmlMQTSWfMmKHffvst33vr169XZGSkOnbsqNmzZ8vJKScC9O/fXyNGjNDLL7+sJUuW2MZHRkZq/fr1CgkJ0cSJE23XFy9erFdffVUTJkzQ9OnTDc2PSgcAADeBXbt2ac6cObrtttvyvR8eHi5JCgsLswUOSerUqZO6du2qffv2affu3bnGOzo66umnn871nNDQUAUEBCgqKkqJiYmG5kjoAADAhOwi+ioKaWlpev7553XLLbfkCQlSTqtk+/bt8vb2VrNmzfLcDw4OliRt3rxZknTy5EkdOXJEAQEB8vHxyXd8VlaWtm7damietFcAADChqNZj9OjR46r3V61adc1nTJo0SSdOnFBERIRcXV3z3I+Pj5fFYlGDBg3kkM+hZv7+/pJyFqFKsi0srVWrVr6f5+fnl2t8YVHpAACgFFu1apUiIyP12GOP5VvFkKTk5GRJkre3d773vby8JEkXLlwo1Pgr16+MLywqHQAAmFBU53QUppJRkDNnzmjcuHFq2rSpRo0aVeA4q9UqSXJ2ds73vouLi6ScLbKSlJGRkev6tcYXFqEDAAATSsKJpOPGjVNaWpqmTJmSa3HoP11puVwJE/9ksVgkSR4eHpIkNze3XNevNb6wCB0AAJhQ1GdsGBUREaE1a9bopZdeUt26da86tnz58pIKboekpKRI+qvNcq32yfnz53ONLyxCBwAApdCyZcsk5SwinTRpUp770dHRatCggWrUqKGoqCi5ubnp2LFj+T7ryvV69epJki3EFDQ+Li4u1/jCInQAAGBCcb975Z577lHbtm3zXE9JSdGnn34qHx8fDR48WJ6ennJ0dFTr1q21ceNGRUdHq2HDhrm+Z9OmTZKkNm3aSJJ8fX1Vu3ZtRUdHKykpSRUrVswz3tHRUa1atTI0Z0IHAAAmFHfouPfee/O9fvz4cVvoGDNmjO16aGioNm7cqMmTJ2v27Nm2xaAbNmzQ2rVrFRgYqObNm+caP3nyZE2ZMkWTJk2ybbVdvHixDhw4oDvvvFO+vr6G5kzoAADgX6Bnz57q2bOnli9frn79+ql79+5KTEzUjz/+qHLlyumtt97KNX7YsGFasWKFvvnmGx06dEhBQUGKjY1VVFSUqlWrphdffNHwHDinAwAAE7IdiubLnt577z0999xzcnBw0KeffqqtW7fq9ttv15dffpmn5eLs7Kx58+bpscce07lz5xQeHq79+/dr4MCB+vLLL1W1alXDn++QnZ1dEnb9XFP7Gt2KewpAibT6497FPQWgxHG/+9kb/hkf+f2nSJ7zeNznRfKc0oBKBwAAsAvWdAAAYEJxLyQtjQgdAACYUCrWJpQwtFcAAIBdUOkAAMCE4j4GvTQidAAAYAJrOowjdAAAYAKhwzjWdAAAALug0gEAgAnsXjGO0AEAgAksJDWO9goAALALKh0AAJjAQlLjCB0AAJjAmg7jaK8AAAC7oNIBAIAJWdQ6DCN0AABgAms6jKO9AgAA7IJKBwAAJtBcMY7QAQCACbRXjCN0AABgAieSGseaDgAAYBdUOgAAMIEts8YROgAAMIHIYRztFQAAYBdUOgAAMIHdK8YROgAAMIE1HcbRXgEAAHZBpQMAABOocxhH6AAAwATWdBhHewUAANgFlQ4AAExgIalxhA4AAEwgchhH6AAAwATWdBjHmg4AAGAXVDoAADAhmwaLYYQOAABMoL1iHKGjFGkR1FwzIt/T289P1f8t+sHQ97bv3k6DHglRo8AGcvNwU/zRE/ohcrkWzYlUpjXzBs346ir4VNBDTw5TUNe2qlzVR2dOndXq79cp/MPPdDHtUp7xZT3LatjoIercM1jV/aopMytLRw4e1Q+Ll2vJp0uVnc2/dfybLN99WAs37tOBk2eVmZWtmpU81bN5XT3QNVCuzuZ+a/th1yG9vHCN7mpRTxPv61bEMy6842dTNGvFTu2MSVBS6iVVr+ipPq3qa3iXQDmXydsVP51yUZ+s3qWNv8cp8XyaXJzKqEH1ShrYvpHubFGvGH4CIH+EjlLCv66f3pg5To6OxpfhPPTkcI147kFZrZnatWW3rBlWBbZtptGvjFTDwAYa99gbN2DGV1fJt6LmfjdT1fyq6tD+w9q0eqsaNW+gYaOHqH23thp5z1hdTL1oG1+hUnnN+naa/Ov4Kel0knZs3iU3d1c1adFIz04MU5vOrfTyiPHKyuLfPf4Npv2wTfPW7JFTGUe1ql1Vrs5O2nUkQR+v2KmN0XGa+1hvuRkMHgnnUjXpm003aMaFdyghSQ999L1SLqWrmb+vGtf00S+xCZr+43ZtOxivmY/cKae/BY+jp8/pwY++V1LqJVUtX1bBDfx0/tJl7TmaqF9iE7TnaKJe7B9cjD/RzYsts8YROkqBVsEt9ObMcapYuaLh720R1FwjnntQZ08l6cmhz+vQ/sOSJN/qlTVj8Xvq0berVnwTpfXLi+432y3xa3QyLkH3Bg0pcMyzE8JUza+qwqd9rtmTP5EkOTk7afy0l3Xb3d306HMP6YPxM2zjx4wfJf86flqzbL3eDJuky5cuS5Kq+1fThwvfUZdeHdV/WF8tWbC0yH4OlEwHTyZp/to98vZw1Sej+qhe1Zx/Ls5fvKxHZ/+gX4+d0qKN+/Rgt+aFfmZ2drZejVirC5csN2raik+6oN6TItSqTjV9MqpPgeNejVinlEvpenVAJ4W0ayhJSr1sUdj85fr50Akt2rRPwzo3s41/PXK9klIvaVCHxnr27va2Skh0/Bk9OvsHRWzar+AGfurUyP+G/Wz/VkQO49i9UoJVqFRez058Uh8uekde5b108niC4Wc8EPYfSdKk596xBQ5JOnXitP43dYFOnTyt+k3sW36tWau6OvfqqIT4RP3v3fm269YMq95+fqpSU1LVb2hvuXu4SZLcPdzUvXdXpV+26O3n37UFDkk6ceykZk6cI0m6vV93u/4cKB5bDxxXdrZ0R/M6tsAhSd4ebnqga6AkaWfMSUPP/Gz9r9p++KRa1alapHM1atuheP0ef0aBt/jaAocklXNz0esDu8jBQVq44TdbK/HYmfPaFZuoyl4eerZvUK7WS8MaPnqkx62SpJ92HxZQElDpKMHuHztUIff309HDxzTp2XfVd8hd6h3aq9Df71XeUy07tNCxmDhtitqa5/6Kb6K04puofL+3TaeWGjxioJq0bCQ3d3edjDupqO/W6IuPv8z1h74ZQd3aydHRUZtXbVVmZu52SNqFNO3cvFtdenVUq+CW2rhysyr4VFD03j+UdiFNKecu5HleXEycJMmnSqXrmhdKBwdHB0nSqfNpee4lp+X82vT2cC308w6eTNKMn3aoS2N/dW9aWztjrh7ul+85rMWbf9cfJ87Impklfx9v3d0mQIM6NMl3vYURG37P+bXcrcktee75+XipftWKOnAySQdPJimgeiUlp15WoL+v6latIGenMnm+55bK3pJy1nyg6NFeMY7QUYLFHz2pKS+9r+8WLlOmNVN9h9xl6PvrN6knJ6cy2r8rWpIU2Lqpgm9vr/IVvRUXe1zLl0TpdMKZPN83bPQQPf7yo8qwZOj3PX/o7KkkNW3ZSI8884A69wzWE6FP68L5VNM/V50GtSRJMdFH8r1/5OBRdenVUXUb1dbGlZt14thJPXbP2AKf1/jWRpKk0yfz/iy4+XQIqCkHB2nd/mP6aPkOhbZvLHcXJ238I04fLd8pF6cyGhzcpFDPslgz9fLCNSrr6qzXBnTSxujjVx3/36836Kut0XJzLqMmfr7ydHfRrtgEvfvdVm38PU7TH+qZ7x/+hXU4IVmSVLdq/q3UOlUq5ISOhGQFVK+k5rWq6NMx/Qp83m/HTkuSfL3Lmp4TCsYKMuMIHSVY5Lwl1/X9NWvVkCQlnz2nce+/kKdK8uCTw/XGmAm51nO07HCrHnvxESWeOKVnhr+kw7/HSJKcXZz1/NtPqc+gO/X0W2P1xtiJpud1pSJx5tTZfO+fScy5XtHn2mtYXN1cbS2k1cvWmZ4TSo86VSpo/IDOmrx0s+ZE7dKcqF22e3WrVNAbg7qoqV/lQj1r+o/bdTAhSe8Ou02VPD2uOnbp9gP6amu0AqpV1PsP3KEaFT0l5ay3eP6zVdp84LhmR/2iJ3q1Mf2zXalIVC5gLpW9cq4nXbh25eJMykUt2vSbJOn2wNqm5wQUJULHTaycZ86/3fQO7SVnFye9+/KHWv39Wjm7OqvffX10/9ihevOj1/Rw78d0ODpWkvSfUYPl6Oio91+bYQsckpRhydC7L3+g9t3a6bZ+3fXRxDk6nXBGd4X21Kvvv5jns6v5VdWW+DW5rt3TbrASjifK3cNdkpReQJsm/XK6JMmjrPtVfz5HR0eNn/ayqvtXU+yBI1r6xfeF/F8GpV2L2lXUIaCmNv0RpyZ+vnJ1KqNf404p5lSyPl//q94c1EUu16g4bDsUr883/KreLevptkL8oRy+do8k6Y3QLrbAIeWst3hjUBfdNXGRIjbt16O3tZSLUxl9vGKnZq/8Jc9zdsac1K3Pzc11bfc7IyRJlywZkiQ3l/x/a3Z1zvmZLlqsV53rJUuGnvk0SqmXM9S2XnV1aZy3XYPrx+FgxhE6bmLOrs6SctZ2vPXU2/ph8XLbvbnvzlc5r3IKffheDR8zVONH/1eOjo66NShnId4vm3fleV76ZYt2/7xXPfp2VfO2zRT13RrFHzmhn75emWtcr5DbdTHtktb/tDHX9Ut/nr2RmZlzLsi1jtW40rvPz5WdLt16d9b55PN66ZHXlPHnb9i4uf167JRGzf1BlTw99OVTIbZ1C+fSLuulhav10+7DcnJ00H+HFHzORsqldL325Tr5epXVC/07XPMzz6RcVOypcyrn5qJGNX3y3K/s5aGA6pW0L+60ouPPKPCWKgqoVlF3/e2MjEuWDK3Zd1QVy7krqH6NfD/H8c9f8wX/ys+RdZV/eK7sdNlzNFE1KnpqUjGeN3Kzo71iHKHjJnb5Uk7FIC31Yq7AccWST5cq9OF71Tq4hSTJu4KXrQqxYv//XfXZVar7SpL2bPtVe7b9muter5DbdT7pfIEtmCvhw9XNJd/7rm6uucb9Uzmvspo45w216dRKSWeS9dR9z+vo4birzhc3j3e+26LUyxn64IFOtsAhSeXLumnCkG66e/KX+mHXYT3eq7WqV/DM9xkTl2xS4vk0ffzIXfJyv/ai05PnctYwpV625KlS/FPCuTQF3iL1aFZbPZr9VUGJT7qgNfuOqrZv+QIPHvP4818ULmfkf2Bf+p/XPVyc872feC5VY+Yt14GTSfKr5KXZI++6ZtsI5lHpMM5Q6EhNNb94sFy5cqa/F+acO3tOkpQQl/9q/IQ/t+B6V8z5jdvxz5X36ZctWnON9RHHj8SbnteVxauVfPNfs3G1NR9Va1bRe5+9rdoBtRR/9ISe+s8Liou5+uI/3DwuZ1j167FTcnMuo5a1825vrVjOXU1qVtbPh07owImkfEPHvrjT+mn3YXl7uOq7HQf03Y4DtnvHk1IkSXuOJurlhWtUu0p5jejRQllZOX+4lPdwVYcGfledo4/n1duCV+PrVVbR8Wd19sJFSXl3Y11Z8+HjlTdIRMef0Zh5y3U65aIa1fDRjId7EjhQ4hgKHa1bt5aDw7UKf3k5ODho//79hr8P1+dwdM6ajEoFbCW9cthY8plzkqTzySnKsGTIybmMJj77zg1rV8T8cUSSVKt+rXzv1w7IuX7499hc1+s0qKVpEVNVybei9u/6Xc8+8IqSzyTfkDmiZEq9ZFF2ds56HscC2m9l/jy1NyMz/2rBxT9/XZ+/mK4fdh3Kd0x80gXFJ11QqzrVNKJHC9sf8i7OTjf0ePR6VSto/e/HFJOYrOCGecNNTGLOr/f6VSvkur790AmFha/QxfQMdWzopyn/6WGrmuDGob1inKHQMXLkSM2dO1dZWVmqUKGC3N3NJ3rceIf2xyjxxClVqe6rtp1ba9v6Hbnut+/eTpK0++e9knIO5/pt5361aN9c7bq00caVm/M8c0bke3JxcdYH42dq/+5oU/PaumabsrKyFHxbkD58fWauo8vLepZVqw636tLFS9q1dY/tetWaVWyBY9OqrXrl0ddtC07x71GxnLu8PVx1/mK6dsacVKs61XLdv3DJon3Hc7aJNqief9huU7e6beHmPy3dfkDjF6/L8+6VGhU9Va18OZ08l6o/TpzN8+xLFqvun7FU5dxc9NbgrrkWmhoR3NBP89bs0Zp9RzWsS2Cue3FnUnQwIUlVy5dV/Wp/VQn3xZ3W2PnLdcli1T1tG2hcSEdb8MKNdbW1NcifoV+ZTz31lCZOnCgHBwf5+/tr5cqVWr16daG+cGN5V/DSLXX9bGstpJyjnSPmREqSnn/7KdWsVd12L6BpfT3yzAPKyspS5Cd/bc2NmJsz/pkJYxXwt5NKHRwcNPKFh9WqQwtV86umg/sLPuGwfY1uVz0CPSE+URtXblGNW6pr9LiRtutOzk56YfLTKutZVt9+/r3SLvx1+NPr019RJd+K2rHxF73w0DgCx7+Uo6OD7aTO/369USeS/zosLu2yReMXr9P5i+nq2NBP/j5/HYwVe+rcdR+QNbRzU0nSqxFrFXcmxXY9w5qpCUs26sDJJF20ZBQYOGpU9NTud0Zc9Qj0lrWrqkH1SvolNkELN/5mu5562aLXI9cpO1sa3iXQVnFOz7DqxS9W65LFqj4t62n8wM4EDpRohheS9u/fXzExMZo7d67mz5+vRx555EbMCwYNePAePfLMA/pl826NHviU7friT5aoScvGuu3ubvpi9Xz9snm3nF2d1axVE7m4uuh/U8O1d8dfv7mtX75JX3wcoaGjBuuTZR8r+tcDOpNwRvUa11XNWjV06eIlvfzo+OtuvUwd96EaBgbovpGh6tC9nWL+iFWjWxuqWs2q+n3PH5r7zjzb2KBubdW8bc67JqzWTI1774V8n5ly7oLef236dc0LJd9jd7TSvrjT+vnQCfWbvFit6lSTUxlH7Ys7reS0y6rtW15vhHa2jZ/2wzb9386D6tuqvt4a3NX0594X3FS/Hj2l5XtiNGDqV2riV1neHq76Le60TqdcVMVy7po89PqO4ndwcNAboV30yKz/05SlW/R/Ow6qRkVP/RKb87bZTo38FNq+sW380u0HFHc2JwBdslj18sI1+T63VmVvPXp7y+uaG/KizmGcqd0rYWFhWrlypWbPnq3Q0FB5eXkV9bxQRLKysvTqqDe1Zc3P6j+0jwLbNlOmNVP7fvldi+ZEasOKvC96m/Hf2dr9816F3N9fjW9tqPqN6+nUyVP6buEyfTZzoY4fOXHd8zp14rQe7j1KjzzzgDr0CFLwbR2UEJ+g8Gmf67OZi3Tp4l9neLTv1s7210FdCz546dTJ04SOfwEXpzKa+cid+mrr7/p+50HtOZqY82r7ip4a2L6RhncJVLkCdkZdD0dHB709tLs6NvTTN9v+0IGTZ2XNzFL1Cp7qdWtdDe8SaDu863o0rFFJX4ztr4+W79S2QycUeypZNSt56f4ugRrSsUmuN8xu+uOvXVurfjtS4DNvrVWF0HEDcAy6cQ7Z2eaaUlu3btXSpUs1YMAAtWrVqqjnlUf7Guw1B/Kz+uPexT0FoMRxv/vZG/4Z991yT5E8Z+HRb4rkOaWB6XM6goKCFBQUVJRzAQCg1OCcDuM4HAwAABPYMmscy5wBAIBdUOkAAMAEFpIaR+gAAMAE1nQYR+gAAMCEkrKmIzU1VXPnztWKFSt0/PhxOTk5qX79+ho4cKAGDhyYa2x6eroWLFigb7/9VvHx8fL09FTXrl01duxY+fr65nl2SkqK5syZoxUrVighIUGVKlVSz549NXr0aHl6Gj95lzUdAACUUikpKRo8eLBmzZolFxcXDR48WH369NHx48c1btw4vfTSS7axVqtVTzzxhKZOnSpvb28NHz5cgYGBioyMVEhIiBIScr8cNDU1VQ888IDmzp0rf39/3X///fL399f8+fM1ZMgQUy+BpdIBAIAJJo+5KlIzZ87UwYMHFRoaqjfeeEOOfx6D/9xzz2nIkCFasmSJevXqpS5duigyMlLr169XSEiIJk6caHvG4sWL9eqrr2rChAmaPv2vAxZnzZqlffv2acyYMXriiSds199//33NmjVLM2bM0IsvvmhovlQ6AAAwIUvZRfJ1PZYtWyYHBwc999xztsAhSV5eXhoxIufFhlFRUZKk8PBwOTo66umnn871jNDQUAUEBCgqKkqJiYmSJIvFooULF8rb21uPPvporvGjR49WhQoV9NVXX8lisRiaL6EDAIBSKDMzU48++qjCwsLyfR2Ji0vO6wDS0tJ08uRJHTlyRAEBAfLx8ckzNjg4WFlZWdq6daskae/evUpLS1Pr1q1tz/n7c9u0aaMLFy5o7969huZMewUAABOKeyFpmTJlNHz48ALv//TTT5KkBg0aKDY2VpJUq1atfMf6+flJkmJiYiSp0ONjY2PVunXrQs+Z0AEAgAlFtWW2R48eV72/atUqw8+MiorS8uXL5eHhoXvuuUfbt2+XJHl7e+c7/sr1CxcuSJKSk5MlSeXLl7/q+JSUFEPzor0CAMBNZNOmTXrmmWckSePHj5evr68yMjIkKU+r5Ior19PT0yXJNt7Z2blQ4wuLSgcAACYU1YmkZioZBVm6dKleeeUVZWRk6Nlnn1X//v0lSW5ubpJU4MLPK9c9PDxyjb8SPq41vrAIHQAAmFAStsxekZ2drffee09z5sxRmTJl9MYbb2jw4MG2+/9sn/zT+fPnJcm2IPVa7ZN/ji8sQgcAAKWYxWLRM888oxUrVsjDw0MffPCBunTpkmtM3bp1JUnHjh3L9xlxcXGSpHr16pkaX1iEDgAATCju3StSzimjo0eP1vr161W1alXNnj1bDRs2zDPO19dXtWvXVnR0tJKSklSxYsVc9zdt2iRHR0e1atVKktSkSRN5enpqx44dysjIyLW2w2KxaNu2bSpbtqwaN25saL4sJAUAwITsIvrP9Zg+fbotcEREROQbOK4IDQ2V1WrVlClTcrWGFi9erAMHDqhnz56296+4uLioX79+Onv2rD7++ONcz5k5c6bOnTunIUOGyMnJWO2CSgcAACYU96vtT506pXnz5kmSGjVqpK+++irfcXXq1FHv3r01bNgwrVixQt98840OHTqkoKAgxcbGKioqStWqVctzpPnYsWO1ceNGzZw5U7/88ouaNWumvXv3auvWrWrUqJFGjRpleM6EDgAASqEtW7bYdpGsWbNGa9asyXdcjx491Lt3bzk7O2vevHmaPXu2li1bpvDwcFWuXFkDBw7UmDFjVKVKlVzf5+3trUWLFmnGjBlatWqVduzYoapVq+qhhx7SY489pnLlyhmes0N2SVp+exXta3Qr7ikAJdLqj3sX9xSAEsf97mdv+Gf0qHlHkTxn1fEVRfKc0oBKBwAAJhR3e6U0YiEpAACwCyodAACYUFTvXvk3IXQAAGBCVulYElmi0F4BAAB2QaUDAAATqHMYR+gAAMAEdq8YR+gAAMAEQodxrOkAAAB2QaUDAAATSsmB3iUKoQMAABNorxhHewUAANgFlQ4AAEzgRFLjCB0AAJjAmg7jaK8AAAC7oNIBAIAJLCQ1jtABAIAJtFeMo70CAADsgkoHAAAm0F4xjtABAIAJbJk1jtABAIAJWazpMIw1HQAAwC6odAAAYALtFeMIHQAAmEB7xTjaKwAAwC6odAAAYALtFeMIHQAAmEB7xTjaKwAAwC6odAAAYALtFeMIHQAAmEB7xTjaKwAAwC6odAAAYALtFeMIHQAAmJCdnVXcUyh1CB0AAJjAq+2NY00HAACwCyodAACYkM3uFcMIHQAAmEB7xTjaKwAAwC6odAAAYALtFeMIHQAAmMCJpMbRXgEAAHZBpQMAABM4kdQ4QgcAACawpsM42isAAMAuqHQAAGAC53QYR+gAAMAE2ivGEToAADCBLbPGsaYDAADYBZUOAABMoL1iHKEDAAATWEhqHO0VAABgF1Q6AAAwgfaKcYQOAABMYPeKcbRXAACAXVDpAADABF74ZhyhAwAAE2ivGEd7BQAA2AWVDgAATGD3inGEDgAATGBNh3GEDgAATKDSYRxrOgAAgF1Q6QAAwAQqHcYROgAAMIHIYRztFQAAYBcO2dSHAACAHVDpAAAAdkHoAAAAdkHoAAAAdkHoAAAAdkHoAAAAdkHoAAAAdkHoAAAAdkHoAAAAdkHoAAAAdkHoAAAAdkHoAAAAdkHoAAAAdkHoAAAAdkHoQKH9+OOPGjRokFq1aqW2bdtq5MiR2rt3b3FPCygx3n//fTVo0EApKSnFPRWgRCJ0oFA+/vhjPfnkkzpz5oxCQ0N1++236+eff9aQIUO0YcOG4p4eUOy+/fZbzZkzp7inAZRoDtnZ2dnFPQmUbIcOHVLfvn1Vr149ffnll/Lw8JAk/f777xoyZIi8vLy0YsUKubm5FfNMAfuzWq2aNm2a5syZoyu/nW7fvl1eXl7FPDOg5KHSgWtasGCBsrKy9Pjjj9sChyQ1atRIAwYMUGJiolatWlWMMwSKx5YtW9S3b1/Nnj1bzZo1U4UKFYp7SkCJRujANW3ZskWSFBwcnOdehw4dJEmbN2+265yAkmDp0qU6deqUnnnmGS1cuDBXKAeQl1NxTwAlW0ZGho4fP66KFSvmWy729/eXJMXExNh7akCxGzBggF588UWVL1++uKcClAqEDlzVuXPnlJ2dLW9v73zvXwkiFy5csOe0gBKhdevWxT0FoFShvYKrslqtkiRnZ+d877u4uEiS0tPT7TYnAEDpROjAVbm6ukrKabPkx2KxSBK9bADANRE6cFWenp4qU6ZMge2TK4cgsT0QAHAthA5clbOzs/z8/HT27FmlpaXluX/s2DFJUr169ew9NQBAKUPowDW1a9dO2dnZtq2zf7dp0yZJUps2bew9LQBAKUPowDUNHDhQDg4O+vDDD3O1WaKjo/X111+ratWquu2224pxhgCA0oAts7imZs2a6cEHH9S8efPUt29f9erVS6mpqfr+++9ltVo1ceJE2y4WAAAKQuhAobzwwguqU6eOFi5cqIULF6ps2bJq27atnnjiCQUGBhb39AAApQAvfAMAAHbBmg4AAGAXhA4AAGAXhA4AAGAXhA4AAGAXhA4AAGAXhA4AAGAXhA4AAGAXhA4AAGAXhA4AAGAXhA4AAGAXhA4AAGAXhA4AAGAX/w8VPTSFzAQhoQAAAABJRU5ErkJggg==", | |
"text/plain": [ | |
"<Figure size 640x480 with 2 Axes>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"confusion_01 = disconnected_cosine[\"embedding_prediction\"].sum()\n", | |
"confusion_00 = sample_size - confusion_01\n", | |
"confusion_11 = connected_cosine[\"embedding_prediction\"].sum()\n", | |
"confusion_10 = sample_size - confusion_11\n", | |
"array = np.array([[confusion_00, confusion_01],\n", | |
" [confusion_10, confusion_11]\n", | |
" ])\n", | |
"\n", | |
"df_cm = pd.DataFrame(array, range(2), range(2))\n", | |
"# plt.figure(figsize=(10,7))\n", | |
"sn.set(font_scale=1.4) # for label size\n", | |
"sn.heatmap(df_cm, annot=True, annot_kws={\"size\": 16}) # font size\n", | |
"\n", | |
"plt.show()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "9cf5aac0", | |
"metadata": {}, | |
"source": [ | |
"This gives **an accuracy of 0.92** (=(1000+840)/2000)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "2ac24094", | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3 (ipykernel)", | |
"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.10.11" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 5 | |
} | |
{ | |
"cell_type": "markdown"{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"id": "dbeead4f", | |
"metadata": {}, | |
"source": [ | |
"# Cora\n", | |
"\n", | |
"A collection of Cora explorations. The focus is on machine learning and not visualization here. Jupyter notebooks are not adequate for visualization, see however the [yFiles Jupyter plugin](https://www.yworks.com/products/yfiles-graphs-for-jupyter).\n", | |
"\n", | |
"*Author*: Francois Vanderseypen, Orbifold Consulting (https://orbifold.net).<br>\n", | |
"*Article*: https://graphsandnetworks.com/the-cora-dataset<br>\n", | |
"*Last update*: July 2023.<br>" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "f59e42e0", | |
"metadata": {}, | |
"source": [ | |
"## Download data\n", | |
"\n", | |
"This part is common to all packages, it downloads and unpacks the necessary data:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 58, | |
"id": "a06b6d68", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import os\n", | |
"import pandas as pd\n", | |
"data_dir = os.path.expanduser(\"~/cora\")\n", | |
"if not os.path.exists(data_dir):\n", | |
" os.makedirs(data_dir)\n", | |
"import requests\n", | |
"\n", | |
" \n", | |
"cora_tgz = os.path.join(data_dir, \"cora.tgz\")\n", | |
"response = requests.get(\"https://temprl.com/cora.tgz\", stream = True)\n", | |
"with open(cora_tgz,'wb') as output:\n", | |
" output.write(response.content)\n", | |
"\n", | |
"import tarfile\n", | |
"with tarfile.open(cora_tgz) as z:\n", | |
" for member in z:\n", | |
" if member.isdir():\n", | |
" continue\n", | |
" fname = member.name.rsplit('/',1)[1]\n", | |
" z.makefile(member,data_dir + '/' + fname)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "aa3525da", | |
"metadata": {}, | |
"source": [ | |
"## NetworkX" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "9bd8820a", | |
"metadata": {}, | |
"source": [ | |
"NetworkX is the most common graph package in Python. It does not perform any machine learning but it has a very complete graph analysis API and performs well on small and medium datasets." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 59, | |
"id": "60559b49", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import networkx as nx\n", | |
"\n", | |
"edge_data = pd.read_csv(os.path.join(data_dir, \"cora.cites\"), sep='\\t', header=None, names=[\"target\", \"source\"])\n", | |
"edge_data[\"label\"] = \"cites\"" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "70c0a3a1", | |
"metadata": {}, | |
"source": [ | |
"The edge list is just a source-target couple and there is no payload:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 60, | |
"id": "ba16ed6c", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<div>\n", | |
"<style scoped>\n", | |
" .dataframe tbody tr th:only-of-type {\n", | |
" vertical-align: middle;\n", | |
" }\n", | |
"\n", | |
" .dataframe tbody tr th {\n", | |
" vertical-align: top;\n", | |
" }\n", | |
"\n", | |
" .dataframe thead th {\n", | |
" text-align: right;\n", | |
" }\n", | |
"</style>\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th>target</th>\n", | |
" <th>source</th>\n", | |
" <th>label</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>741</th>\n", | |
" <td>3191</td>\n", | |
" <td>1127530</td>\n", | |
" <td>cites</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>4347</th>\n", | |
" <td>162080</td>\n", | |
" <td>1109830</td>\n", | |
" <td>cites</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>3549</th>\n", | |
" <td>69198</td>\n", | |
" <td>231198</td>\n", | |
" <td>cites</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>209</th>\n", | |
" <td>114</td>\n", | |
" <td>91975</td>\n", | |
" <td>cites</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>4766</th>\n", | |
" <td>289085</td>\n", | |
" <td>689152</td>\n", | |
" <td>cites</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" target source label\n", | |
"741 3191 1127530 cites\n", | |
"4347 162080 1109830 cites\n", | |
"3549 69198 231198 cites\n", | |
"209 114 91975 cites\n", | |
"4766 289085 689152 cites" | |
] | |
}, | |
"execution_count": 60, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"edge_data.sample(frac=1).head(5)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 61, | |
"id": "658349e2", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"Gnx = nx.from_pandas_edgelist(edge_data, edge_attr=\"label\")\n", | |
"nx.set_node_attributes(Gnx, \"paper\", \"label\")" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 62, | |
"id": "f3e560f3", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"{'label': 'paper'}" | |
] | |
}, | |
"execution_count": 62, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
" Gnx.nodes[1103985]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 63, | |
"id": "a9cafdda", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"feature_names = [\"w_{}\".format(ii) for ii in range(1433)]\n", | |
"column_names = feature_names + [\"subject\"]\n", | |
"node_data = pd.read_csv(os.path.join(data_dir, \"cora.content\"), sep='\\t', header=None, names=column_names)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "42c07961", | |
"metadata": {}, | |
"source": [ | |
"The payload on the node consists of the weights with the subject label:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 64, | |
"id": "c27ee8a9", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<div>\n", | |
"<style scoped>\n", | |
" .dataframe tbody tr th:only-of-type {\n", | |
" vertical-align: middle;\n", | |
" }\n", | |
"\n", | |
" .dataframe tbody tr th {\n", | |
" vertical-align: top;\n", | |
" }\n", | |
"\n", | |
" .dataframe thead th {\n", | |
" text-align: right;\n", | |
" }\n", | |
"</style>\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th>w_0</th>\n", | |
" <th>w_1</th>\n", | |
" <th>w_2</th>\n", | |
" <th>w_3</th>\n", | |
" <th>w_4</th>\n", | |
" <th>w_5</th>\n", | |
" <th>w_6</th>\n", | |
" <th>w_7</th>\n", | |
" <th>w_8</th>\n", | |
" <th>w_9</th>\n", | |
" <th>...</th>\n", | |
" <th>w_1424</th>\n", | |
" <th>w_1425</th>\n", | |
" <th>w_1426</th>\n", | |
" <th>w_1427</th>\n", | |
" <th>w_1428</th>\n", | |
" <th>w_1429</th>\n", | |
" <th>w_1430</th>\n", | |
" <th>w_1431</th>\n", | |
" <th>w_1432</th>\n", | |
" <th>subject</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>31336</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>1</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>Neural_Networks</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1061127</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>0</td>\n", | |
" <td>1</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>Rule_Learning</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1106406</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>Reinforcement_Learning</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>13195</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>Reinforcement_Learning</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>37879</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>Probabilistic_Methods</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"<p>5 rows × 1434 columns</p>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" w_0 w_1 w_2 w_3 w_4 w_5 w_6 w_7 w_8 w_9 ... w_1424 \\\n", | |
"31336 0 0 0 0 0 0 0 0 0 0 ... 0 \n", | |
"1061127 0 0 0 0 0 0 0 0 0 0 ... 0 \n", | |
"1106406 0 0 0 0 0 0 0 0 0 0 ... 0 \n", | |
"13195 0 0 0 0 0 0 0 0 0 0 ... 0 \n", | |
"37879 0 0 0 0 0 0 0 0 0 0 ... 0 \n", | |
"\n", | |
" w_1425 w_1426 w_1427 w_1428 w_1429 w_1430 w_1431 w_1432 \\\n", | |
"31336 0 1 0 0 0 0 0 0 \n", | |
"1061127 1 0 0 0 0 0 0 0 \n", | |
"1106406 0 0 0 0 0 0 0 0 \n", | |
"13195 0 0 0 0 0 0 0 0 \n", | |
"37879 0 0 0 0 0 0 0 0 \n", | |
"\n", | |
" subject \n", | |
"31336 Neural_Networks \n", | |
"1061127 Rule_Learning \n", | |
"1106406 Reinforcement_Learning \n", | |
"13195 Reinforcement_Learning \n", | |
"37879 Probabilistic_Methods \n", | |
"\n", | |
"[5 rows x 1434 columns]" | |
] | |
}, | |
"execution_count": 64, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"node_data.head(5)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "61af1435", | |
"metadata": {}, | |
"source": [ | |
"There are seven subjects:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 65, | |
"id": "5f405208", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"{'Case_Based',\n", | |
" 'Genetic_Algorithms',\n", | |
" 'Neural_Networks',\n", | |
" 'Probabilistic_Methods',\n", | |
" 'Reinforcement_Learning',\n", | |
" 'Rule_Learning',\n", | |
" 'Theory'}" | |
] | |
}, | |
"execution_count": 65, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"set(node_data[\"subject\"])" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "098bc658", | |
"metadata": {}, | |
"source": [ | |
"If you don't like the weights in multiple columns you can merge them:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 66, | |
"id": "5ff5a8b3", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"weight_column_names = node_data.columns[0:-1]\n", | |
"node_data['content'] = node_data[weight_column_names].apply(\n", | |
" lambda x: ','.join(x.dropna().astype(str)),\n", | |
" axis=1\n", | |
")\n", | |
"node_data.drop(weight_column_names, axis=1, inplace=True)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 84, | |
"id": "870e3fae", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<div>\n", | |
"<style scoped>\n", | |
" .dataframe tbody tr th:only-of-type {\n", | |
" vertical-align: middle;\n", | |
" }\n", | |
"\n", | |
" .dataframe tbody tr th {\n", | |
" vertical-align: top;\n", | |
" }\n", | |
"\n", | |
" .dataframe thead th {\n", | |
" text-align: right;\n", | |
" }\n", | |
"</style>\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th>subject</th>\n", | |
" <th>content</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>31336</th>\n", | |
" <td>Neural_Networks</td>\n", | |
" <td>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1061127</th>\n", | |
" <td>Rule_Learning</td>\n", | |
" <td>0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,...</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1106406</th>\n", | |
" <td>Reinforcement_Learning</td>\n", | |
" <td>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>13195</th>\n", | |
" <td>Reinforcement_Learning</td>\n", | |
" <td>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>37879</th>\n", | |
" <td>Probabilistic_Methods</td>\n", | |
" <td>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" subject \\\n", | |
"31336 Neural_Networks \n", | |
"1061127 Rule_Learning \n", | |
"1106406 Reinforcement_Learning \n", | |
"13195 Reinforcement_Learning \n", | |
"37879 Probabilistic_Methods \n", | |
"\n", | |
" content \n", | |
"31336 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,... \n", | |
"1061127 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,... \n", | |
"1106406 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,... \n", | |
"13195 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,... \n", | |
"37879 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,... " | |
] | |
}, | |
"execution_count": 84, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"node_data.head()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "a1e65089", | |
"metadata": {}, | |
"source": [ | |
"Note that the content is not an embedding but is the encoded article content." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 87, | |
"id": "3a6fa0f7", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"node_data['content'] = node_data['content'].apply(lambda x: np.array([int(i) for i in x.split(',')]))\n", | |
"# node_data.astype({'subject': 'str','content':'str'})" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "30af6bfb", | |
"metadata": {}, | |
"source": [ | |
"### Poor man's path to link prediction: Jaccard" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "ae086f04", | |
"metadata": {}, | |
"source": [ | |
"Long before graph machine learning came along, people were predicting edges using very simple algorithms. The Jaccard index (algorithm) basically looks at how the immediate neighborhood of two nodes overlap and the more they overlap the more they are likely to be connected. The idea stems from social network analysis where the more friends you share with somebody, the more likely you know each other." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "fecc7d71", | |
"metadata": {}, | |
"source": [ | |
"The following is a manual calculation for some:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "6c6e78ac", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"for u,v in list(Gnx.edges)[12:20]:\n", | |
" cnbors = list(nx.common_neighbors(Gnx, u, v))\n", | |
" union_size = len(set(Gnx[u]) | set(Gnx[v])) \n", | |
" print(u,v, len(cnbors)/union_size)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "19be9453", | |
"metadata": {}, | |
"source": [ | |
"Using NetworkX you can do the whole graph in one go:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "60c3f13d", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"jaccard_predictions = list(nx.jaccard_coefficient(Gnx))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "e1a7c6e6", | |
"metadata": {}, | |
"source": [ | |
"Filtering out the most likely candidates:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "0453540a", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"jaccard_predictions_top = [(t[0],t[1]) for t in jaccard_predictions if t[2]>0.8]" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "ce922f59", | |
"metadata": {}, | |
"source": [ | |
"Note that none of these are existing edges in the graph:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "de9a9463", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"[t for t in jaccard_predictions_top if Gnx.has_edge(*t)]" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "e30e0277", | |
"metadata": {}, | |
"source": [ | |
"There are plenty of nodes which have a fully common neighborhood leading to a probability equal to one. The only case with a partially overlapping neighborhood is the following:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "e2337f85", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
" [t for t in jaccard_predictions if t[2]>0.8 and t[2]!=1]" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "9b6c660d", | |
"metadata": {}, | |
"source": [ | |
"You can see that they differ in a single node:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "fd797519", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"print(\"Common: \",sorted(nx.common_neighbors(Gnx, 14428, 14430)))\n", | |
"print(\"14428:\", list(nx.neighbors(Gnx,14428)))\n", | |
"print(\"14430:\", list(nx.neighbors(Gnx,14430)))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "b912f361", | |
"metadata": {}, | |
"source": [ | |
"The main problem with Jaccard is the fact that it does not take the payload into account, only the immediate topology is looked at. Even the topology, it's only the first hop and maybe node neighborhoods on a higher level have a lot in common.\n", | |
"This makes Jaccard indicative rather than reliable." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "d121db6f", | |
"metadata": {}, | |
"source": [ | |
"### Cosine similarity of the payload\n", | |
"\n", | |
"We can look at the payload only and see whether the existing links are correlated with the payload.\n", | |
"The content can be seen a vectors and if we take the cosine similarity we get:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 108, | |
"id": "ffff5321", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"from random import sample\n", | |
"import numpy as np\n", | |
"sample_size = 1000\n", | |
"connected_sample=sample(list(Gnx.edges), sample_size)\n", | |
"disconnected_sample=sample(list(nx.complement(Gnx).edges), sample_size)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 100, | |
"id": "5606b585", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"assert len([e for e in disconnected_sample if Gnx.has_edge(*e)])==0" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "b1563272", | |
"metadata": {}, | |
"source": [ | |
"The cosine similarity is simply the dot product of the normalized vectors:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 101, | |
"id": "d21e9952", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"def cosine(u,v):\n", | |
" uc = node_data.loc[u][\"content\"]\n", | |
" vc = node_data.loc[v][\"content\"]\n", | |
" return np.dot(uc, vc)/(np.linalg.norm(uc)*np.linalg.norm(vc))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "24bfdee6", | |
"metadata": {}, | |
"source": [ | |
"So, for the connected subset we get:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 109, | |
"id": "2fa25891", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"connected_cosine = pd.DataFrame({\"source\":[e[0] for e in connected_sample],\"target\":[e[1] for e in connected_sample]})\n", | |
"connected_cosine[\"cosine\"]= connected_cosine.apply(lambda row: cosine(row.source,row.target), axis=1)\n", | |
"# connected_cosine" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 110, | |
"id": "b8564d60", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"<Axes: >" | |
] | |
}, | |
"execution_count": 110, | |
"metadata": {}, | |
"output_type": "execute_result" | |
}, | |
{ | |
"data": { | |
"image/png": "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9eqrr1pLly61vvSlL1nHHHOMdfjw4ew1F110kTV8+HDro48+st5//33r+OOPt6688sooHimW3H///Va3bt2s119/3dqwYYP1z3/+0+rQoYP1u9/9LnsN1bM/pk2bZv3iF7+wXn75ZQuA9corr9jOm6jXAwcOWBUVFdbVV19tLV++3Hruueesdu3aWX/6058Clb1ghZFRo0ZZN998c/bvVCpl9enTx5oyZUqEpWq97Ny50wJgzZ4927Isy9q/f79VUlJi/fOf/8xes3LlSguANXfuXMuymj+cZDJpVVZWZq959NFHrU6dOln19fX5fYCYU1NTY51wwgnWjBkzrPPOOy8rjFA9m+O2226zzj77bOn5dDpt9erVy/rNb36TPbZ//36rrKzMeu655yzLsqwVK1ZYAKyPP/44e82bb75pJRIJa9u2beEVvhVx6aWXWt/97ndtx7761a9aV199tWVZVM+m4IURU/X6yCOPWEceeaSt77jtttusgQMHBipvQZppGhoasHDhQowdOzZ7LJlMYuzYsZg7d26EJWu9HDhwAADQtWtXAMDChQvR2Nhoq+NBgwahf//+2TqeO3cuhg0bhoqKiuw148aNQ3V1NT799NM8lj7+3Hzzzbj00ktt9QlQPZvk3//+N0aOHIlvfOMb6NmzJ0499VQ8/vjj2fMbNmxAZWWlra47d+6M0aNH2+q6S5cuGDlyZPaasWPHIplMYt68efl7mBhz5plnYubMmVizZg0AYOnSpZgzZw4uvvhiAFTPYWGqXufOnYtzzz0XpaWl2WvGjRuH1atXY9++fb7L1yo2yjPN7t27kUqlbJ0zAFRUVGDVqlURlar1kk6nceutt+Kss87C0KFDAQCVlZUoLS1Fly5dbNdWVFSgsrIye43oHWTOEc08//zzWLRoET7++GPHOapnc6xfvx6PPvooJk2ahDvvvBMff/wxfvSjH6G0tBTjx4/P1pWoLtm67tmzp+18cXExunbtSnXdwu23347q6moMGjQIRUVFSKVSuP/++3H11VcDANVzSJiq18rKShxzzDGONDLnjjzySF/lK0hhhDDLzTffjOXLl2POnDlRF6XNsWXLFtxyyy2YMWMGysvLoy5OmyadTmPkyJF44IEHAACnnnoqli9fjsceewzjx4+PuHRthxdffBHPPPMMnn32WZx00klYsmQJbr31VvTp04fquYApSDNN9+7dUVRU5FhxUFVVhV69ekVUqtbJxIkT8frrr+Pdd9/FUUcdlT3eq1cvNDQ0YP/+/bbr2Tru1auX8B1kzhHNZpidO3fitNNOQ3FxMYqLizF79mz8/ve/R3FxMSoqKqieDdG7d28MGTLEdmzw4MHYvHkzgFxdufUbvXr1ws6dO23nm5qasHfvXqrrFn72s5/h9ttvx7e+9S0MGzYM11xzDX784x9jypQpAKiew8JUvYbVnxSkMFJaWooRI0Zg5syZ2WPpdBozZ87EmDFjIixZ68GyLEycOBGvvPIK3nnnHYfabsSIESgpKbHV8erVq7F58+ZsHY8ZMwbLli2zNf4ZM2agU6dOjkGhULnggguwbNkyLFmyJPtv5MiRuPrqq7O/qZ7NcNZZZzmWp69ZswZHH300AOCYY45Br169bHVdXV2NefPm2ep6//79WLhwYfaad955B+l0GqNHj87DU8SfQ4cOIZm0Dz1FRUVIp9MAqJ7DwlS9jhkzBu+99x4aGxuz18yYMQMDBw70baIBUNhLe8vKyqynnnrKWrFihXXDDTdYXbp0sa04IOTceOONVufOna1Zs2ZZO3bsyP47dOhQ9pof/OAHVv/+/a133nnHWrBggTVmzBhrzJgx2fOZJadf+MIXrCVLlljTp0+3evToQUtOPWBX01gW1bMp5s+fbxUXF1v333+/9dlnn1nPPPOM1b59e+vpp5/OXjN16lSrS5cu1muvvWZ98skn1pe//GXh0shTTz3VmjdvnjVnzhzrhBNOKPglpyzjx4+3+vbtm13a+/LLL1vdu3e3fv7zn2evoXr2R01NjbV48WJr8eLFFgDrwQcftBYvXmxt2rTJsiwz9bp//36roqLCuuaaa6zly5dbzz//vNW+fXta2huEP/zhD1b//v2t0tJSa9SoUdZHH30UdZFaDQCE/5588snsNYcPH7Zuuukm68gjj7Tat29vfeUrX7F27NhhS2fjxo3WxRdfbLVr187q3r279ZOf/MRqbGzM89O0LnhhhOrZHP/5z3+soUOHWmVlZdagQYOsP//5z7bz6XTauuuuu6yKigqrrKzMuuCCC6zVq1fbrtmzZ4915ZVXWh06dLA6depkTZgwwaqpqcnnY8Sa6upq65ZbbrH69+9vlZeXW8cee6z1i1/8wrZUlOrZH++++66wXx4/frxlWebqdenSpdbZZ59tlZWVWX379rWmTp0auOwJy2LC3hEEQRAEQeSZgvQZIQiCIAgiPpAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpPx/sFquoEdWNM8AAAAASUVORK5CYII=", | |
"text/plain": [ | |
"<Figure size 640x480 with 1 Axes>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"connected_cosine.cosine.plot()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "f4c1c7d1", | |
"metadata": {}, | |
"source": [ | |
"With an average cosine:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 111, | |
"id": "b9d1ff3e", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"0.16600344225511338" | |
] | |
}, | |
"execution_count": 111, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"np.average(connected_cosine.cosine)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 112, | |
"id": "a9da3ce4", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"disconnected_cosine = pd.DataFrame({\"source\":[e[0] for e in disconnected_sample],\"target\":[e[1] for e in disconnected_sample]})\n", | |
"disconnected_cosine[\"cosine\"]= disconnected_cosine.apply(lambda row: cosine(row.source,row.target), axis=1)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "f55ea8d3", | |
"metadata": {}, | |
"source": [ | |
"Visual inspection reveals that the disconnected nodes have on average a lower consine:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 113, | |
"id": "32edfcd0", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"<Axes: >" | |
] | |
}, | |
"execution_count": 113, | |
"metadata": {}, | |
"output_type": "execute_result" | |
}, | |
{ | |
"data": { | |
"image/png": "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/nnWv39/9vjjjzsqe84KI1dccQW75ZZbUn9Ho1E2ZswYtnDhQh9Llb3U1tYyAGzVqlWMMcaamppYv3792IsvvphKs3v3bgaAVVRUMMbiH044HGbV1dWpNI8++igbPHgw6+rqyuwDBJzW1lZ23nnnseXLl7NPfvKTKWGE6tk9fvazn7Grr75aeD4Wi7HRo0ez+++/P3WsqamJFRYWsueff54xxtiuXbsYALZ+/fpUmn//+98sFAqxY8eOeVf4LOLaa69l3/3ud3XHvvrVr7IbbriBMUb17BZGYcStev3Tn/7Ehg0bpus7fvazn7Hzzz/fUXlzcpkmEolg48aNKC0tTR0Lh8MoLS1FRUWFjyXLXpqbmwEAw4cPBwBs3LgR3d3dujqeOHEixo8fn6rjiooKXHzxxSgpKUmlmTlzJlpaWrBz584Mlj743HLLLbj22mt19QlQPbvJv/71L0ybNg3f+MY3MGrUKFx66aV48sknU+cPHTqE6upqXV0PGTIE06dP19X10KFDMW3atFSa0tJShMNhrF27NnMPE2CuvPJKlJeXY9++fQCArVu3YvXq1fj85z8PgOrZK9yq14qKCnziE59AQUFBKs3MmTOxd+9enDx50nb5smKjPLepr69HNBrVdc4AUFJSgj179vhUquwlFovhtttuw1VXXYWLLroIAFBdXY2CggIMHTpUl7akpATV1dWpNLx3kDxHxFmyZAk2bdqE9evXp52jenaPgwcP4tFHH0VZWRluv/12rF+/Hj/84Q9RUFCA2bNnp+qKV5fauh41apTufH5+PoYPH051neDnP/85WlpaMHHiROTl5SEajeK+++7DDTfcAABUzx7hVr1WV1fjrLPOSssjeW7YsGG2ypeTwgjhLrfccgt27NiB1atX+12UPkdVVRVuvfVWLF++HEVFRX4Xp08Ti8Uwbdo0/PrXvwYAXHrppdixYwcee+wxzJ492+fS9R1eeOEFPPvss3juuedw4YUXYsuWLbjtttswZswYquccJieXaUaOHIm8vLw0j4OamhqMHj3ap1JlJ/PmzcPrr7+OFStW4IwzzkgdHz16NCKRCJqamnTptXU8evRo7jtIniPiyzC1tbW47LLLkJ+fj/z8fKxatQq///3vkZ+fj5KSEqpnlzj99NMxadIk3bELLrgAlZWVAHrryqzfGD16NGpra3Xne3p60NjYSHWd4Cc/+Ql+/vOf45vf/CYuvvhifOc738GPfvQjLFy4EADVs1e4Va9e9Sc5KYwUFBRg6tSpKC8vTx2LxWIoLy/HjBkzfCxZ9sAYw7x58/Dyyy/j3XffTVPbTZ06Ff369dPV8d69e1FZWZmq4xkzZmD79u26xr98+XIMHjw4bVDIVT7zmc9g+/bt2LJlS+q/adOm4YYbbkj9pnp2h6uuuirNPX3fvn0488wzAQBnnXUWRo8eravrlpYWrF27VlfXTU1N2LhxYyrNu+++i1gshunTp2fgKYJPR0cHwmH90JOXl4dYLAaA6tkr3KrXGTNm4L333kN3d3cqzfLly3H++efbXqIBkNuuvYWFheyZZ55hu3btYv/93//Nhg4dqvM4IMT84Ac/YEOGDGErV65kJ06cSP3X0dGRSvP973+fjR8/nr377rtsw4YNbMaMGWzGjBmp80mX089+9rNsy5YtbNmyZey0004jl1MLtN40jFE9u8W6detYfn4+u++++9hHH33Enn32WVZcXMz+/ve/p9IsWrSIDR06lL366qts27Zt7Mtf/jLXNfLSSy9la9euZatXr2bnnXdezrucapk9ezYbO3ZsyrX3pZdeYiNHjmQ//elPU2monu3R2trKNm/ezDZv3swAsIceeoht3ryZHTlyhDHmTr02NTWxkpIS9p3vfIft2LGDLVmyhBUXF5NrrxP+8Ic/sPHjx7OCggJ2xRVXsDVr1vhdpKwBAPe/p59+OpWms7OT3XzzzWzYsGGsuLiYfeUrX2EnTpzQ5XP48GH2+c9/nvXv35+NHDmS/c///A/r7u7O8NNkF0ZhhOrZPV577TV20UUXscLCQjZx4kT2xBNP6M7HYjH2y1/+kpWUlLDCwkL2mc98hu3du1eXpqGhgV1//fVs4MCBbPDgwWzOnDmstbU1k48RaFpaWtitt97Kxo8fz4qKitjZZ5/N7rjjDp2rKNWzPVasWMHtl2fPns0Yc69et27dyq6++mpWWFjIxo4dyxYtWuS47CHGNGHvCIIgCIIgMkxO2owQBEEQBBEcSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJX/n9XfdMsKBNREQAAAABJRU5ErkJggg==", | |
"text/plain": [ | |
"<Figure size 640x480 with 1 Axes>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"disconnected_cosine.cosine.plot()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "e80b3341", | |
"metadata": {}, | |
"source": [ | |
"On average the cosine similarity is three times higher for connected nodes:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 115, | |
"id": "549153eb", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"2.8722134876583296" | |
] | |
}, | |
"execution_count": 115, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"np.average(connected_cosine.cosine)/np.average(disconnected_cosine.cosine)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "8fd35200", | |
"metadata": {}, | |
"source": [ | |
"This shows that connectivity is correlated with the payload of the nodes and can be used to predict links." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "62a78970", | |
"metadata": {}, | |
"source": [ | |
"Let's see how predictive this is. Looking at the plot you can see that cosine similarity above 0.1 seems to be a threshold:\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 145, | |
"id": "b53f0f27", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"cosine_threshold = 0.1\n", | |
"connected_cosine[\"cosine_prediction\"]= connected_cosine.apply(lambda row: row.cosine>cosine_threshold, axis=1)\n", | |
"disconnected_cosine[\"cosine_prediction\"]= disconnected_cosine.apply(lambda row: row.cosine>cosine_threshold, axis=1)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "47834bb8", | |
"metadata": {}, | |
"source": [ | |
"The confusion matrix for this prediction can be assembled as follows:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 146, | |
"id": "ad98c2db", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"image/png": "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", | |
"text/plain": [ | |
"<Figure size 640x480 with 2 Axes>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"import seaborn as sn\n", | |
"import pandas as pd\n", | |
"import matplotlib.pyplot as plt\n", | |
"confusion_01 = disconnected_cosine[\"cosine_prediction\"].sum()\n", | |
"confusion_00 = sample_size - confusion_01\n", | |
"confusion_11 = connected_cosine[\"cosine_prediction\"].sum()\n", | |
"confusion_10 = sample_size - confusion_11\n", | |
"array = np.array([[confusion_00, confusion_01],\n", | |
" [confusion_10, confusion_11]\n", | |
" ])*100/sample_size\n", | |
"\n", | |
"df_cm = pd.DataFrame(array, range(2), range(2))\n", | |
"# plt.figure(figsize=(10,7))\n", | |
"sn.set(font_scale=1.4) # for label size\n", | |
"sn.heatmap(df_cm, annot=True, annot_kws={\"size\": 16}) # font size\n", | |
"\n", | |
"plt.show()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "aab1575e", | |
"metadata": {}, | |
"source": [ | |
"This shows that prediction the edges purely on the basis of the node content is not too bad. " | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "53a11790", | |
"metadata": {}, | |
"source": [ | |
"### Combined Jaccard and cosine similarity\n", | |
"\n", | |
"It's natural to wonder whether the topological similarity improves the cosine prediction.\n", | |
"There are various ways the probabilities could be combined. Let's use the optimistic approach and take the maximum:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 164, | |
"id": "e8e2f8a6", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"combined_threshold = 0.1\n", | |
"\n", | |
"connected_cosine[\"jaccard\"]= connected_cosine.apply(lambda row: list(nx.jaccard_coefficient(Gnx, [(row.source, row.target)]))[0][2], axis=1)\n", | |
"connected_cosine[\"combined_prediction\"]= connected_cosine.apply(lambda row: max(row.cosine,row.jaccard)>combined_threshold, axis=1)\n", | |
"\n", | |
"disconnected_cosine[\"jaccard\"]= disconnected_cosine.apply(lambda row: list(nx.jaccard_coefficient(Gnx, [(row.source, row.target)]))[0][2], axis=1)\n", | |
"disconnected_cosine[\"combined_prediction\"]= disconnected_cosine.apply(lambda row: max(row.cosine,row.jaccard)>combined_threshold, axis=1)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 165, | |
"id": "4aae7db3", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"image/png": "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", | |
"text/plain": [ | |
"<Figure size 640x480 with 2 Axes>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"confusion_01 = disconnected_cosine[\"combined_prediction\"].sum()\n", | |
"confusion_00 = sample_size - confusion_01\n", | |
"confusion_11 = connected_cosine[\"combined_prediction\"].sum()\n", | |
"confusion_10 = sample_size - confusion_11\n", | |
"array = np.array([[confusion_00, confusion_01],\n", | |
" [confusion_10, confusion_11]\n", | |
" ])*100/sample_size\n", | |
"\n", | |
"df_cm = pd.DataFrame(array, range(2), range(2))\n", | |
"# plt.figure(figsize=(10,7))\n", | |
"sn.set(font_scale=1.4) # for label size\n", | |
"sn.heatmap(df_cm, annot=True, annot_kws={\"size\": 16}) # font size\n", | |
"\n", | |
"plt.show()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "dbdaa901", | |
"metadata": {}, | |
"source": [ | |
"This gives **an accuracy of 0.76** (= (78+74)/200). Altogether not a bad score for this simplistic approach." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "99e5c3d2", | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3 (ipykernel)", | |
"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.10.11" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 5 | |
} | |
, | |
"id": "dbeead4f", | |
"metadata": {}, | |
"source": [ | |
"# Cora\n", | |
"\n", | |
"A collection of Cora explorations. The focus is on machine learning and not visualization here. Jupyter notebooks are not adequate for visualization, see however the [yFiles Jupyter plugin](https://www.yworks.com/products/yfiles-graphs-for-jupyter).\n", | |
"\n", | |
"*Author*: Francois Vanderseypen, Orbifold Consulting (https://orbifold.net).<br>\n", | |
"*Article*: https://graphsandnetworks.com/the-cora-dataset<br>\n", | |
"*Last update*: July 2023.<br>" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "f59e42e0", | |
"metadata": {}, | |
"source": [ | |
"## Download data\n", | |
"\n", | |
"This part is common to all packages, it downloads and unpacks the necessary data:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 58, | |
"id": "a06b6d68", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import os\n", | |
"import pandas as pd\n", | |
"data_dir = os.path.expanduser(\"~/cora\")\n", | |
"if not os.path.exists(data_dir):\n", | |
" os.makedirs(data_dir)\n", | |
"import requests\n", | |
"\n", | |
" \n", | |
"cora_tgz = os.path.join(data_dir, \"cora.tgz\")\n", | |
"response = requests.get(\"https://temprl.com/cora.tgz\", stream = True)\n", | |
"with open(cora_tgz,'wb') as output:\n", | |
" output.write(response.content)\n", | |
"\n", | |
"import tarfile\n", | |
"with tarfile.open(cora_tgz) as z:\n", | |
" for member in z:\n", | |
" if member.isdir():\n", | |
" continue\n", | |
" fname = member.name.rsplit('/',1)[1]\n", | |
" z.makefile(member,data_dir + '/' + fname)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "aa3525da", | |
"metadata": {}, | |
"source": [ | |
"## NetworkX" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "9bd8820a", | |
"metadata": {}, | |
"source": [ | |
"NetworkX is the most common graph package in Python. It does not perform any machine learning but it has a very complete graph analysis API and performs well on small and medium datasets." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 59, | |
"id": "60559b49", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import networkx as nx\n", | |
"\n", | |
"edge_data = pd.read_csv(os.path.join(data_dir, \"cora.cites\"), sep='\\t', header=None, names=[\"target\", \"source\"])\n", | |
"edge_data[\"label\"] = \"cites\"" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "70c0a3a1", | |
"metadata": {}, | |
"source": [ | |
"The edge list is just a source-target couple and there is no payload:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 60, | |
"id": "ba16ed6c", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<div>\n", | |
"<style scoped>\n", | |
" .dataframe tbody tr th:only-of-type {\n", | |
" vertical-align: middle;\n", | |
" }\n", | |
"\n", | |
" .dataframe tbody tr th {\n", | |
" vertical-align: top;\n", | |
" }\n", | |
"\n", | |
" .dataframe thead th {\n", | |
" text-align: right;\n", | |
" }\n", | |
"</style>\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th>target</th>\n", | |
" <th>source</th>\n", | |
" <th>label</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>741</th>\n", | |
" <td>3191</td>\n", | |
" <td>1127530</td>\n", | |
" <td>cites</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>4347</th>\n", | |
" <td>162080</td>\n", | |
" <td>1109830</td>\n", | |
" <td>cites</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>3549</th>\n", | |
" <td>69198</td>\n", | |
" <td>231198</td>\n", | |
" <td>cites</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>209</th>\n", | |
" <td>114</td>\n", | |
" <td>91975</td>\n", | |
" <td>cites</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>4766</th>\n", | |
" <td>289085</td>\n", | |
" <td>689152</td>\n", | |
" <td>cites</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" target source label\n", | |
"741 3191 1127530 cites\n", | |
"4347 162080 1109830 cites\n", | |
"3549 69198 231198 cites\n", | |
"209 114 91975 cites\n", | |
"4766 289085 689152 cites" | |
] | |
}, | |
"execution_count": 60, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"edge_data.sample(frac=1).head(5)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 61, | |
"id": "658349e2", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"Gnx = nx.from_pandas_edgelist(edge_data, edge_attr=\"label\")\n", | |
"nx.set_node_attributes(Gnx, \"paper\", \"label\")" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 62, | |
"id": "f3e560f3", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"{'label': 'paper'}" | |
] | |
}, | |
"execution_count": 62, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
" Gnx.nodes[1103985]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 63, | |
"id": "a9cafdda", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"feature_names = [\"w_{}\".format(ii) for ii in range(1433)]\n", | |
"column_names = feature_names + [\"subject\"]\n", | |
"node_data = pd.read_csv(os.path.join(data_dir, \"cora.content\"), sep='\\t', header=None, names=column_names)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "42c07961", | |
"metadata": {}, | |
"source": [ | |
"The payload on the node consists of the weights with the subject label:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 64, | |
"id": "c27ee8a9", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<div>\n", | |
"<style scoped>\n", | |
" .dataframe tbody tr th:only-of-type {\n", | |
" vertical-align: middle;\n", | |
" }\n", | |
"\n", | |
" .dataframe tbody tr th {\n", | |
" vertical-align: top;\n", | |
" }\n", | |
"\n", | |
" .dataframe thead th {\n", | |
" text-align: right;\n", | |
" }\n", | |
"</style>\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th>w_0</th>\n", | |
" <th>w_1</th>\n", | |
" <th>w_2</th>\n", | |
" <th>w_3</th>\n", | |
" <th>w_4</th>\n", | |
" <th>w_5</th>\n", | |
" <th>w_6</th>\n", | |
" <th>w_7</th>\n", | |
" <th>w_8</th>\n", | |
" <th>w_9</th>\n", | |
" <th>...</th>\n", | |
" <th>w_1424</th>\n", | |
" <th>w_1425</th>\n", | |
" <th>w_1426</th>\n", | |
" <th>w_1427</th>\n", | |
" <th>w_1428</th>\n", | |
" <th>w_1429</th>\n", | |
" <th>w_1430</th>\n", | |
" <th>w_1431</th>\n", | |
" <th>w_1432</th>\n", | |
" <th>subject</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>31336</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>1</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>Neural_Networks</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1061127</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>0</td>\n", | |
" <td>1</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>Rule_Learning</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1106406</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>Reinforcement_Learning</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>13195</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>Reinforcement_Learning</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>37879</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>Probabilistic_Methods</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"<p>5 rows × 1434 columns</p>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" w_0 w_1 w_2 w_3 w_4 w_5 w_6 w_7 w_8 w_9 ... w_1424 \\\n", | |
"31336 0 0 0 0 0 0 0 0 0 0 ... 0 \n", | |
"1061127 0 0 0 0 0 0 0 0 0 0 ... 0 \n", | |
"1106406 0 0 0 0 0 0 0 0 0 0 ... 0 \n", | |
"13195 0 0 0 0 0 0 0 0 0 0 ... 0 \n", | |
"37879 0 0 0 0 0 0 0 0 0 0 ... 0 \n", | |
"\n", | |
" w_1425 w_1426 w_1427 w_1428 w_1429 w_1430 w_1431 w_1432 \\\n", | |
"31336 0 1 0 0 0 0 0 0 \n", | |
"1061127 1 0 0 0 0 0 0 0 \n", | |
"1106406 0 0 0 0 0 0 0 0 \n", | |
"13195 0 0 0 0 0 0 0 0 \n", | |
"37879 0 0 0 0 0 0 0 0 \n", | |
"\n", | |
" subject \n", | |
"31336 Neural_Networks \n", | |
"1061127 Rule_Learning \n", | |
"1106406 Reinforcement_Learning \n", | |
"13195 Reinforcement_Learning \n", | |
"37879 Probabilistic_Methods \n", | |
"\n", | |
"[5 rows x 1434 columns]" | |
] | |
}, | |
"execution_count": 64, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"node_data.head(5)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "61af1435", | |
"metadata": {}, | |
"source": [ | |
"There are seven subjects:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 65, | |
"id": "5f405208", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"{'Case_Based',\n", | |
" 'Genetic_Algorithms',\n", | |
" 'Neural_Networks',\n", | |
" 'Probabilistic_Methods',\n", | |
" 'Reinforcement_Learning',\n", | |
" 'Rule_Learning',\n", | |
" 'Theory'}" | |
] | |
}, | |
"execution_count": 65, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"set(node_data[\"subject\"])" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "098bc658", | |
"metadata": {}, | |
"source": [ | |
"If you don't like the weights in multiple columns you can merge them:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 66, | |
"id": "5ff5a8b3", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"weight_column_names = node_data.columns[0:-1]\n", | |
"node_data['content'] = node_data[weight_column_names].apply(\n", | |
" lambda x: ','.join(x.dropna().astype(str)),\n", | |
" axis=1\n", | |
")\n", | |
"node_data.drop(weight_column_names, axis=1, inplace=True)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 84, | |
"id": "870e3fae", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<div>\n", | |
"<style scoped>\n", | |
" .dataframe tbody tr th:only-of-type {\n", | |
" vertical-align: middle;\n", | |
" }\n", | |
"\n", | |
" .dataframe tbody tr th {\n", | |
" vertical-align: top;\n", | |
" }\n", | |
"\n", | |
" .dataframe thead th {\n", | |
" text-align: right;\n", | |
" }\n", | |
"</style>\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th>subject</th>\n", | |
" <th>content</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>31336</th>\n", | |
" <td>Neural_Networks</td>\n", | |
" <td>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1061127</th>\n", | |
" <td>Rule_Learning</td>\n", | |
" <td>0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,...</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1106406</th>\n", | |
" <td>Reinforcement_Learning</td>\n", | |
" <td>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>13195</th>\n", | |
" <td>Reinforcement_Learning</td>\n", | |
" <td>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>37879</th>\n", | |
" <td>Probabilistic_Methods</td>\n", | |
" <td>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" subject \\\n", | |
"31336 Neural_Networks \n", | |
"1061127 Rule_Learning \n", | |
"1106406 Reinforcement_Learning \n", | |
"13195 Reinforcement_Learning \n", | |
"37879 Probabilistic_Methods \n", | |
"\n", | |
" content \n", | |
"31336 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,... \n", | |
"1061127 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,... \n", | |
"1106406 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,... \n", | |
"13195 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,... \n", | |
"37879 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,... " | |
] | |
}, | |
"execution_count": 84, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"node_data.head()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "a1e65089", | |
"metadata": {}, | |
"source": [ | |
"Note that the content is not an embedding but is the encoded article content." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 87, | |
"id": "86e48586", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"node_data['content'] = node_data['content'].apply(lambda x: np.array([int(i) for i in x.split(',')]))\n", | |
"# node_data.astype({'subject': 'str','content':'str'})" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "30af6bfb", | |
"metadata": {}, | |
"source": [ | |
"### Poor man's path to link prediction: Jaccard" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "ae086f04", | |
"metadata": {}, | |
"source": [ | |
"Long before graph machine learning came along, people were predicting edges using very simple algorithms. The Jaccard index (algorithm) basically looks at how the immediate neighborhood of two nodes overlap and the more they overlap the more they are likely to be connected. The idea stems from social network analysis where the more friends you share with somebody, the more likely you know each other." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "fecc7d71", | |
"metadata": {}, | |
"source": [ | |
"The following is a manual calculation for some:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "6c6e78ac", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"for u,v in list(Gnx.edges)[12:20]:\n", | |
" cnbors = list(nx.common_neighbors(Gnx, u, v))\n", | |
" union_size = len(set(Gnx[u]) | set(Gnx[v])) \n", | |
" print(u,v, len(cnbors)/union_size)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "19be9453", | |
"metadata": {}, | |
"source": [ | |
"Using NetworkX you can do the whole graph in one go:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "60c3f13d", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"jaccard_predictions = list(nx.jaccard_coefficient(Gnx))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "e1a7c6e6", | |
"metadata": {}, | |
"source": [ | |
"Filtering out the most likely candidates:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "0453540a", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"jaccard_predictions_top = [(t[0],t[1]) for t in jaccard_predictions if t[2]>0.8]" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "ce922f59", | |
"metadata": {}, | |
"source": [ | |
"Note that none of these are existing edges in the graph:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "de9a9463", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"[t for t in jaccard_predictions_top if Gnx.has_edge(*t)]" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "2e7e5486", | |
"metadata": {}, | |
"source": [ | |
"There are plenty of nodes which have a fully common neighborhood leading to a probability equal to one. The only case with a partially overlapping neighborhood is the following:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "e2337f85", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
" [t for t in jaccard_predictions if t[2]>0.8 and t[2]!=1]" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "d3810102", | |
"metadata": {}, | |
"source": [ | |
"You can see that they differ in a single node:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "479f1254", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"print(\"Common: \",sorted(nx.common_neighbors(Gnx, 14428, 14430)))\n", | |
"print(\"14428:\", list(nx.neighbors(Gnx,14428)))\n", | |
"print(\"14430:\", list(nx.neighbors(Gnx,14430)))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "625686cd", | |
"metadata": {}, | |
"source": [ | |
"The main problem with Jaccard is the fact that it does not take the payload into account, only the immediate topology is looked at. Even the topology, it's only the first hop and maybe node neighborhoods on a higher level have a lot in common.\n", | |
"This makes Jaccard indicative rather than reliable." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "d6689c9a", | |
"metadata": {}, | |
"source": [ | |
"### Cosine similarity of the payload\n", | |
"\n", | |
"We can look at the payload only and see whether the existing links are correlated with the payload.\n", | |
"The content can be seen a vectors and if we take the cosine similarity we get:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 108, | |
"id": "d78ca209", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"from random import sample\n", | |
"import numpy as np\n", | |
"sample_size = 1000\n", | |
"connected_sample=sample(list(Gnx.edges), sample_size)\n", | |
"disconnected_sample=sample(list(nx.complement(Gnx).edges), sample_size)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 100, | |
"id": "b3c4df0e", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"assert len([e for e in disconnected_sample if Gnx.has_edge(*e)])==0" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "37385f91", | |
"metadata": {}, | |
"source": [ | |
"The cosine similarity is simply the dot product of the normalized vectors:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 101, | |
"id": "3cbc816b", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"def cosine(u,v):\n", | |
" uc = node_data.loc[u][\"content\"]\n", | |
" vc = node_data.loc[v][\"content\"]\n", | |
" return np.dot(uc, vc)/(np.linalg.norm(uc)*np.linalg.norm(vc))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "32f006e5", | |
"metadata": {}, | |
"source": [ | |
"So, for the connected subset we get:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 109, | |
"id": "2033b5e2", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"connected_cosine = pd.DataFrame({\"source\":[e[0] for e in connected_sample],\"target\":[e[1] for e in connected_sample]})\n", | |
"connected_cosine[\"cosine\"]= connected_cosine.apply(lambda row: cosine(row.source,row.target), axis=1)\n", | |
"# connected_cosine" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 110, | |
"id": "c5918c3c", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"<Axes: >" | |
] | |
}, | |
"execution_count": 110, | |
"metadata": {}, | |
"output_type": "execute_result" | |
}, | |
{ | |
"data": { | |
"image/png": "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9eqrr1pLly61vvSlL1nHHHOMdfjw4ew1F110kTV8+HDro48+st5//33r+OOPt6688sooHimW3H///Va3bt2s119/3dqwYYP1z3/+0+rQoYP1u9/9LnsN1bM/pk2bZv3iF7+wXn75ZQuA9corr9jOm6jXAwcOWBUVFdbVV19tLV++3Hruueesdu3aWX/6058Clb1ghZFRo0ZZN998c/bvVCpl9enTx5oyZUqEpWq97Ny50wJgzZ4927Isy9q/f79VUlJi/fOf/8xes3LlSguANXfuXMuymj+cZDJpVVZWZq959NFHrU6dOln19fX5fYCYU1NTY51wwgnWjBkzrPPOOy8rjFA9m+O2226zzj77bOn5dDpt9erVy/rNb36TPbZ//36rrKzMeu655yzLsqwVK1ZYAKyPP/44e82bb75pJRIJa9u2beEVvhVx6aWXWt/97ndtx7761a9aV199tWVZVM+m4IURU/X6yCOPWEceeaSt77jtttusgQMHBipvQZppGhoasHDhQowdOzZ7LJlMYuzYsZg7d26EJWu9HDhwAADQtWtXAMDChQvR2Nhoq+NBgwahf//+2TqeO3cuhg0bhoqKiuw148aNQ3V1NT799NM8lj7+3Hzzzbj00ktt9QlQPZvk3//+N0aOHIlvfOMb6NmzJ0499VQ8/vjj2fMbNmxAZWWlra47d+6M0aNH2+q6S5cuGDlyZPaasWPHIplMYt68efl7mBhz5plnYubMmVizZg0AYOnSpZgzZw4uvvhiAFTPYWGqXufOnYtzzz0XpaWl2WvGjRuH1atXY9++fb7L1yo2yjPN7t27kUqlbJ0zAFRUVGDVqlURlar1kk6nceutt+Kss87C0KFDAQCVlZUoLS1Fly5dbNdWVFSgsrIye43oHWTOEc08//zzWLRoET7++GPHOapnc6xfvx6PPvooJk2ahDvvvBMff/wxfvSjH6G0tBTjx4/P1pWoLtm67tmzp+18cXExunbtSnXdwu23347q6moMGjQIRUVFSKVSuP/++3H11VcDANVzSJiq18rKShxzzDGONDLnjjzySF/lK0hhhDDLzTffjOXLl2POnDlRF6XNsWXLFtxyyy2YMWMGysvLoy5OmyadTmPkyJF44IEHAACnnnoqli9fjsceewzjx4+PuHRthxdffBHPPPMMnn32WZx00klYsmQJbr31VvTp04fquYApSDNN9+7dUVRU5FhxUFVVhV69ekVUqtbJxIkT8frrr+Pdd9/FUUcdlT3eq1cvNDQ0YP/+/bbr2Tru1auX8B1kzhHNZpidO3fitNNOQ3FxMYqLizF79mz8/ve/R3FxMSoqKqieDdG7d28MGTLEdmzw4MHYvHkzgFxdufUbvXr1ws6dO23nm5qasHfvXqrrFn72s5/h9ttvx7e+9S0MGzYM11xzDX784x9jypQpAKiew8JUvYbVnxSkMFJaWooRI0Zg5syZ2WPpdBozZ87EmDFjIixZ68GyLEycOBGvvPIK3nnnHYfabsSIESgpKbHV8erVq7F58+ZsHY8ZMwbLli2zNf4ZM2agU6dOjkGhULnggguwbNkyLFmyJPtv5MiRuPrqq7O/qZ7NcNZZZzmWp69ZswZHH300AOCYY45Br169bHVdXV2NefPm2ep6//79WLhwYfaad955B+l0GqNHj87DU8SfQ4cOIZm0Dz1FRUVIp9MAqJ7DwlS9jhkzBu+99x4aGxuz18yYMQMDBw70baIBUNhLe8vKyqynnnrKWrFihXXDDTdYXbp0sa04IOTceOONVufOna1Zs2ZZO3bsyP47dOhQ9pof/OAHVv/+/a133nnHWrBggTVmzBhrzJgx2fOZJadf+MIXrCVLlljTp0+3evToQUtOPWBX01gW1bMp5s+fbxUXF1v333+/9dlnn1nPPPOM1b59e+vpp5/OXjN16lSrS5cu1muvvWZ98skn1pe//GXh0shTTz3VmjdvnjVnzhzrhBNOKPglpyzjx4+3+vbtm13a+/LLL1vdu3e3fv7zn2evoXr2R01NjbV48WJr8eLFFgDrwQcftBYvXmxt2rTJsiwz9bp//36roqLCuuaaa6zly5dbzz//vNW+fXta2huEP/zhD1b//v2t0tJSa9SoUdZHH30UdZFaDQCE/5588snsNYcPH7Zuuukm68gjj7Tat29vfeUrX7F27NhhS2fjxo3WxRdfbLVr187q3r279ZOf/MRqbGzM89O0LnhhhOrZHP/5z3+soUOHWmVlZdagQYOsP//5z7bz6XTauuuuu6yKigqrrKzMuuCCC6zVq1fbrtmzZ4915ZVXWh06dLA6depkTZgwwaqpqcnnY8Sa6upq65ZbbrH69+9vlZeXW8cee6z1i1/8wrZUlOrZH++++66wXx4/frxlWebqdenSpdbZZ59tlZWVWX379rWmTp0auOwJy2LC3hEEQRAEQeSZgvQZIQiCIAgiPpAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpJAwQhAEQRBEpPx/sFquoEdWNM8AAAAASUVORK5CYII=", | |
"text/plain": [ | |
"<Figure size 640x480 with 1 Axes>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"connected_cosine.cosine.plot()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "576cfe84", | |
"metadata": {}, | |
"source": [ | |
"With an average cosine:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 111, | |
"id": "aa5792b9", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"0.16600344225511338" | |
] | |
}, | |
"execution_count": 111, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"np.average(connected_cosine.cosine)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 112, | |
"id": "e502eb5b", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"disconnected_cosine = pd.DataFrame({\"source\":[e[0] for e in disconnected_sample],\"target\":[e[1] for e in disconnected_sample]})\n", | |
"disconnected_cosine[\"cosine\"]= disconnected_cosine.apply(lambda row: cosine(row.source,row.target), axis=1)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "f0168d1e", | |
"metadata": {}, | |
"source": [ | |
"Visual inspection reveals that the disconnected nodes have on average a lower consine:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 113, | |
"id": "ef51d9df", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"<Axes: >" | |
] | |
}, | |
"execution_count": 113, | |
"metadata": {}, | |
"output_type": "execute_result" | |
}, | |
{ | |
"data": { | |
"image/png": "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/nnWv39/9vjjjzsqe84KI1dccQW75ZZbUn9Ho1E2ZswYtnDhQh9Llb3U1tYyAGzVqlWMMcaamppYv3792IsvvphKs3v3bgaAVVRUMMbiH044HGbV1dWpNI8++igbPHgw6+rqyuwDBJzW1lZ23nnnseXLl7NPfvKTKWGE6tk9fvazn7Grr75aeD4Wi7HRo0ez+++/P3WsqamJFRYWsueff54xxtiuXbsYALZ+/fpUmn//+98sFAqxY8eOeVf4LOLaa69l3/3ud3XHvvrVr7IbbriBMUb17BZGYcStev3Tn/7Ehg0bpus7fvazn7Hzzz/fUXlzcpkmEolg48aNKC0tTR0Lh8MoLS1FRUWFjyXLXpqbmwEAw4cPBwBs3LgR3d3dujqeOHEixo8fn6rjiooKXHzxxSgpKUmlmTlzJlpaWrBz584Mlj743HLLLbj22mt19QlQPbvJv/71L0ybNg3f+MY3MGrUKFx66aV48sknU+cPHTqE6upqXV0PGTIE06dP19X10KFDMW3atFSa0tJShMNhrF27NnMPE2CuvPJKlJeXY9++fQCArVu3YvXq1fj85z8PgOrZK9yq14qKCnziE59AQUFBKs3MmTOxd+9enDx50nb5smKjPLepr69HNBrVdc4AUFJSgj179vhUquwlFovhtttuw1VXXYWLLroIAFBdXY2CggIMHTpUl7akpATV1dWpNLx3kDxHxFmyZAk2bdqE9evXp52jenaPgwcP4tFHH0VZWRluv/12rF+/Hj/84Q9RUFCA2bNnp+qKV5fauh41apTufH5+PoYPH051neDnP/85WlpaMHHiROTl5SEajeK+++7DDTfcAABUzx7hVr1WV1fjrLPOSssjeW7YsGG2ypeTwgjhLrfccgt27NiB1atX+12UPkdVVRVuvfVWLF++HEVFRX4Xp08Ti8Uwbdo0/PrXvwYAXHrppdixYwcee+wxzJ492+fS9R1eeOEFPPvss3juuedw4YUXYsuWLbjtttswZswYquccJieXaUaOHIm8vLw0j4OamhqMHj3ap1JlJ/PmzcPrr7+OFStW4IwzzkgdHz16NCKRCJqamnTptXU8evRo7jtIniPiyzC1tbW47LLLkJ+fj/z8fKxatQq///3vkZ+fj5KSEqpnlzj99NMxadIk3bELLrgAlZWVAHrryqzfGD16NGpra3Xne3p60NjYSHWd4Cc/+Ql+/vOf45vf/CYuvvhifOc738GPfvQjLFy4EADVs1e4Va9e9Sc5KYwUFBRg6tSpKC8vTx2LxWIoLy/HjBkzfCxZ9sAYw7x58/Dyyy/j3XffTVPbTZ06Ff369dPV8d69e1FZWZmq4xkzZmD79u26xr98+XIMHjw4bVDIVT7zmc9g+/bt2LJlS+q/adOm4YYbbkj9pnp2h6uuuirNPX3fvn0488wzAQBnnXUWRo8eravrlpYWrF27VlfXTU1N2LhxYyrNu+++i1gshunTp2fgKYJPR0cHwmH90JOXl4dYLAaA6tkr3KrXGTNm4L333kN3d3cqzfLly3H++efbXqIBkNuuvYWFheyZZ55hu3btYv/93//Nhg4dqvM4IMT84Ac/YEOGDGErV65kJ06cSP3X0dGRSvP973+fjR8/nr377rtsw4YNbMaMGWzGjBmp80mX089+9rNsy5YtbNmyZey0004jl1MLtN40jFE9u8W6detYfn4+u++++9hHH33Enn32WVZcXMz+/ve/p9IsWrSIDR06lL366qts27Zt7Mtf/jLXNfLSSy9la9euZatXr2bnnXdezrucapk9ezYbO3ZsyrX3pZdeYiNHjmQ//elPU2monu3R2trKNm/ezDZv3swAsIceeoht3ryZHTlyhDHmTr02NTWxkpIS9p3vfIft2LGDLVmyhBUXF5NrrxP+8Ic/sPHjx7OCggJ2xRVXsDVr1vhdpKwBAPe/p59+OpWms7OT3XzzzWzYsGGsuLiYfeUrX2EnTpzQ5XP48GH2+c9/nvXv35+NHDmS/c///A/r7u7O8NNkF0ZhhOrZPV577TV20UUXscLCQjZx4kT2xBNP6M7HYjH2y1/+kpWUlLDCwkL2mc98hu3du1eXpqGhgV1//fVs4MCBbPDgwWzOnDmstbU1k48RaFpaWtitt97Kxo8fz4qKitjZZ5/N7rjjDp2rKNWzPVasWMHtl2fPns0Yc69et27dyq6++mpWWFjIxo4dyxYtWuS47CHGNGHvCIIgCIIgMkxO2owQBEEQBBEcSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJXSBghCIIgCMJX/n9XfdMsKBNREQAAAABJRU5ErkJggg==", | |
"text/plain": [ | |
"<Figure size 640x480 with 1 Axes>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"disconnected_cosine.cosine.plot()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "d094178e", | |
"metadata": {}, | |
"source": [ | |
"On average the cosine similarity is three times higher for connected nodes:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 115, | |
"id": "7e8fca56", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"2.8722134876583296" | |
] | |
}, | |
"execution_count": 115, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"np.average(connected_cosine.cosine)/np.average(disconnected_cosine.cosine)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "10c0293c", | |
"metadata": {}, | |
"source": [ | |
"This shows that connectivity is correlated with the payload of the nodes and can be used to predict links." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "828b5706", | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3 (ipykernel)", | |
"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.10.11" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 5 | |
} | |
"# Cora\n", | |
"\n", | |
"A collection of Cora explorations. The focus is on machine learning and not visualization here. Jupyter notebooks are not adequate for visualization, see however the [yFiles Jupyter plugin](https://www.yworks.com/products/yfiles-graphs-for-jupyter).\n", | |
"\n", | |
"*Author*: Francois Vanderseypen, Orbifold Consulting (https://orbifold.net).<br>\n", | |
"*Article*: https://graphsandnetworks.com/the-cora-dataset<br>\n", | |
"*Last update*: July 2023.<br>"{{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"id": "dbeead4f", | |
"metadata": {}, | |
"source": [ | |
"# Cora\n", | |
"\n", | |
"A collection of Cora explorations. The focus is on machine learning and not visualization here. Jupyter notebooks are not adequate for visualization, see however the [yFiles Jupyter plugin](https://www.yworks.com/products/yfiles-graphs-for-jupyter).\n", | |
"\n", | |
"*Author*: Francois Vanderseypen, Orbifold Consulting (https://orbifold.net).<br>\n", | |
"*Article*: https://graphsandnetworks.com/the-cora-dataset<br>\n", | |
"*Last update*: July 2023.<br>" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "f59e42e0", | |
"metadata": {}, | |
"source": [ | |
"## Download data\n", | |
"\n", | |
"This part is common to all packages, it downloads and unpacks the necessary data:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "a06b6d68", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import os\n", | |
"import pandas as pd\n", | |
"data_dir = os.path.expanduser(\"~/cora\")\n", | |
"if not os.path.exists(data_dir):\n", | |
" os.makedirs(data_dir)\n", | |
"import requests\n", | |
"\n", | |
" \n", | |
"cora_tgz = os.path.join(data_dir, \"cora.tgz\")\n", | |
"response = requests.get(\"https://temprl.com/cora.tgz\", stream = True)\n", | |
"with open(cora_tgz,'wb') as output:\n", | |
" output.write(response.content)\n", | |
"\n", | |
"import tarfile\n", | |
"with tarfile.open(cora_tgz) as z:\n", | |
" for member in z:\n", | |
" if member.isdir():\n", | |
" continue\n", | |
" fname = member.name.rsplit('/',1)[1]\n", | |
" z.makefile(member,data_dir + '/' + fname)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "aa3525da", | |
"metadata": {}, | |
"source": [ | |
"## NetworkX" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "9bd8820a", | |
"metadata": {}, | |
"source": [ | |
"NetworkX is the most common graph package in Python. It does not perform any machine learning but it has a very complete graph analysis API and performs well on small and medium datasets." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "60559b49", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import networkx as nx\n", | |
"\n", | |
"edge_data = pd.read_csv(os.path.join(data_dir, \"cora.cites\"), sep='\\t', header=None, names=[\"target\", \"source\"])\n", | |
"edge_data[\"label\"] = \"cites\"" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "70c0a3a1", | |
"metadata": {}, | |
"source": [ | |
"The edge list is just a source-target couple and there is no payload:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "ba16ed6c", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"edge_data.sample(frac=1).head(5)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "658349e2", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"Gnx = nx.from_pandas_edgelist(edge_data, edge_attr=\"label\")\n", | |
"nx.set_node_attributes(Gnx, \"paper\", \"label\")" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "f3e560f3", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
" Gnx.nodes[1103985]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "a9cafdda", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"feature_names = [\"w_{}\".format(ii) for ii in range(1433)]\n", | |
"column_names = feature_names + [\"subject\"]\n", | |
"node_data = pd.read_csv(os.path.join(data_dir, \"cora.content\"), sep='\\t', header=None, names=column_names)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "42c07961", | |
"metadata": {}, | |
"source": [ | |
"The payload on the node consists of the weights with the subject label:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "c27ee8a9", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"node_data.head(5)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "61af1435", | |
"metadata": {}, | |
"source": [ | |
"There are seven subjects:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "5f405208", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"set(node_data[\"subject\"])" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "098bc658", | |
"metadata": {}, | |
"source": [ | |
"If you don't like the weights in multiple columns you can merge them:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "5ff5a8b3", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"weight_column_names = node_data.columns[0:-1]\n", | |
"node_data['content'] = node_data[weight_column_names].apply(\n", | |
" lambda x: ','.join(x.dropna().astype(str)),\n", | |
" axis=1\n", | |
")\n", | |
"node_data.drop(weight_column_names, axis=1, inplace=True)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "870e3fae", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"node_data.head()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "a1e65089", | |
"metadata": {}, | |
"source": [ | |
"Note that the content is not an embedding but is the encoded article content." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "30af6bfb", | |
"metadata": {}, | |
"source": [ | |
"### Poor man's path to link prediction: Jaccard" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "ae086f04", | |
"metadata": {}, | |
"source": [ | |
"Long before graph machine learning came along, people were predicting edges using very simple algorithms. The Jaccard index (algorithm) basically looks at how the immediate neighborhood of two nodes overlap and the more they overlap the more they are likely to be connected. The idea stems from social network analysis where the more friends you share with somebody, the more likely you know each other." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "fecc7d71", | |
"metadata": {}, | |
"source": [ | |
"The following is a manual calculation for some:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "6c6e78ac", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"for u,v in list(Gnx.edges)[12:20]:\n", | |
" cnbors = list(nx.common_neighbors(Gnx, u, v))\n", | |
" union_size = len(set(Gnx[u]) | set(Gnx[v])) \n", | |
" print(u,v, len(cnbors)/union_size)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "19be9453", | |
"metadata": {}, | |
"source": [ | |
"Using NetworkX you can do the whole graph in one go:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "60c3f13d", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"jaccard_predictions = list(nx.jaccard_coefficient(Gnx))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "e1a7c6e6", | |
"metadata": {}, | |
"source": [ | |
"Filtering out the most likely candidates:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "0453540a", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"jaccard_predictions_top = [(t[0],t[1]) for t in jaccard_predictions if t[2]>0.8]" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "ce922f59", | |
"metadata": {}, | |
"source": [ | |
"Note that none of these are existing edges in the graph:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "de9a9463", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"[t for t in jaccard_predictions_top if Gnx.has_edge(*t)]" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "9a3c6e79", | |
"metadata": {}, | |
"source": [ | |
"There are plenty of nodes which have a fully common neighborhood leading to a probability equal to one. The only case with a partially overlapping neighborhood is the following:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "e2337f85", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
" [t for t in jaccard_predictions if t[2]>0.8 and t[2]!=1]" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "47d10dda", | |
"metadata": {}, | |
"source": [ | |
"You can see that they differ in a single node:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "9dd25c6f", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"print(\"Common: \",sorted(nx.common_neighbors(Gnx, 14428, 14430)))\n", | |
"print(\"14428:\", list(nx.neighbors(Gnx,14428)))\n", | |
"print(\"14430:\", list(nx.neighbors(Gnx,14430)))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "52e4985a", | |
"metadata": {}, | |
"source": [ | |
"The main problem with Jaccard is the fact that it does not take the payload into account, only the immediate topology is looked at. Even the topology, it's only the first hop and maybe node neighborhoods on a higher level have a lot in common.\n", | |
"This makes Jaccard indicative rather than reliable." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "33b9c715", | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3 (ipykernel)", | |
"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.10.11" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 5 | |
} | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"id": "dbeead4f", | |
"metadata": {}, | |
"source": [ | |
"# Cora\n", | |
"\n", | |
"A collection of Cora explorations. The focus is on machine learning and not visualization here. Jupyter notebooks are not adequate for visualization, see however the [yFiles Jupyter plugin](https://www.yworks.com/products/yfiles-graphs-for-jupyter).\n", | |
"\n", | |
"*Author*: Francois Vanderseypen, Orbifold Consulting (https://orbifold.net).<br>\n", | |
"*Article*: https://graphsandnetworks.com/the-cora-dataset<br>\n", | |
"*Last update*: July 2023.<br>" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "f59e42e0", | |
"metadata": {}, | |
"source": [ | |
"## Download data\n", | |
"\n", | |
"This part is common to all packages, it downloads and unpacks the necessary data:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"id": "a06b6d68", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import os\n", | |
"import pandas as pd\n", | |
"data_dir = os.path.expanduser(\"~/cora\")\n", | |
"if not os.path.exists(data_dir):\n", | |
" os.makedirs(data_dir)\n", | |
"import requests\n", | |
"\n", | |
" \n", | |
"cora_tgz = os.path.join(data_dir, \"cora.tgz\")\n", | |
"response = requests.get(\"https://temprl.com/cora.tgz\", stream = True)\n", | |
"with open(cora_tgz,'wb') as output:\n", | |
" output.write(response.content)\n", | |
"\n", | |
"import tarfile\n", | |
"with tarfile.open(cora_tgz) as z:\n", | |
" for member in z:\n", | |
" if member.isdir():\n", | |
" continue\n", | |
" fname = member.name.rsplit('/',1)[1]\n", | |
" z.makefile(member,data_dir + '/' + fname)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "aa3525da", | |
"metadata": {}, | |
"source": [ | |
"## NetworkX" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "9bd8820a", | |
"metadata": {}, | |
"source": [ | |
"NetworkX is the most common graph package in Python. It does not perform any machine learning but it has a very complete graph analysis API and performs well on small and medium datasets." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"id": "60559b49", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import networkx as nx\n", | |
"\n", | |
"edge_data = pd.read_csv(os.path.join(data_dir, \"cora.cites\"), sep='\\t', header=None, names=[\"target\", \"source\"])\n", | |
"edge_data[\"label\"] = \"cites\"" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "70c0a3a1", | |
"metadata": {}, | |
"source": [ | |
"The edge list is just a source-target couple and there is no payload:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"id": "ba16ed6c", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<div>\n", | |
"<style scoped>\n", | |
" .dataframe tbody tr th:only-of-type {\n", | |
" vertical-align: middle;\n", | |
" }\n", | |
"\n", | |
" .dataframe tbody tr th {\n", | |
" vertical-align: top;\n", | |
" }\n", | |
"\n", | |
" .dataframe thead th {\n", | |
" text-align: right;\n", | |
" }\n", | |
"</style>\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th>target</th>\n", | |
" <th>source</th>\n", | |
" <th>label</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>2671</th>\n", | |
" <td>28957</td>\n", | |
" <td>35922</td>\n", | |
" <td>cites</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>3334</th>\n", | |
" <td>56115</td>\n", | |
" <td>135130</td>\n", | |
" <td>cites</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1696</th>\n", | |
" <td>10183</td>\n", | |
" <td>259772</td>\n", | |
" <td>cites</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1701</th>\n", | |
" <td>10430</td>\n", | |
" <td>1120713</td>\n", | |
" <td>cites</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>5040</th>\n", | |
" <td>578646</td>\n", | |
" <td>1153900</td>\n", | |
" <td>cites</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" target source label\n", | |
"2671 28957 35922 cites\n", | |
"3334 56115 135130 cites\n", | |
"1696 10183 259772 cites\n", | |
"1701 10430 1120713 cites\n", | |
"5040 578646 1153900 cites" | |
] | |
}, | |
"execution_count": 3, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"edge_data.sample(frac=1).head(5)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"id": "658349e2", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"Gnx = nx.from_pandas_edgelist(edge_data, edge_attr=\"label\")\n", | |
"nx.set_node_attributes(Gnx, \"paper\", \"label\")" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"id": "f3e560f3", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"{'label': 'paper'}" | |
] | |
}, | |
"execution_count": 5, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
" Gnx.nodes[1103985]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"id": "a9cafdda", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"feature_names = [\"w_{}\".format(ii) for ii in range(1433)]\n", | |
"column_names = feature_names + [\"subject\"]\n", | |
"node_data = pd.read_csv(os.path.join(data_dir, \"cora.content\"), sep='\\t', header=None, names=column_names)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "42c07961", | |
"metadata": {}, | |
"source": [ | |
"The payload on the node consists of the weights with the subject label:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"id": "c27ee8a9", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<div>\n", | |
"<style scoped>\n", | |
" .dataframe tbody tr th:only-of-type {\n", | |
" vertical-align: middle;\n", | |
" }\n", | |
"\n", | |
" .dataframe tbody tr th {\n", | |
" vertical-align: top;\n", | |
" }\n", | |
"\n", | |
" .dataframe thead th {\n", | |
" text-align: right;\n", | |
" }\n", | |
"</style>\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th>w_0</th>\n", | |
" <th>w_1</th>\n", | |
" <th>w_2</th>\n", | |
" <th>w_3</th>\n", | |
" <th>w_4</th>\n", | |
" <th>w_5</th>\n", | |
" <th>w_6</th>\n", | |
" <th>w_7</th>\n", | |
" <th>w_8</th>\n", | |
" <th>w_9</th>\n", | |
" <th>...</th>\n", | |
" <th>w_1424</th>\n", | |
" <th>w_1425</th>\n", | |
" <th>w_1426</th>\n", | |
" <th>w_1427</th>\n", | |
" <th>w_1428</th>\n", | |
" <th>w_1429</th>\n", | |
" <th>w_1430</th>\n", | |
" <th>w_1431</th>\n", | |
" <th>w_1432</th>\n", | |
" <th>subject</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>31336</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>1</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>Neural_Networks</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1061127</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>0</td>\n", | |
" <td>1</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>Rule_Learning</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1106406</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>Reinforcement_Learning</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>13195</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>Reinforcement_Learning</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>37879</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>Probabilistic_Methods</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"<p>5 rows × 1434 columns</p>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" w_0 w_1 w_2 w_3 w_4 w_5 w_6 w_7 w_8 w_9 ... w_1424 \\\n", | |
"31336 0 0 0 0 0 0 0 0 0 0 ... 0 \n", | |
"1061127 0 0 0 0 0 0 0 0 0 0 ... 0 \n", | |
"1106406 0 0 0 0 0 0 0 0 0 0 ... 0 \n", | |
"13195 0 0 0 0 0 0 0 0 0 0 ... 0 \n", | |
"37879 0 0 0 0 0 0 0 0 0 0 ... 0 \n", | |
"\n", | |
" w_1425 w_1426 w_1427 w_1428 w_1429 w_1430 w_1431 w_1432 \\\n", | |
"31336 0 1 0 0 0 0 0 0 \n", | |
"1061127 1 0 0 0 0 0 0 0 \n", | |
"1106406 0 0 0 0 0 0 0 0 \n", | |
"13195 0 0 0 0 0 0 0 0 \n", | |
"37879 0 0 0 0 0 0 0 0 \n", | |
"\n", | |
" subject \n", | |
"31336 Neural_Networks \n", | |
"1061127 Rule_Learning \n", | |
"1106406 Reinforcement_Learning \n", | |
"13195 Reinforcement_Learning \n", | |
"37879 Probabilistic_Methods \n", | |
"\n", | |
"[5 rows x 1434 columns]" | |
] | |
}, | |
"execution_count": 7, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"node_data.head(5)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "61af1435", | |
"metadata": {}, | |
"source": [ | |
"There are seven subjects:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 45, | |
"id": "5f405208", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"{'Case_Based',\n", | |
" 'Genetic_Algorithms',\n", | |
" 'Neural_Networks',\n", | |
" 'Probabilistic_Methods',\n", | |
" 'Reinforcement_Learning',\n", | |
" 'Rule_Learning',\n", | |
" 'Theory'}" | |
] | |
}, | |
"execution_count": 45, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"set(node_data[\"subject\"])" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "098bc658", | |
"metadata": {}, | |
"source": [ | |
"If you don't like the weights in multiple columns you can merge them:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"id": "5ff5a8b3", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"weight_column_names = node_data.columns[0:-1]\n", | |
"node_data['content'] = node_data[weight_column_names].apply(\n", | |
" lambda x: ','.join(x.dropna().astype(str)),\n", | |
" axis=1\n", | |
")\n", | |
"node_data.drop(weight_column_names, axis=1, inplace=True)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 9, | |
"id": "870e3fae", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<div>\n", | |
"<style scoped>\n", | |
" .dataframe tbody tr th:only-of-type {\n", | |
" vertical-align: middle;\n", | |
" }\n", | |
"\n", | |
" .dataframe tbody tr th {\n", | |
" vertical-align: top;\n", | |
" }\n", | |
"\n", | |
" .dataframe thead th {\n", | |
" text-align: right;\n", | |
" }\n", | |
"</style>\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th>subject</th>\n", | |
" <th>content</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>31336</th>\n", | |
" <td>Neural_Networks</td>\n", | |
" <td>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1061127</th>\n", | |
" <td>Rule_Learning</td>\n", | |
" <td>0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,...</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1106406</th>\n", | |
" <td>Reinforcement_Learning</td>\n", | |
" <td>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>13195</th>\n", | |
" <td>Reinforcement_Learning</td>\n", | |
" <td>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>37879</th>\n", | |
" <td>Probabilistic_Methods</td>\n", | |
" <td>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" subject \\\n", | |
"31336 Neural_Networks \n", | |
"1061127 Rule_Learning \n", | |
"1106406 Reinforcement_Learning \n", | |
"13195 Reinforcement_Learning \n", | |
"37879 Probabilistic_Methods \n", | |
"\n", | |
" content \n", | |
"31336 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,... \n", | |
"1061127 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,... \n", | |
"1106406 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,... \n", | |
"13195 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,... \n", | |
"37879 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,... " | |
] | |
}, | |
"execution_count": 9, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"node_data.head()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "a1e65089", | |
"metadata": {}, | |
"source": [ | |
"Note that the content is not an embedding but is the encoded article content." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "30af6bfb", | |
"metadata": {}, | |
"source": [ | |
"### Poor man's path to link prediction: Jaccard" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "ae086f04", | |
"metadata": {}, | |
"source": [ | |
"Long before graph machine learning came along, people were predicting edges using very simple algorithms. The Jaccard index (algorithm) basically looks at how the immediate neighborhood of two nodes overlap and the more they overlap the more they are likely to be connected. The idea stems from social network analysis where the more friends you share with somebody, the more likely you know each other." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "fecc7d71", | |
"metadata": {}, | |
"source": [ | |
"The following is a manual calculation for some:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 10, | |
"id": "6c6e78ac", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"35 1113438 0.005813953488372093\n", | |
"35 1113831 0.0058823529411764705\n", | |
"35 1114331 0.01764705882352941\n", | |
"35 1117476 0.0058823529411764705\n", | |
"35 1119505 0.0\n", | |
"35 1119708 0.01764705882352941\n", | |
"35 1120431 0.0\n", | |
"35 1123756 0.005847953216374269\n" | |
] | |
} | |
], | |
"source": [ | |
"for u,v in list(Gnx.edges)[12:20]:\n", | |
" cnbors = list(nx.common_neighbors(Gnx, u, v))\n", | |
" union_size = len(set(Gnx[u]) | set(Gnx[v])) \n", | |
" print(u,v, len(cnbors)/union_size)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "19be9453", | |
"metadata": {}, | |
"source": [ | |
"Using NetworkX you can do the whole graph in one go:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 11, | |
"id": "60c3f13d", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"jaccard_predictions = list(nx.jaccard_coefficient(Gnx))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "e1a7c6e6", | |
"metadata": {}, | |
"source": [ | |
"Filtering out the most likely candidates:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 12, | |
"id": "0453540a", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"jaccard_predictions_top = [(t[0],t[1]) for t in jaccard_predictions if t[2]>0.8]" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "ce922f59", | |
"metadata": {}, | |
"source": [ | |
"Note that none of these are existing edges in the graph:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 104, | |
"id": "de9a9463", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"[]" | |
] | |
}, | |
"execution_count": 104, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"[t for t in jaccard_predictions_top if Gnx.has_edge(*t)]" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "777c6d2f", | |
"metadata": {}, | |
"source": [ | |
"There are plenty of nodes which have a fully common neighborhood leading to a probability equal to one. The only case with a partially overlapping neighborhood is the following:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 30, | |
"id": "e2337f85", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"[(14428, 14430, 0.8571428571428571)]" | |
] | |
}, | |
"execution_count": 30, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
" [t for t in jaccard_predictions if t[2]>0.8 and t[2]!=1]" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "c59b74cc", | |
"metadata": {}, | |
"source": [ | |
"You can see that they differ in a single node:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 37, | |
"id": "d42a920a", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Common: [14429, 14431, 34082, 73119, 1103031, 1103969]\n", | |
"14428: [1103031, 1103969, 14429, 14431, 34082, 73119]\n", | |
"14430: [1103031, 1103969, 1119216, 14429, 14431, 34082, 73119]\n" | |
] | |
} | |
], | |
"source": [ | |
"print(\"Common: \",sorted(nx.common_neighbors(Gnx, 14428, 14430)))\n", | |
"print(\"14428:\", list(nx.neighbors(Gnx,14428)))\n", | |
"print(\"14430:\", list(nx.neighbors(Gnx,14430)))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "962f7bfb", | |
"metadata": {}, | |
"source": [ | |
"The main problem with Jaccard is the fact that it does not take the payload into account, only the immediate topology is looked at. Even the topology, it's only the first hop and maybe node neighborhoods on a higher level have a lot in common.\n", | |
"This makes Jaccard indicative rather than reliable." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "b36c1128", | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3 (ipykernel)", | |
"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.10.11" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 5 | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "221a982a", | |
"metadata": {}, | |
"source": [ | |
"## Download data\n", | |
"\n", | |
"This part is common to all packages, it downloads and unpacks the necessary data:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 22, | |
"id": "a06b6d68", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import os\n", | |
"import pandas as pd\n", | |
"data_dir = os.path.expanduser(\"~/cora\")\n", | |
"if not os.path.exists(data_dir):\n", | |
" os.makedirs(data_dir)\n", | |
"import requests\n", | |
"\n", | |
" \n", | |
"cora_tgz = os.path.join(data_dir, \"cora.tgz\")\n", | |
"response = requests.get(\"https://temprl.com/cora.tgz\", stream = True)\n", | |
"with open(cora_tgz,'wb') as output:\n", | |
" output.write(response.content)\n", | |
"\n", | |
"import tarfile\n", | |
"with tarfile.open(cora_tgz) as z:\n", | |
" for member in z:\n", | |
" if member.isdir():\n", | |
" continue\n", | |
" fname = member.name.rsplit('/',1)[1]\n", | |
" z.makefile(member,data_dir + '/' + fname)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "99458e7d", | |
"metadata": {}, | |
"source": [ | |
"## NetworkX" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "dd2672ad", | |
"metadata": {}, | |
"source": [ | |
"NetworkX is the most common graph package in Python. It does not perform any machine learning but it has a very complete graph analysis API and performs well on small and medium datasets." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 39, | |
"id": "60559b49", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import networkx as nx\n", | |
"\n", | |
"edge_data = pd.read_csv(os.path.join(data_dir, \"cora.cites\"), sep='\\t', header=None, names=[\"target\", \"source\"])\n", | |
"edge_data[\"label\"] = \"cites\"" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "5de3c572", | |
"metadata": {}, | |
"source": [ | |
"The edge list is just a source-target couple and there is no payload:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 40, | |
"id": "8e58718d", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<div>\n", | |
"<style scoped>\n", | |
" .dataframe tbody tr th:only-of-type {\n", | |
" vertical-align: middle;\n", | |
" }\n", | |
"\n", | |
" .dataframe tbody tr th {\n", | |
" vertical-align: top;\n", | |
" }\n", | |
"\n", | |
" .dataframe thead th {\n", | |
" text-align: right;\n", | |
" }\n", | |
"</style>\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th>target</th>\n", | |
" <th>source</th>\n", | |
" <th>label</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>4354</th>\n", | |
" <td>162664</td>\n", | |
" <td>531348</td>\n", | |
" <td>cites</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>907</th>\n", | |
" <td>3232</td>\n", | |
" <td>20942</td>\n", | |
" <td>cites</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>4151</th>\n", | |
" <td>133553</td>\n", | |
" <td>1120049</td>\n", | |
" <td>cites</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2607</th>\n", | |
" <td>28290</td>\n", | |
" <td>56709</td>\n", | |
" <td>cites</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>4943</th>\n", | |
" <td>523574</td>\n", | |
" <td>1154229</td>\n", | |
" <td>cites</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" target source label\n", | |
"4354 162664 531348 cites\n", | |
"907 3232 20942 cites\n", | |
"4151 133553 1120049 cites\n", | |
"2607 28290 56709 cites\n", | |
"4943 523574 1154229 cites" | |
] | |
}, | |
"execution_count": 40, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"edge_data.sample(frac=1).head(5)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 41, | |
"id": "2d12a50d", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"Gnx = nx.from_pandas_edgelist(edge_data, edge_attr=\"label\")\n", | |
"nx.set_node_attributes(Gnx, \"paper\", \"label\")" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 42, | |
"id": "33f2d088", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"{'label': 'paper'}" | |
] | |
}, | |
"execution_count": 42, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
" Gnx.nodes[1103985]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 43, | |
"id": "2e721d84", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"feature_names = [\"w_{}\".format(ii) for ii in range(1433)]\n", | |
"column_names = feature_names + [\"subject\"]\n", | |
"node_data = pd.read_csv(os.path.join(data_dir, \"cora.content\"), sep='\\t', header=None, names=column_names)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "89b1c2e1", | |
"metadata": {}, | |
"source": [ | |
"The payload on the node consists of the weights with the subject label:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 44, | |
"id": "7e9df542", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<div>\n", | |
"<style scoped>\n", | |
" .dataframe tbody tr th:only-of-type {\n", | |
" vertical-align: middle;\n", | |
" }\n", | |
"\n", | |
" .dataframe tbody tr th {\n", | |
" vertical-align: top;\n", | |
" }\n", | |
"\n", | |
" .dataframe thead th {\n", | |
" text-align: right;\n", | |
" }\n", | |
"</style>\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th>w_0</th>\n", | |
" <th>w_1</th>\n", | |
" <th>w_2</th>\n", | |
" <th>w_3</th>\n", | |
" <th>w_4</th>\n", | |
" <th>w_5</th>\n", | |
" <th>w_6</th>\n", | |
" <th>w_7</th>\n", | |
" <th>w_8</th>\n", | |
" <th>w_9</th>\n", | |
" <th>...</th>\n", | |
" <th>w_1424</th>\n", | |
" <th>w_1425</th>\n", | |
" <th>w_1426</th>\n", | |
" <th>w_1427</th>\n", | |
" <th>w_1428</th>\n", | |
" <th>w_1429</th>\n", | |
" <th>w_1430</th>\n", | |
" <th>w_1431</th>\n", | |
" <th>w_1432</th>\n", | |
" <th>subject</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>31336</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>1</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>Neural_Networks</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1061127</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>0</td>\n", | |
" <td>1</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>Rule_Learning</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1106406</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>Reinforcement_Learning</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>13195</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>Reinforcement_Learning</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>37879</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>Probabilistic_Methods</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"<p>5 rows × 1434 columns</p>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" w_0 w_1 w_2 w_3 w_4 w_5 w_6 w_7 w_8 w_9 ... w_1424 \\\n", | |
"31336 0 0 0 0 0 0 0 0 0 0 ... 0 \n", | |
"1061127 0 0 0 0 0 0 0 0 0 0 ... 0 \n", | |
"1106406 0 0 0 0 0 0 0 0 0 0 ... 0 \n", | |
"13195 0 0 0 0 0 0 0 0 0 0 ... 0 \n", | |
"37879 0 0 0 0 0 0 0 0 0 0 ... 0 \n", | |
"\n", | |
" w_1425 w_1426 w_1427 w_1428 w_1429 w_1430 w_1431 w_1432 \\\n", | |
"31336 0 1 0 0 0 0 0 0 \n", | |
"1061127 1 0 0 0 0 0 0 0 \n", | |
"1106406 0 0 0 0 0 0 0 0 \n", | |
"13195 0 0 0 0 0 0 0 0 \n", | |
"37879 0 0 0 0 0 0 0 0 \n", | |
"\n", | |
" subject \n", | |
"31336 Neural_Networks \n", | |
"1061127 Rule_Learning \n", | |
"1106406 Reinforcement_Learning \n", | |
"13195 Reinforcement_Learning \n", | |
"37879 Probabilistic_Methods \n", | |
"\n", | |
"[5 rows x 1434 columns]" | |
] | |
}, | |
"execution_count": 44, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"node_data.head(5)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "46c3f09d", | |
"metadata": {}, | |
"source": [ | |
"There are seven subjects:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 45, | |
"id": "72aedfcf", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"{'Case_Based',\n", | |
" 'Genetic_Algorithms',\n", | |
" 'Neural_Networks',\n", | |
" 'Probabilistic_Methods',\n", | |
" 'Reinforcement_Learning',\n", | |
" 'Rule_Learning',\n", | |
" 'Theory'}" | |
] | |
}, | |
"execution_count": 45, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"set(node_data[\"subject\"])" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "803e0b6d", | |
"metadata": {}, | |
"source": [ | |
"If you don't like the weights in multiple columns you can merge them:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 46, | |
"id": "d287d7b9", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"weight_column_names = node_data.columns[0:-1]\n", | |
"node_data['content'] = node_data[weight_column_names].apply(\n", | |
" lambda x: ','.join(x.dropna().astype(str)),\n", | |
" axis=1\n", | |
")\n", | |
"node_data.drop(weight_column_names, axis=1, inplace=True)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 47, | |
"id": "611826dc", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<div>\n", | |
"<style scoped>\n", | |
" .dataframe tbody tr th:only-of-type {\n", | |
" vertical-align: middle;\n", | |
" }\n", | |
"\n", | |
" .dataframe tbody tr th {\n", | |
" vertical-align: top;\n", | |
" }\n", | |
"\n", | |
" .dataframe thead th {\n", | |
" text-align: right;\n", | |
" }\n", | |
"</style>\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th>subject</th>\n", | |
" <th>content</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>31336</th>\n", | |
" <td>Neural_Networks</td>\n", | |
" <td>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1061127</th>\n", | |
" <td>Rule_Learning</td>\n", | |
" <td>0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,...</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1106406</th>\n", | |
" <td>Reinforcement_Learning</td>\n", | |
" <td>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>13195</th>\n", | |
" <td>Reinforcement_Learning</td>\n", | |
" <td>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>37879</th>\n", | |
" <td>Probabilistic_Methods</td>\n", | |
" <td>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" subject \\\n", | |
"31336 Neural_Networks \n", | |
"1061127 Rule_Learning \n", | |
"1106406 Reinforcement_Learning \n", | |
"13195 Reinforcement_Learning \n", | |
"37879 Probabilistic_Methods \n", | |
"\n", | |
" content \n", | |
"31336 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,... \n", | |
"1061127 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,... \n", | |
"1106406 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,... \n", | |
"13195 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,... \n", | |
"37879 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,... " | |
] | |
}, | |
"execution_count": 47, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"node_data.head()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "e6c9a46e", | |
"metadata": {}, | |
"source": [ | |
"Note that the content is not an embedding but is the encoded article content." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "17f37893", | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3 (ipykernel)", | |
"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.10.11" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 5 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment