Skip to content
Snippets Groups Projects
Commit 3a26b7ed authored by Fize Jacques's avatar Fize Jacques
Browse files

Add sphinx documentation + Change documentation + clean import+ debug

parent 66856df8
No related branches found
No related tags found
No related merge requests found
Showing
with 376 additions and 32 deletions
...@@ -210,7 +210,7 @@ instance/ ...@@ -210,7 +210,7 @@ instance/
.scrapy .scrapy
# Sphinx documentation # Sphinx documentation
docs/_build/ doc/build/
# PyBuilder # PyBuilder
.pybuilder/ .pybuilder/
...@@ -286,4 +286,5 @@ visualisation ...@@ -286,4 +286,5 @@ visualisation
results results
outputs outputs
notebooks notebooks
.idea/ .idea/
\ No newline at end of file erosion_test.ipynb
\ No newline at end of file
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = source
BUILDDIR = build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
<mxfile host="Electron" modified="2021-05-04T12:27:55.299Z" agent="5.0 (Macintosh; Intel Mac OS X 10_16_0) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/12.9.13 Chrome/80.0.3987.163 Electron/8.2.1 Safari/537.36" etag="0mYTPV5g55D7n4PHjvws" version="12.9.13" type="device"><diagram id="Whi_XeIdqUOBZHivEhyE" name="Page-1">zVVNb9swDP01PrawreWjxyVpNwwbNjSHfty0iLE02JYhM7GdXz/JpmJ73oIVKNCeLD6SEvmeKQVsndWfDC/kNy0gDeJQ1AHbBHEcReHcfhzSdMhiueyAxChBQT2wVScgMCT0oASUo0DUOkVVjMGdznPY4QjjxuhqHLbX6fjUgicwAbY7nk7RByVQdugyXvT4Z1CJ9CdH85vOk3EfTJ2UkgtdDSB2G7C10Rq7VVavIXXkeV66vLt/eM+FGcjxfxLqx3n2pazu5bO8P+HTcXP18P3qA9WGjW/Y6EMuwOWEAVtpg1InOufpV60LC0YW/AWIDUnFD6gtJDFLyQu1wsfB+om2cutNPTQab+RoGpcSXoeLmQfavOtFD/TJreWzBS9lW2/kXT/AqAwQDEV0PYKYKN1TR1CpD2YHF/iK6RfkJgG8EMfOAtvJAG2rMY3NM5ByVMdxHZx+0eQc16toFyTkC0SlIo88PdBJE5XtLnaCrLGqpELYFrxtu7JDPFaTl0U3VntVO5aJzCMYhPoyndP2fcKcRoLuBOZHpBpMGEFyMFwee3XC2DsnLF6MCYvfmrDZlDB2N+HMNox/kJOqJLfrnW3cjefK0aLsbfuRHJkSwqWvDJTqxH+2W7kZLrTKsW1jtgpmG7eXvXnK7hJyW+91jls6+2yT++aVZPC3vpdhOZWB/UUG9nIZrNm/DK1v8L6y298=</diagram></mxfile>
\ No newline at end of file
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd
dl{
margin-top: 0.5em !important;
}
div.sphinxsidebarwrapper p.logo {
padding:2em !important;
}
\ No newline at end of file
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
sys.path.insert(0, os.path.abspath('../..'))
# -- Project information -----------------------------------------------------
project = 'Link Prediction'
copyright = '2021, Jacques Fize'
author = 'Jacques Fize'
# The full version, including alpha/beta/rc tags
release = '0.6'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.coverage',
'sphinx.ext.napoleon',
'sphinx.ext.autosectionlabel'
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = 'en'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = []
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'alabaster'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
html_css_files = [
'css/custom.css',
]
html_logo = "logo.png"
napoleon_google_docstring = False
napoleon_use_param = False
napoleon_use_ivar = True
Get Started
===========
Installation
------------
See :ref:`Installation`
Generate a graph with a model
-----------------------------
We developed a serie of functions for generating graph based on the following models:
* Spatial model
* Stochastic Block Model
* Configuration Model
* Random (ER)
* Mixed Model (Spatial + SBM
For example, if you want to generate a graph based on a stochastic block model, use the following code :
.. code-block:: python
from lib.random import stochastic_block_model_graph
G = stochastic_block_model_graph(nb_nodes=300,nb_edges=1200,nb_com=5,percentage_edge_betw=0.01)
If you wish to generate a dataset containing generated graph with different configurations,
you can use the script generate_random_graph.py` using the following command :
.. code-block:: shell
python generate_theoric_random_graph.py <output_dir>
\ No newline at end of file
Graph Generators
===================
All graph generator can be found in the module `lib.random`. For every graph generator, you can set the number of edges and nodes
in the resulting graph.
For example, if you want to generate a graph following the stochastic block model, use the follwing code :
.. code-block:: python
from lib.random import stochastic_block_model_graph
G = stochastic_block_model_graph(nb_nodes=300,nb_edges=1200,nb_com=5,percentage_edge_betw=0.01)
Stochastic Block Model
----------------------
This model partitions :math:`n` vertices in :math:`k` blocks, and places edges between pairs of nodes with a probability that depends on the vertices membership. The probability of a pair of nodes is computed based four parameter, the number of vertices :math:`|V|` and edges :math:`|E|`, the number of blocks :math:`|B|` and finally, the percentage of interlinks :math:`per_{betw}`, i.e number of selected pairs of nodes that belongs to different blocks.
First, we assign randomly a block :math:`b_i \in B` for each node :math:`v \in V`. In this model, all blocks are associated with the same number of nodes :math:`\frac{|V|}{|B|}`. Second, to compute the probability of a pair of nodes to be connected, we use the function :math:`f(u,v)` defined as follows:
.. math::
f(u,v)=\begin{cases}
p_{in}, & if b_u == b_v\\
p_{out}, & otherwise
\end{cases}
where :math:`p_{in}` is the probability of a pair of nodes from the same block to be connected, and :math:`p_{out}` is the probability of a pair of nodes with different block membership to be connected. :math:`b_u` and :math:`b_v` correspond the block membership for the nodes :math:`u` and :math:`v`.
To compute the :math:`p_{in}` and :math:`p_{out}`, we do the following:
.. math::
\begin{eqnarray}
U_{in} = \sum\limits_{b\in B} \frac{N_b\times(N_b-1)}{2}\\
U = \frac{|V| \times(|V| -1)}{2}\\
U_{out} = U-U_{in}\\
L_{out} = |E| * per_{betw}\\
L_{in} = |E| - L_out\\
\\p_{in} = L_{in}/U_{in}\\
p_{out} = L_{out}/U_{out}
\end{eqnarray}
Spatial Model
-------------
This model generate a graph with $n$ vertices and $e$ edges selected randomly. Edges are selected using the deterrence function defined in the following formula:
.. math::
err(u,v) = \frac{1}{|p_u - p_v|^2 +\epsilon}
where :math:`u` and :math:`v` are two vertices and :math:`p_u` and :math:`p_v` correspond to their position.
Nodes coordinates can be generated randomly or randomly selected from existing places (here countries centroids).
ER Random Graph
---------------
The model returns a Erdős-Rényi graph or a binomial graph. Basically,
the model generates a graph :math:`G_{n,m}` where :math:`n` corresponds to the number of vertices
and :math:`m` the number of edges in :math:`G_{n,m}`. In this model, each pair of nodes has the same
probability to be connected.
Configuration model
-------------------
The configuration model generates a graph (graph with parallel edges and self loops) by randomly assigning edges to match a given degree distribution. In our case, generated graph degree distribution follows a powerlaw. We use the Molloy-Reed approach [molloy1995critical]_ to generate the graph.
.. [molloy1995critical] Molloy, M., & Reed, B. (1995). A critical point for random graphs with a given degree sequence. Random structures & algorithms, 6(2‐3), 161-180.
Generate a graph dataset based on different models and configurations
---------------------------------------------------------------------
If you wish to generate a dataset containing generated graph with different configurations,
you can use the script generate_random_graph.py` using the following command :
.. code-block:: shell
python generate_theoric_random_graph.py <output_dir>
You can modify the parameters of each configuration for each model in the script source code.
Graph parameters
^^^^^^^^^^^^^^^^
.. code-block:: python
GRAPH_SIZE = [80,800,5000]
EDGE_FACTOR = [2,4,5,10]
sample_per_params = 10
Model parameters
^^^^^^^^^^^^^^^^
.. code-block:: python
parameters = {
"stochastic_block_model_graph": {
"nb_nodes":GRAPH_SIZE,
"nb_edges":EDGE_FACTOR,
"nb_com" :[2,5,8,16,10,25],
"percentage_edge_betw":[0.1,0.01],
},
#...
}
API Reference
-------------
.. automodule:: lib.random
:members:
\ No newline at end of file
.. Link Prediction documentation master file, created by
sphinx-quickstart on Tue May 4 13:26:48 2021.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to Link Prediction's documentation!
===========================================
Summary
-------
.. toctree::
:maxdepth: 2
installation
get_started
graph_generator
link_pred_eval
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
Installation
============
To use the code in this repo, first you'll need to install Python requirements using the following command
.. code-block:: shell
pip install -r requirements.txt
Then, install our custom version of EvalNE using pip
.. code-block:: shell
pip install git+https://github.com/thunlp/OpenNE.git
pip install git+https://github.com/Jacobe2169/EvalNE
Finally, install the Python library `graph-tool
<https://graph-tool.skewed.de>`_.
\ No newline at end of file
Link Prediction Evaluation
==========================
doc/source/logo.png

5.7 KiB

import argparse
from lib.utils import load_edgelist
from evalne.evaluation.evaluator import LPEvaluator from evalne.evaluation.evaluator import LPEvaluator
from evalne.evaluation.split import EvalSplit as LPEvalSplit from evalne.evaluation.split import EvalSplit as LPEvalSplit
from evalne.evaluation.score import Scoresheet from evalne.evaluation.score import Scoresheet
from evalne.utils import preprocess as pp from evalne.utils import preprocess as pp
import networkx as nx import networkx as nx
from tqdm import tqdm from tqdm import tqdm
from lib.utils import load_edgelist
import argparse
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("graph_filename") parser.add_argument("graph_filename")
......
# coding = utf-8 # coding = utf-8
import argparse import argparse
import time import time
import glob
from lib.erosion_model import eval_erosion_model
from lib.utils import load_edgelist
import pandas as pd import pandas as pd
import networkx as nx
from lib.random import mixed_model_spat_sbm
from lib.erosion_model import eval_erosion_model
from joblib import Parallel,delayed from joblib import Parallel,delayed
import networkx as nx
import glob
from tqdm import tqdm from tqdm import tqdm
from lib.utils import load_edgelist
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("graph_dir") parser.add_argument("graph_dir")
......
# coding = utf-8 # coding = utf-8
import networkx as nx
import matplotlib.pyplot as plt
import seaborn as sns
import glob import glob
import numpy as np
import re import re
import pandas as pd
import argparse import argparse
import os import os
import pandas as pd
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
import seaborn as sns
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("graph_directory") parser.add_argument("graph_directory")
parser.add_argument("output_directory") parser.add_argument("output_directory")
......
# coding = utf-8 # coding = utf-8
import itertools import itertools
import os import os
import argparse
import lib.random as ra
import networkx as nx import networkx as nx
import argparse
from tqdm import tqdm from tqdm import tqdm
import lib.random as ra
# COMMAND PARSING # COMMAND PARSING
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
......
# coding = utf-8 # coding = utf-8
import itertools import itertools
import os import os
import argparse
import lib.random as ra
import networkx as nx import networkx as nx
import argparse
from tqdm import tqdm from tqdm import tqdm
import lib.random as ra
# COMMAND PARSING # COMMAND PARSING
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
......
import matplotlib.pyplot as plt from glob import glob
import matplotlib.patheffects as path_effects
import seaborn as sns
import networkx as nx
import pandas as pd import pandas as pd
import numpy as np import numpy as np
from glob import glob import networkx as nx
from fa2 import ForceAtlas2 from fa2 import ForceAtlas2
import matplotlib.pyplot as plt
import matplotlib.patheffects as path_effects
import seaborn as sns
def get_force_atlas(weight_influence=0, scaling_ratio=3.0, gravity=5): def get_force_atlas(weight_influence=0, scaling_ratio=3.0, gravity=5):
""" """
......
# coding = utf-8 # coding = utf-8
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_auc_score
from .link_prediction_eval import get_auc_heuristics, split_train_test, get_all_possible_edges from .link_prediction_eval import get_auc_heuristics, split_train_test, get_all_possible_edges
from .lambda_func import euclid_dist as dist from .lambda_func import euclid_dist as dist
from .lambda_func import hash_func from .lambda_func import hash_func
...@@ -15,6 +12,9 @@ import networkx as nx ...@@ -15,6 +12,9 @@ import networkx as nx
import numpy as np import numpy as np
float_epsilon = np.finfo(float).eps float_epsilon = np.finfo(float).eps
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_auc_score
VERBOSE = True VERBOSE = True
def log(x): def log(x):
if VERBOSE: if VERBOSE:
......
from .link_prediction_eval import get_all_possible_edges
import numpy as np import numpy as np
import networkx as nx import networkx as nx
import pandas as pd import pandas as pd
from .link_prediction_eval import get_all_possible_edges
try: try:
import graph_tool as gt import graph_tool as gt
except: except:
pass raise ImportError("Graph-tool must be installed !")
def parse_evalne_output(string): def parse_evalne_output(string):
def foo(x): def foo(x):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment