From d3c22dd0d275cd65cab00a184ce3440fa4f7a258 Mon Sep 17 00:00:00 2001
From: Fize Jacques <jacques.fize@cirad.fr>
Date: Fri, 27 Nov 2020 11:35:28 +0100
Subject: [PATCH] Save Repo

---
 LICENSE                                       |  21 +
 README.md                                     | 194 ++++++++
 desamb_eval.py                                |  66 +++
 desamb_eval_runs.sh                           |   3 +
 documentation/imgs/LSTM_archv2.png            | Bin 0 -> 187798 bytes
 generate_dataset.py                           | 149 ++++++
 geocoder_app.py                               |  93 ++++
 helpers.py                                    | 201 ++++++++
 lib/__init__.py                               |   0
 lib/custom_layer.py                           |  31 ++
 lib/data_generator.py                         | 347 ++++++++++++++
 lib/data_generatorv3.py                       | 354 ++++++++++++++
 lib/datageneratorv4.py                        |  65 +++
 lib/geocoder/__init__.py                      |   0
 lib/geocoder/bert_geocoder.py                 |  67 +++
 lib/geocoder/heuristics.py                    |  55 +++
 lib/geocoder/our_geocoder.py                  | 113 +++++
 lib/geocoder/svm_geocoder.py                  |  36 ++
 lib/metrics.py                                |  37 ++
 lib/ngram_index.py                            | 229 +++++++++
 lib/run.py                                    | 223 +++++++++
 lib/torch_generator.py                        |  50 ++
 lib/utils.py                                  | 220 +++++++++
 lib/utils_geo.py                              | 444 ++++++++++++++++++
 lib/word_index.py                             | 180 +++++++
 .../toponym_combination_embedding.json        |  20 +
 .../toponym_combination_embedding_v2.json     |  20 +
 .../toponym_combination_embedding_v3.json     |  20 +
 predict_toponym_coordinates.py                | 133 ++++++
 region_model.py                               | 199 ++++++++
 requirements.txt                              |  27 ++
 run_multiple_configurations.py                |  22 +
 scripts/embeddingngram.py                     |  59 +++
 scripts/generate_cooc_geocoding_dataset.py    |  41 ++
 scripts/get_all_adjacency_rel.py              |  88 ++++
 scripts/get_cooccurrence.py                   |  40 ++
 scripts/gethealpix.py                         |  32 ++
 scripts/randoludo.py                          |  50 ++
 templates/pair_topo.html                      |  55 +++
 templates/skeleton.html                       | 116 +++++
 templates/text.html                           |  60 +++
 train_bert_geocoder.py                        | 353 ++++++++++++++
 train_geocoder.py                             | 401 ++++++++++++++++
 train_geocoder_v2.py                          | 242 ++++++++++
 train_test_split_cooccurrence_data.py         |  68 +++
 train_test_split_geonames.py                  |  66 +++
 46 files changed, 5290 insertions(+)
 create mode 100644 LICENSE
 create mode 100644 desamb_eval.py
 create mode 100644 desamb_eval_runs.sh
 create mode 100644 documentation/imgs/LSTM_archv2.png
 create mode 100644 generate_dataset.py
 create mode 100644 geocoder_app.py
 create mode 100644 helpers.py
 create mode 100644 lib/__init__.py
 create mode 100644 lib/custom_layer.py
 create mode 100644 lib/data_generator.py
 create mode 100644 lib/data_generatorv3.py
 create mode 100644 lib/datageneratorv4.py
 create mode 100644 lib/geocoder/__init__.py
 create mode 100644 lib/geocoder/bert_geocoder.py
 create mode 100644 lib/geocoder/heuristics.py
 create mode 100644 lib/geocoder/our_geocoder.py
 create mode 100644 lib/geocoder/svm_geocoder.py
 create mode 100644 lib/metrics.py
 create mode 100644 lib/ngram_index.py
 create mode 100644 lib/run.py
 create mode 100644 lib/torch_generator.py
 create mode 100644 lib/utils.py
 create mode 100644 lib/utils_geo.py
 create mode 100644 lib/word_index.py
 create mode 100644 parser_config/toponym_combination_embedding.json
 create mode 100644 parser_config/toponym_combination_embedding_v2.json
 create mode 100644 parser_config/toponym_combination_embedding_v3.json
 create mode 100644 predict_toponym_coordinates.py
 create mode 100644 region_model.py
 create mode 100644 requirements.txt
 create mode 100644 run_multiple_configurations.py
 create mode 100644 scripts/embeddingngram.py
 create mode 100644 scripts/generate_cooc_geocoding_dataset.py
 create mode 100644 scripts/get_all_adjacency_rel.py
 create mode 100644 scripts/get_cooccurrence.py
 create mode 100644 scripts/gethealpix.py
 create mode 100644 scripts/randoludo.py
 create mode 100644 templates/pair_topo.html
 create mode 100644 templates/skeleton.html
 create mode 100644 templates/text.html
 create mode 100644 train_bert_geocoder.py
 create mode 100644 train_geocoder.py
 create mode 100644 train_geocoder_v2.py
 create mode 100644 train_test_split_cooccurrence_data.py
 create mode 100644 train_test_split_geonames.py

diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..ff31b15
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 Jacques Fize, Ludovic Moncla and Bruno Martins
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
index e69de29..f5c5288 100644
--- a/README.md
+++ b/README.md
@@ -0,0 +1,194 @@
+
+
+This repository contains the code for *"Using a deep neural network for toponym geocoding based on co-occurrences and spatial relations"*. In a nutshell, we propose to geocode place names using the less information available (two place names, one to geocode and the second used as context) and rely on deep learning network architecture.
+
+
+
+<hr>
+
+# Model architecture
+
+The model is neural network. The first model is illustrated in the Figure 1. In a nutshell, the model aims to predict coordinates (output) from two place names. The first place name is the one we want to geocode and the second place name is used as context.
+
+In a experiment (presented [here](https://jacobe2169.github.io/mapthetoponymsim/)), we found and assume that specific toponym affixes (suffix or prefix for example) are bound to certain geographic area. Based on this assumption, we decide to use n-gram sequence representation of input toponyms. For example, Paris will be transformed to Par,ari,ris.
+
+<div style="text-align:center">
+<img src="documentation/imgs/LSTM_archv2.png"/>
+<p><strong>Figure 1</strong> : General workflow</p>
+</div>
+
+<hr>
+
+
+# Setup environnement
+
+- Python3.6+
+- Os free**
+
+***It is strongly advised to used Anaconda in a Windows environnement!*
+
+## Install dependencies
+
+    pip3 install -r requirements.txt
+
+For Anaconda users
+
+    while read requirement; do conda install --yes $requirement; done < requirements.txt
+
+
+
+<hr>
+
+# Get Started
+
+## Get pre-trained model
+
+Pre-trained model are available :
+
+| Geographic Area | Description                                                             | URL                                                                      |
+|-----------|-------------------------------------------------------------------------|--------------------------------------------------------------------------|
+| FR        | Model trained on the France populated places and area                   | https://projet.liris.cnrs.fr/hextgeo/files/trained_models/FR_MODEL_2.zip |
+| GB        | Model trained on the England populated places and area                  | https://projet.liris.cnrs.fr/hextgeo/files/trained_models/GB_MODEL_2.zip |
+| US        | Model trained on the United States of America populated places and area | https://projet.liris.cnrs.fr/hextgeo/files/trained_models/US_MODEL_2.zip |
+
+## Load and use the model
+
+First thing is to import the dedicated module and load pre-trained model file. Here, we'll be using the France model.
+
+```python
+from lib.geocoder.our_geocoder import Geocoder
+g = Geocoder("FR_MODEL_2/FR.txt_100_4_100__A_C.h5","FR_MODEL_2/FR.txt_100_4_100__A_C_index")
+
+```
+
+To geocode a pair of toponym use the `model.get_coord` method:
+```python
+print(g.get_coord("Paris","France"))
+#(2.7003836631774902, 41.24913454055786) #lon,lat
+```
+
+To reduce computation time, use the `model.get_coords` to geocode multiple pairs of toponyms:
+
+```python
+print(g.get_coords(["Paris","Paris"],["Cherbourg","Montpellier"]))
+#(array([2.6039734, 3.480011 ], dtype=float32),
+# array([48.27507 , 48.075943], dtype=float32))
+
+```
+
+<hr>
+
+# Train your own model
+
+We propose an implementation of the model illustrated in Figure 1 and a second based on the same input but using BERT pre-trained model.
+
+
+## Prepare data
+
+The data preparation is divided into three steps. First, we retrieve required data from Geonames. Second, we retrieve place names co-occurrences from Wikipedia. Finally, we generate the datasets to train the model.
+
+### Geonames data
+ 1. Download the Geonames data use to train the network [here](download.geonames.org/export/dump/)
+ 2. download the hierarchy data [here](http://download.geonames.org/export/dump/hierarchy.zip)
+ 3. unzip both file in the directory of your choice
+
+### Cooccurence data
+
+ 5. First, you must download the Wikipedia corpus from which you want to extract co-occurrences : [English Wikipedia Corpus](https://dumps.wikimedia.org/enwiki/20200201/enwiki-20200201-pages-articles.xml.bz2)
+ 6. Parse the corpus with Gensim script using the following command : `python3 -m gensim.scripts.segment_wiki -i -f <wikicorpus> -o <1stoutputname>.json.gz`
+ 7. Build a page of interest file that contains a list of Wikipedia pages. The file must be a csv with the following column : title,latitude,longitude.<br> You can find [here](https://projet.liris.cnrs.fr/hextgeo/files/place_en_fr_page_clean.csv) a page of interest file that contains places that appears in both FR and EN wikipedia.
+ 8. Then using and index that contains pages of interest run the command : `python3 script/get_cooccurrence.py <page_of_interest_file> <2noutputname> -c <1stoutputname>.json.gz`
+
+### Generate dataset
+
+Use the following command to generate the datasets for training your model.
+
+    python3 generate_dataset.py <geonames_dataset> <wikipedia_dataset> <geonames_hierarchy_data>
+
+
+| Parameter       | Description                                                                                                                                          |
+|-----------------|------------------------------------------------------------------------------------------------------------------------------------------------------|
+| --cooc-sampling | Number of cooccurrence sampled for each place in the cooccurrence dataset                                                                            |
+| --adj-sampling  | Number of adjacent relation extracted for each place in a Healpix cell                                                                               |
+| --adj-nside     | Healpix resolution where places within are considered adjacent                                                                                       |
+| --split-nside   | Size of the zone where the train/test split are done                                                                                                 |
+| --split-method  | [per_pair\|per_entity] Split each dataset based on places (place cannot exists in both train and test) or pairs(place can appears in train and test) |
+
+### If you're in a hurry
+
+French Geonames, French Wikipedia cooccurence data, and their train/test splits datasets can be found here : [https://projet.liris.cnrs.fr/hextgeo/files/](https://projet.liris.cnrs.fr/hextgeo/files/)
+
+
+## Our model
+
+To train the first model use the following command :
+
+    python3 train_geocoder_v2.py <dataset_name> <inclusion_dataset> <adjacent_dataset> <cooccurrence_dataset> [-i | -a | -w ]+ [optional args]
+
+| Parameter             | Description                                                                     |
+|-----------------------|---------------------------------------------------------------------------------|
+| -i,--inclusion        | Use inclusion relationships to train the network                                |
+| -a,--adjacency        | Use adjacency relationships to train the network                                |
+| -w,--wikipedia-coo    | Use Wikipedia place co-occurrences to train the network                         |
+| -n,--ngram-size       | ngram size                                                                      |
+| -t,--tolerance-value  | K-value in the computation of the accuracy@k (K unit is kilometer)                                    |
+| -e,--epochs           | number of epochs                                                                |
+| -d,--dimension        | size of the ngram embeddings                                                    |
+| --admin_code_1        | (Optional) If you wish to train the network on a specific region             |
+
+
+<hr>
+
+# [In Progress] BERT model
+In the recent years, BERT architecture proposed by Google researches enables to outperform state-of-art methods for differents tasks in NLP (POS, NER, Classification). To verify if BERT embeddings would permit to increase the performance of our approach, we code a script to use bert with our data. In our previous model, the model returned two values each on between [0,1]. Using Bert, the task has shifted to classification (softmax) where each class correspond to a cell on the glob. We use the hierarchical projection model : Healpix. Other projections model like S2geometry can be considered : https://s2geometry.io/about/overview.
+
+In order, to run this model training, run the `train_bert_geocoder.py` script :
+
+    python3 train_bert_geocoder.py \
+    <train_dataset>\
+    <test_dataset>\
+    <output_dir>\
+    [--batch_size BATCH_SIZE | --epochs EPOCHS]
+
+The train and test dataset are table data composed of two columns: sentence and label.
+
+### Pretrained-model
+
+Pretrained model can be found [here](https://projet.liris.cnrs.fr/hextgeo/files/trained_models/BERT_MODELS/)
+
+### Use BERT model 
+
+```python
+from lib.geocoder.bert_geocoder import BertGeocoder
+geocoder = BertGeocoder(<bert_model_dir>,<label_healpix_file>)
+geocoder.geocode(<toponyms>,<context,toponyms>)
+```
+
+<hr>
+
+# Train multiple model with different parameters
+
+We built a tiny module that allows to run the network training using different parameters. To do that use the GridSearchModel class in `lib.run`. You can find
+an example in the following code:
+
+```python
+from lib.run import GridSearchModel
+from collections import OrderedDict
+
+grid = GridSearchModel(\
+    "python3 train_geocoder_v2.py",
+    **OrderedDict({ # We use an OrderedDict since the order of parameters is important
+    "rel":["-i","-a","-c"],
+    "-n":[4],
+    "geoname_fn":"../data/geonamesData/US_FR.txt".split(),
+    "hierarchy_fn":"../data/geonamesData/hierarchy.txt".split(),
+    "store_true":["rel"]
+    }.items()))
+grid.run()
+```
+
+# Authors and Acknowledgment
+
+Proposed by **Jacques Fize**, **Ludovic Moncla** and **Bruno Martins**
+
+This research is supported by an IDEXLYON project of the University of Lyon within the framework of the Investments for the Future Program (ANR-16-IDEX-0005). Bruno Martins was supported by the Fundação para a Ciência e a Tecnologia (FCT), through the project grants PTDC/CCI-CIF/32607/2017 CMIMU) and UIBD/50021/2020 (INESC-ID multi-annual funding).
\ No newline at end of file
diff --git a/desamb_eval.py b/desamb_eval.py
new file mode 100644
index 0000000..8fcd5fe
--- /dev/null
+++ b/desamb_eval.py
@@ -0,0 +1,66 @@
+from glob import glob
+import json
+
+import argparse
+import logging
+
+import pandas as pd
+
+
+
+parser = argparse.ArgumentParser()
+parser.add_argument("eval_dataset")
+parser.add_argument("models_directory")
+parser.add_argument("-g","--gpu",action="store_true")
+args = parser.parse_args()#("-g ../data/geocoding_evaluation/fr_cooc_test.csv outputs/FR_RESULT".split())
+
+
+if not args.gpu:
+    import os
+    os.environ['CUDA_VISIBLE_DEVICES'] = '-1' # No need for GPU
+
+
+from predict_toponym_coordinates import Geocoder
+from lib.utils_geo import haversine_pd
+
+logging.getLogger("tensorflow").setLevel(logging.CRITICAL)
+logging.getLogger("tensorflow_hub").setLevel(logging.CRITICAL)
+
+EVAL_DATASET_FN= args.eval_dataset#"./test_dataset_ambiguity.csv"
+
+
+def eval_model(eval_dataset_fn,model_fn,model_index_fn):
+    print("Dataset -- {0} -- Model -- {1}".format(\
+        eval_dataset_fn.split("/")[-1],
+        model_fn.split("/")[-1]))
+    df = pd.read_csv(eval_dataset_fn)
+    geocoder = Geocoder(model_fn,model_index_fn)
+    lon,lat = geocoder.get_coords(df.name1.values,df.name2.values)                  
+    lon,lat = geocoder.wgs_coord(lon,lat)
+
+    df["p_longitude"] = lon
+    df["p_latitude"] = lat
+
+    df["dist"] = haversine_pd(df.longitude,df.latitude,df.p_longitude,df.p_latitude)
+
+    print("100km",(df.dist<100).sum()/len(df))
+    print("50km",(df.dist<50).sum()/len(df))
+    print("20km",(df.dist<20).sum()/len(df))
+    return df
+
+prefixes = [x.rstrip(".h5") for x in glob(args.models_directory+"/*.h5")]
+
+final_output = []
+for prefix in prefixes:
+    try:
+        df = eval_model(EVAL_DATASET_FN,prefix + ".h5",prefix + "_index")
+        data = json.load(open(prefix+".json"))
+        data["acccuracy@100km"] = (df.dist<100).sum()/len(df)
+        data["acccuracy@50km"] = (df.dist<50).sum()/len(df)
+        data["acccuracy@25km"] = (df.dist<25).sum()/len(df)
+        final_output.append(data)
+    except:
+        print("BUMP!")
+    
+
+pd.DataFrame(final_output).to_csv("{0}_RESULT.csv".format(EVAL_DATASET_FN.rstrip(".csv")))
\ No newline at end of file
diff --git a/desamb_eval_runs.sh b/desamb_eval_runs.sh
new file mode 100644
index 0000000..20eb682
--- /dev/null
+++ b/desamb_eval_runs.sh
@@ -0,0 +1,3 @@
+python3 desamb_eval.py -g ../data/geocoding_evaluation/fr_dataset_ambiguity_sample50percent.csv outputs/FR_RESULT 
+python3 desamb_eval.py -g ../data/geocoding_evaluation/us_fr_cooc_test.csv outputs/USFR_WORD
+python3 desamb_eval.py -g ../data/geocoding_evaluation/us_fr_dataset_ambiguity.csv outputs/USFR_WORD
diff --git a/documentation/imgs/LSTM_archv2.png b/documentation/imgs/LSTM_archv2.png
new file mode 100644
index 0000000000000000000000000000000000000000..794909f8d568f9f153a774bba997d97f9d6a89be
GIT binary patch
literal 187798
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%0AgA(3Xp~NHKZ(S)Qp9V)fSweog
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
Ld<XSN`0xJ#fe_t*

literal 0
HcmV?d00001

diff --git a/generate_dataset.py b/generate_dataset.py
new file mode 100644
index 0000000..788fe37
--- /dev/null
+++ b/generate_dataset.py
@@ -0,0 +1,149 @@
+import argparse
+
+import pandas as pd
+import numpy as np
+
+from helpers import read_geonames
+from lib.utils_geo import latlon2healpix
+
+from tqdm import tqdm
+from sklearn.model_selection import train_test_split
+
+parser = argparse.ArgumentParser()
+
+parser.add_argument("geonames_dataset")
+parser.add_argument("wikipedia_dataset")
+parser.add_argument("geonames_hierarchy_data")
+parser.add_argument("--cooc-sampling", default=4, type=int)
+parser.add_argument("--adj-sampling", default=4, type=int)
+parser.add_argument("--adj-nside", default=128, type=int)
+parser.add_argument("--split-nside", default=128, type=int)
+parser.add_argument("--split-method", default="per_pair", type=str, choices="per_pair per_place".split())
+
+args = parser.parse_args()#("../data/geonamesData/FR.txt ../data/wikipedia/cooccurrence_FR.txt ../data/geonamesData/hierarchy.txt".split())
+
+PREFIX = args.geonames_dataset.split("/")[-1].split(".")[0]  # Ouch !
+PREFIX = PREFIX + "_" + args.split_method
+
+#  LOAD DATA
+geonames_data = read_geonames(args.geonames_dataset)
+wikipedia_data = pd.read_csv(args.wikipedia_dataset, sep="\t")
+geonames_hierarchy_data = pd.read_csv(args.geonames_hierarchy_data, sep="\t", header=None,
+                                      names="parentId,childId,type".split(",")).fillna("")
+
+# Add IDs for the Wikipedia Cooc Dataset
+min_id = geonames_data.geonameid.max() + 1
+max_id = min_id + len(wikipedia_data)
+wikipedia_data["geonameid"] = np.arange(min_id, max_id)
+
+#  Healpix cell id computation
+geonames_data["adj_split"] = geonames_data.apply(lambda x: latlon2healpix(x.latitude, x.longitude, args.adj_nside),
+                                                 axis=1)
+
+
+def get_adjacent_pairs(dataframe, sampling_nb):
+    """
+    Return pairs of place toponyms that are adjacent geographicaly.
+    Parameters
+    ----------
+    dataframe : pandas.DataFrame
+        geonames data
+    sampling_nb : int
+        number of adjacent place drawn
+
+    Returns
+    -------
+    list of list
+        [[ID,place toponym,adjacent place toponym, latitude, longitude],...]
+    """
+    new_pairs = []
+    for ix, row in tqdm(dataframe.iterrows(), total=len(dataframe), desc="Get Adjacent Toponym Pairs"):
+        healpix_cell = row.adj_split
+        topo_prin = row["name"]
+        lat, lon = row.latitude, row.longitude
+        within_cell = dataframe[dataframe.adj_split == healpix_cell]["name"].values
+        selected = np.random.choice(within_cell, sampling_nb)
+        new_pairs.extend([[row.geonameid, topo_prin, sel, lat, lon] for sel in selected])
+    return new_pairs
+
+
+def get_cooccurrence_pairs(dataframe, sampling_nb):
+    """
+    Return pairs of place toponyms where toponyms appears in a same wikipedia page
+    Parameters
+    ----------
+    dataframe : pandas.DataFrame
+        wikipedia cooccurrence data
+    sampling_nb : int
+        number of adjacent place drawn
+
+    Returns
+    -------
+    list of list
+        [[ID,place toponym,adjacent place toponym, latitude, longitude],...]
+    """
+    new_pairs = []
+    dataframe["interlinks"] = dataframe.interlinks.apply(lambda x: np.random.choice(x.split("|"), sampling_nb))
+    for ix, row in tqdm(dataframe.iterrows(), total=len(dataframe), desc="Get Cooccurrent Toponym Pairs"):
+        topo_prin = row.title
+        lat, lon = row.latitude, row.longitude
+        new_pairs.extend([[row.geonameid, topo_prin, sel, lat, lon] for sel in row["interlinks"]])
+    return new_pairs
+
+
+def get_inclusion_pairs(geoname_df, hierarchy_df):
+    """
+    Return pairs of place toponyms that share an inclusion relationship. Ex. Paris, France (Paris geometry is included in France geometry)
+    Parameters
+    ----------
+    dataframe : pandas.DataFrame
+        geonames data
+    hierarchy_df : pandas.DataFrame
+        geonames hierarchy data
+
+    Returns
+    -------
+    list of list
+        [[ID,place toponym,adjacent place toponym, latitude, longitude],...]
+    """
+    geonamesIDS = set(geoname_df.geonameid.values)
+    id_label = dict(geonames_data["geonameid name".split()].values)
+    id_lat = dict(geonames_data["geonameid latitude".split()].values)
+    id_lon = dict(geonames_data["geonameid longitude".split()].values)
+    filter_mask = (hierarchy_df.childId.isin(geonamesIDS) & hierarchy_df.parentId.isin(geonamesIDS))
+    pairs_id = hierarchy_df[filter_mask]["childId parentId".split()].values.tolist()
+    return [[p[0], id_label[p[0]], id_label[p[1]], id_lat[p[0]], id_lon[p[0]]] for p in pairs_id]
+
+# EXTRACT PAIRS FROM INPUT DATA
+cooc_pairs = pd.DataFrame(get_cooccurrence_pairs(wikipedia_data, args.cooc_sampling),
+                          columns="ID toponym toponym_context latitude longitude".split())
+adjacent_pairs = pd.DataFrame(get_adjacent_pairs(geonames_data, args.adj_sampling),
+                              columns="ID toponym toponym_context latitude longitude".split())
+inclusion_pairs = pd.DataFrame(get_inclusion_pairs(geonames_data, geonames_hierarchy_data),
+                               columns="ID toponym toponym_context latitude longitude".split())
+
+# FOR EACH PAIR, COMPUTE THE HEALPIX CELL ID FOR EACH COORDINATES ASSOCIATED
+cooc_pairs["hp_split"] = cooc_pairs.apply(lambda x: latlon2healpix(x.latitude, x.longitude, args.split_nside), axis=1)
+adjacent_pairs["hp_split"] = adjacent_pairs.apply(lambda x: latlon2healpix(x.latitude, x.longitude, args.split_nside),
+                                                  axis=1)
+inclusion_pairs["hp_split"] = inclusion_pairs.apply(lambda x: latlon2healpix(x.latitude, x.longitude, args.split_nside),
+                                                    axis=1)
+
+# SPLIT DATASETS BETWEEN TRAIN AND TEST GEOGRAPHICALY
+field = "hp_split"
+if args.split_method == "per_place":
+    field = "ID"
+
+for df in [cooc_pairs, adjacent_pairs]:
+    df_train, _ = train_test_split(df, stratify=df[field].values, test_size=0.33)
+    df["split"] = "test"
+    df.loc[df_train.index.values, "split"] = "train"
+
+inc_train, _ = train_test_split(inclusion_pairs, test_size=0.33)
+inclusion_pairs["split"] = "test"
+inclusion_pairs.loc[inc_train.index.values, "split"] = "train"
+
+# SAVE DATA
+inclusion_pairs.to_csv("{0}_inclusion.csv".format(PREFIX), sep="\t")
+adjacent_pairs.to_csv("{0}_adjacent.csv".format(PREFIX), sep="\t")
+cooc_pairs.to_csv("{0}_cooc.csv".format(PREFIX), sep="\t")
diff --git a/geocoder_app.py b/geocoder_app.py
new file mode 100644
index 0000000..81d4a1e
--- /dev/null
+++ b/geocoder_app.py
@@ -0,0 +1,93 @@
+from flask import Flask, escape, request, render_template,jsonify,Markup, redirect, url_for
+from lib.geocoder.our_geocoder import Geocoder,TextGeocoder
+from lib.geocoder.heuristics import *
+
+import spacy
+
+app = Flask(__name__)
+
+dict_model = {
+    "FR_AIC":("./outputs/FR_MODEL_2/FR.txt_100_4_100__A_I_C.h5","./outputs/FR_MODEL_2/FR.txt_100_4_100__A_I_C_index"),
+    "FR_C":("./outputs/FR_MODEL_2/FR.txt_100_4_100__C.h5","./outputs/FR_MODEL_2/FR.txt_100_4_100__C_index"),
+    "FR_AC":("./outputs/FR_MODEL_2/FR.txt_100_4_100__A_C.h5","./outputs/FR_MODEL_2/FR.txt_100_4_100__A_C_index"),
+    "FR_IC":("./outputs/FR_MODEL_2/FR.txt_100_4_100__I_C.h5","./outputs/FR_MODEL_2/FR.txt_100_4_100__I_C_index"),
+
+    "GB_AIC":("./outputs/GB_MODEL_2/GB.txt_100_4_100__A_I_C.h5","./outputs/GB_MODEL_2/GB.txt_100_4_100__A_I_C_index"),
+    "GB_C":("./outputs/GB_MODEL_2/GB.txt_100_4_100__C.h5","./outputs/GB_MODEL_2/GB.txt_100_4_100__C_index"),
+    "GB_AC":("./outputs/GB_MODEL_2/GB.txt_100_4_100__A_C.h5","./outputs/GB_MODEL_2/GB.txt_100_4_100__A_C_index"),
+    "GB_IC":("./outputs/GB_MODEL_2/GB.txt_100_4_100__I_C.h5","./outputs/GB_MODEL_2/GB.txt_100_4_100__I_C_index")
+    ,"FR_IGN":("./outputs/IGN/onlyAdjac/IGN_4_100_A_C.h5","./outputs/IGN/onlyAdjac/IGN_4_100_A_C_index")
+}
+
+MODEL = "FR_AC"
+LANG = "fr"
+NER = "spacy"
+
+heuristic_func = heuristic_cluster
+
+geocoder = Geocoder(*dict_model[MODEL])
+g_t = TextGeocoder(geocoder,NER,LANG,heuristic_func)
+
+
+@app.route('/')
+def home():
+    toponym = request.args.get("top", "")
+    c_toponym = request.args.get("c_top", "")
+    msg = request.args.get("msg", "")
+    msg_code = request.args.get("msg_code", "info")
+    if toponym and c_toponym:
+        lon,lat = geocoder.get_coords([toponym],[c_toponym])
+        lon,lat = lon[0],lat[0]
+        print(lon,lat)
+        return  render_template("pair_topo.html",lat=lat,lon=lon,title="Toponyms Pair Geocoder",dict_model=dict_model,msg_code=msg_code)
+    else:
+        return  render_template("pair_topo.html",title="Toponyms Pair Geocoder",dict_model=dict_model,msg_code=msg_code)
+
+@app.route('/text')
+def text():
+    return render_template("text.html",title="Text Geocoder",dict_model=dict_model)
+
+@app.route('/geocode', methods=['POST', 'GET'])
+def geocode():
+    if request.method == 'POST':
+        text = request.form["text"]
+        
+        results = g_t.geocode(g_t.extract_geo_entities(text))
+        
+        html_, pos_ = "", 0
+        for item in results:
+            start,end = item["start"], item["end"]
+            html_ = html_ + text[pos_:start] + "<span class=\"annotation place\">{0}</span>".format(text[start:end])
+            pos_ = end
+        
+        place_coords = {}
+        for r in results:
+            if r["text"] in place_coords:
+                continue
+            place_coords[r["text"]]={"lat":float(r["coord"]["lat"]),"lon":float(r["coord"]["lon"])}
+        return render_template("text.html",title="Text Geocoder",data={"type":"success","output":Markup(html_),"place_coords":place_coords},dict_model=dict_model)
+
+
+@app.route("/loadmodel/<model_id>")
+def loadModel(model_id):
+    global geocoder,g_t,LANG
+    if not model_id in dict_model:
+        return redirect(url_for(".home",msg="An error happend when loading the model \"{0}\"!".format(model_id),msg_code="danger"))
+    else: 
+        geocoder = Geocoder(*dict_model[model_id])
+        g_t = TextGeocoder(geocoder,NER,LANG,heuristic_func)
+        return redirect(url_for(".home",msg="Model \"{0}\" was loaded successfuly!".format(model_id),msg_code="success"))
+
+@app.route("/loadlang/<lang>")
+def loadLang(lang):
+    global geocoder,g_t,LANG
+    try:
+        g_t = TextGeocoder(geocoder,NER,lang,heuristic_func)
+        LANG = lang
+        return redirect(url_for(".home",msg="Language is now set to \"{0}\"!".format(LANG),msg_code="success"))
+    except:
+        return redirect(url_for(".home",msg="\"{}\" language is not available!".format(lang),msg_code="danger"))
+        
+
+if __name__ == "__main__":
+    app.run(host="0.0.0.0",debug=True)
\ No newline at end of file
diff --git a/helpers.py b/helpers.py
new file mode 100644
index 0000000..b093f62
--- /dev/null
+++ b/helpers.py
@@ -0,0 +1,201 @@
+import os
+import time
+import re
+
+import numpy as np
+import pandas as pd
+
+
+def read_geonames(file):
+    """
+    Return a dataframe that contains Geonames data.
+    
+    Parameters
+    ----------
+    file : str
+        path of the Geonames Csv file
+    
+    Returns
+    -------
+    pd.DataFrame
+        geonames data
+    """
+    dtypes_dict = {
+        0: int,  # geonameid
+        1: str,  # name
+        2: str,  # asciiname
+        3: str,  # alternatenames
+        4: float,  # latitude
+        5: float,  # longitude
+        6: str,  # feature class
+        7: str,  # feature code
+        8: str,  # country code
+        9: str,  # cc2
+        10: str,  # admin1 code
+        11: str,  # admin2 code
+        12: str,  # admin3 code
+        13: str,  # admin4 code
+        14: int,  # population
+        15: str,  # elevation
+        16: int,  # dem (digital elevation model)
+        17: str,  # timezone
+        18: str,  # modification date yyyy-MM-dd
+    }
+    rename_cols = {
+        0: "geonameid",  # geonameid
+        1: "name",  # name
+        2: "asciiname",  # asciiname
+        3: "alternatenames",  # alternatenames
+        4: "latitude",  # latitude
+        5: "longitude",  # longitude
+        6: "feature_class",  # feature class
+        7: "feature_code",  # feature code
+        8: "country_code",  # country code
+        9: "cc2",  # cc2
+        10: "admin1_code",  # admin1 code
+        11: "admin2_code",  # admin2 code
+        12: "admin3_code",  # admin3 code
+        13: "admin4_code",  # admin4 code
+        14: "population",  # population
+        15: "elevation",  # elevation
+        16: "dem",  # dem (digital elevation model)
+        17: "timezone",  # timezone
+        18: "modification_date",  # modification date yyyy-MM-dd
+    }
+    data = pd.read_csv(
+        file,
+        sep="\t",
+        header=None,
+        quoting=3,
+        dtype=dtypes_dict,
+        na_values="",
+        keep_default_na=False,
+        error_bad_lines=False,
+    )
+    data.rename(columns=rename_cols, inplace=True)
+    return data
+
+
+def parse_title_wiki(title_wiki):
+    """
+    Parse Wikipedia title
+    
+    Parameters
+    ----------
+    title_wiki : str
+        wikipedia title
+    
+    Returns
+    -------
+    str
+        parsed wikipedia title
+    """
+    return re.sub("\(.*\)", "", str(title_wiki)).strip().lower()
+
+
+def _split(lst, n, complete_chunk_value):
+    """
+    Split a list into chunk of n-size.
+    
+    Parameters
+    ----------
+    lst : list
+        input list
+    n : int
+        chunk size
+    complete_chunk_value : object
+        if last chunk size not equal to n, this value is used to complete it
+    
+    Returns
+    -------
+    list
+        chunked list
+    """
+    chunks = [lst[i : i + n] for i in range(0, len(lst), n)]
+    if not chunks:
+        return chunks
+    if len(chunks[-1]) != n:
+        chunks[-1].extend([complete_chunk_value] * (n - len(chunks[-1])))
+    return np.array(chunks)
+
+
+class Chronometer:
+    def __init__(self):
+        self.__task_begin_timestamp = {}
+
+    def start(self, task_name):
+        """
+        Start a new task chronometer
+        
+        Parameters
+        ----------
+        task_name : str
+            task id
+        
+        Raises
+        ------
+        ValueError
+            if a running task already exists with that name
+        """
+        if task_name in self.__task_begin_timestamp:
+            raise ValueError(
+                "A running task exists with the name {0}!".format(task_name)
+            )
+        self.__task_begin_timestamp[task_name] = time.time()
+
+    def stop(self, task_name):
+        """
+        Stop and return the duration of the task
+        
+        Parameters
+        ----------
+        task_name : str
+            task id
+        
+        Returns
+        -------
+        float
+            duration of the task in seconds
+        
+        Raises
+        ------
+        ValueError
+            if no task exist with the id `task_name`
+        """
+        if not task_name in self.__task_begin_timestamp:
+            raise ValueError("The {0} task does not exist!".format(task_name))
+        
+        duration = time.time() - self.__task_begin_timestamp[task_name]
+        del self.__task_begin_timestamp[task_name]
+
+        return duration
+
+
+from keras.callbacks import Callback
+import time
+
+class EpochTimer(Callback):
+    def __init__(self,log_filename):
+        self.epoch = 0
+        self.timer = time.time()
+        self.output = open(log_filename,'w')
+        self.output.write("{0},{1}\n".format("Epoch","Execution Time"))
+        self.output.flush()
+
+    def on_epoch_begin(self,epoch, logs={}):
+        self.timer = time.time()
+
+    def on_epoch_end(self, epoch, logs=None):
+        end_time = time.time() - self.timer
+        self.output.write("{0},{1}\n".format(self.epoch,end_time))
+        self.output.flush()
+        self.epoch += 1 
+
+if __name__ == "__main__":
+    chrono = Chronometer()
+    chrono.start("test")
+    chrono.start("test2")
+    time.sleep(3)
+    print(chrono.stop("test"))
+    time.sleep(3)
+    print(chrono.stop("test2"))
diff --git a/lib/__init__.py b/lib/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/lib/custom_layer.py b/lib/custom_layer.py
new file mode 100644
index 0000000..7204573
--- /dev/null
+++ b/lib/custom_layer.py
@@ -0,0 +1,31 @@
+# This Layer implementation comes from 
+
+import keras
+from keras import backend as K
+from keras.engine.topology import Layer
+
+
+
+class Pentanh(Layer):
+    """
+    Implementation for the "Penalized Tanh" activation function presented in :
+        Xu, Bing, Ruitong Huang, et Mu Li. « Revise saturated activation functions ». arXiv preprint arXiv:1602.05980, 2016.
+    
+    Code Author: Ana Bárbara Cardoso https://github.com/barbarainacioc/toponym-resolution/blob/master/system/nn_model.py
+    """
+
+    def __init__(self, **kwargs):
+        super(Pentanh, self).__init__(**kwargs)
+        self.supports_masking = True
+        self.__name__ = 'pentanh'
+
+    def call(self, inputs):
+        return K.switch(K.greater(inputs,0), K.tanh(inputs), 0.25 * K.tanh(inputs))
+
+    def get_config(self):
+        return super(Pentanh, self).get_config()
+
+    def compute_output_shape(self, input_shape):
+        return input_shape
+
+keras.utils.generic_utils.get_custom_objects().update({'pentanh': Pentanh()})
\ No newline at end of file
diff --git a/lib/data_generator.py b/lib/data_generator.py
new file mode 100644
index 0000000..7eae387
--- /dev/null
+++ b/lib/data_generator.py
@@ -0,0 +1,347 @@
+import os
+from gzip import GzipFile
+
+import keras
+from keras.utils import to_categorical
+import numpy as np
+import pandas as pd
+
+from .utils_geo import zero_one_encoding
+
+from helpers import parse_title_wiki,read_geonames
+from gensim.models.keyedvectors import KeyedVectors
+
+from sklearn.preprocessing import LabelEncoder
+
+
+def wc_l(filename,gzip=True):
+    lc = 0
+    if not gzip:
+        f = open(filename)
+    if gzip:
+        f = GzipFile(filename)
+    while f.readline():
+        lc += 1 
+    f.close()       
+    return lc
+
+class SamplingProbabilities:
+    def __init__(self):
+        self.count = {}
+    
+    def get_probs(self,item):
+        if not item in self.count:
+            self.count[item] = 0
+        self.count[item]+=1
+        return 1/self.count[item]
+    def __call__(self,a):
+        return self.get_probs(a)
+        
+
+class DataSource(object):
+    def __init__(self,name,input_filename):
+        self.name = name
+        assert os.path.exists(input_filename)
+        self.input_filename = input_filename
+        self.len = 0
+
+        self.is_there_healpix = False
+
+    def __next__(self):
+        raise NotImplementedError()
+
+    def __iter__(self):
+        return self
+    
+    def __len__(self):
+        return self.len
+    
+    def __reset__(self):
+        raise NotImplementedError()
+
+    def isOver(self):
+        raise NotImplementedError()
+
+class Adjacency(DataSource):
+    def __init__(self,filename,geonames_filename,sampling=3,len_=None,gzip=True):
+        DataSource.__init__(self,"Adjacency SRC",filename)
+
+        assert os.path.exists(geonames_filename)
+        self.geonames_data_dict = {row.geonameid:row.name for row in read_geonames(geonames_filename).itertuples()}
+        
+        self.gzip = gzip
+        if not self.gzip:
+            self.data_src = open(self.input_filename,'rb')
+        else:
+            self.data_src = GzipFile(self.input_filename,'rb')
+
+        if len_:
+            self.len = len_*sampling
+        else:
+            self.len = wc_l(filename,gzip=gzip)
+        
+        self.data_src.readline() # header line
+
+        self.sampling = sampling
+        if self.sampling:
+            self.probs_storage = SamplingProbabilities() 
+
+        self.topo = None
+        self.context_topo_context = []
+        self.curr_probs = None
+        self.lat, self.lon = None, None
+
+
+        self.i = 0
+        self.is_over = False
+    
+    def __next__(self):
+        if  self.i >= len(self.context_topo_context):
+            line = self.data_src.readline()
+            if not line:
+                self.is_over = True
+                raise StopIteration
+            line = line.decode("utf-8").rstrip("\n")
+            _,geonameid, adjacent_geoname_id,latitude,longitude = tuple(line.split(","))
+
+            self.topo = int(geonameid)
+            self.context_topo_context = [int(x) for x in adjacent_geoname_id.split("|")]
+            if self.sampling:
+                self.curr_probs = [self.probs_storage(x) for x in self.context_topo_context]
+                self.context_topo_context = np.random.choice(self.context_topo_context,self.sampling,self.curr_probs)
+            self.lat, self.lon = float(latitude),float(longitude)
+
+            self.i = 0
+        
+        self.i += 1
+        return (self.geonames_data_dict[self.topo],
+        self.geonames_data_dict[self.context_topo_context[self.i-1]],
+        self.lat,self.lon)
+
+    def __reset__(self):
+        if not self.gzip:
+            self.data_src = open(self.input_filename,'rb')
+        else:
+            self.data_src = GzipFile(self.input_filename,'rb')
+
+        self.data_src.readline() # header line
+        self.is_over = False
+
+    def isOver(self):
+        return self.is_over
+
+
+class Inclusion(DataSource):
+    def __init__(self, geonames_filename,hierarchy_filename,mask_ids=None):
+        super().__init__("Inclusion SRC",hierarchy_filename)
+        assert os.path.exists(geonames_filename)
+        self.geonames_data_dict = {row.geonameid:(row.name,row.latitude,row.longitude) for row in read_geonames(geonames_filename).itertuples()}
+        
+        self.data_src = pd.read_csv(self.input_filename,
+            sep="\t",
+            header=None,
+            names="parentId,childId,type".split(",")
+        ).fillna("")
+        
+        if mask_ids:
+            self.data_src = self.data_src[self.data_src.childId.isin(mask_ids)]
+        self.data_src= self.data_src[self.data_src.childId.isin(self.geonames_data_dict)]
+        self.data_src= self.data_src[self.data_src.parentId.isin(self.geonames_data_dict)]
+
+        self.data_src = self.data_src["childId parentId".split()].values.tolist()
+        self.len = len(self.data_src)
+
+        self.i = 0
+
+        self.is_over = False
+
+    def __next__(self):
+        if self.i+1 >= self.len:
+            self.eof = True
+            raise StopIteration
+        else:
+            self.i += 1
+            tup_ = tuple(self.data_src[self.i-1])
+            return (self.geonames_data_dict[tup_[0]][0],
+            self.geonames_data_dict[tup_[1]][0],
+            self.geonames_data_dict[tup_[0]][2],
+            self.geonames_data_dict[tup_[0]][1])
+
+    def __reset__(self):
+        self.i = 0
+        self.is_over = False
+    
+    def isOver(self):
+        return (self.i == self.len)
+    
+
+
+
+class CoOccurrences(DataSource):
+    def __init__(self, filename, label_encoder,sampling=3,resolution = 256,use_healpix=False):
+        super().__init__("Co-Occurrence data",filename)
+        self.is_there_healpix = use_healpix
+        # LOAD DATA
+
+        self.data_src = pd.read_csv(filename,sep="\t")
+
+        # CHECK IF THE HEALPIX RESOLUTION DATA APPEARS IN THE DATA
+        if not "healpix_{0}".format(resolution) in self.data_src.columns:
+            raise KeyError("healpix_{0} column does not exists ! ".format(resolution))
+        
+        # PARSE TOPONYMS
+        self.data_src["title"] = self.data_src.title.apply(parse_title_wiki)
+        try:
+            self.data_src["interlinks"] = self.data_src.interlinks.apply(parse_title_wiki)
+        except:
+            pass
+
+        # LOOP parameter
+        self.sampling = sampling
+        if self.sampling:
+            self.probs_storage = SamplingProbabilities()
+            
+        # LOOP INDICES
+        self.i = 0
+        self.j = 0
+        self.is_over = False
+        self.len = len(self.data_src)*self.sampling
+
+        
+        # BUFFER VARIABLE
+        self.topo = None
+        self.context_topo_context = []
+        self.curr_probs = None
+        self.lat, self.lon = None, None
+
+
+        self.resolution = resolution
+        self.classes = self.data_src["healpix_{0}".format(self.resolution)].unique().tolist()
+
+        self.class_encoder = label_encoder
+        self.class_encoder.fit(self.classes)
+
+        self.healpix = None
+
+    def __next__(self):
+        if self.isOver() or self.i*self.sampling == self.len:
+            self.is_over = True
+            raise StopIteration 
+
+        if  self.j >= len(self.context_topo_context):
+            line = self.data_src.iloc[self.i]
+            
+            self.topo = line.title
+            self.context_topo_context = [x for x in str(line.interlinks).split("|")]
+            if self.sampling:
+                self.curr_probs = [self.probs_storage(x) for x in self.context_topo_context]
+                self.context_topo_context = np.random.choice(self.context_topo_context,self.sampling,self.curr_probs)
+            self.lat, self.lon = line.latitude,line.longitude
+            
+            self.healpix = line["healpix_{0}".format(self.resolution)]
+            
+            self.i += 1
+            self.j = 0
+        
+        self.j += 1
+        return (self.topo,
+        self.context_topo_context[self.j-1],
+        self.lat,self.lon,self.class_encoder.transform([self.healpix])[0])
+
+    def __reset__(self):
+        self.i = 0
+        self.is_over = False
+    
+    def isOver(self):
+        return self.is_over
+    
+class DataGenerator(keras.utils.Sequence):
+    'Generates data for Keras'
+    def __init__(self,data_sources,ngram_index,class_encoder,**kwargs):
+        'Initialization'
+        self.data_src = data_sources
+        self.ngram_index = ngram_index
+
+        self.batch_size = kwargs.get("batch_size",1000)
+        self.only_healpix = kwargs.get("only_healpix",False)
+        
+        self.len = sum([len(d) for d in self.data_src])
+        self.datasrc_index = 0
+
+        self.num_classes = class_encoder.get_num_classes()
+
+        self.is_there_healpix = self.data_src[self.datasrc_index].is_there_healpix
+    def __len__(self):
+        'Denotes the number of batches per epoch'
+        return int(np.floor(self.len / self.batch_size))
+
+    def return_(self,X,y,y2=None):
+        if self.is_there_healpix and self.only_healpix:
+            return [X[:,0],X[:,1]],y2
+
+        elif self.is_there_healpix:
+            return [X[:,0],X[:,1]],[y,y2]
+        else:
+            return [X[:,0],X[:,1]],y
+
+    def __getitem__(self, index):
+        'Generate one batch of data'
+        X = np.empty((self.batch_size,2,self.ngram_index.max_len),dtype=np.int32) # toponym
+        y = np.empty((self.batch_size,2),dtype=float) #lat lon coord
+
+        y2=None # For healpix
+        if self.is_there_healpix:
+            y2 = np.empty((self.batch_size,self.num_classes),dtype=float) # healpix class
+
+        if self.data_src[self.datasrc_index].isOver():
+                self.datasrc_index += 1
+                self.is_there_healpix = self.data_src[self.datasrc_index].is_there_healpix
+
+        if self.datasrc_index >= len(self.data_src):
+            self.return_(X,y,y2)
+        
+        for i in range(self.batch_size):
+            if self.data_src[self.datasrc_index].isOver():
+                return self.return_(X,y,y2)
+            try:
+                topo, topo_context, latitude, longitude, healpix_class = self.data_src[self.datasrc_index].__next__()
+            except StopIteration as e:
+                return self.return_(X,y,y2)
+            
+            X[i] = [ self.ngram_index.encode(topo),self.ngram_index.encode(topo_context)]
+            y[i] =  [*zero_one_encoding(longitude,latitude)]
+            if self.is_there_healpix:
+                y2[i] = to_categorical(healpix_class, num_classes=self.num_classes, dtype='int32'
+)
+
+            #y[i] = [longitude,latitude]
+        return self.return_(X,y,y2)
+
+    def on_epoch_end(self):
+        'Updates indexes after each epoch'
+        [d.__reset__() for d in self.data_src]
+        self.datasrc_index = 0
+
+
+    
+def load_embedding(model_fn,dim_vector=100):
+    model = KeyedVectors.load(model_fn)
+    N = len(model.wv.vocab)
+    M = np.zeros((N,dim_vector))
+    for i in range(N):
+        try:
+            M[i] = model.wv[str(i)]
+        except KeyError:
+            pass
+    return M
+
+if __name__ == "__main__":
+    # All adj nb of line :7955000-1
+    from lib.ngram_index import NgramIndex
+    from tqdm import tqdm
+    ng = NgramIndex.load("../data/embeddings/word2vec4gram/4gramWiki+geonames_index.json")
+    c= CoOccurrences("../data/wikipedia/cooccurrence_FR.txt_test.csv",sampling=3)
+    a = Adjacency("/home/jacques/sample_adjacency.txt",geonames_filename="../data/geonamesData/allCountries.txt",gzip=False,sampling=10)
+    i= Inclusion(geonames_filename="../data/geonamesData/allCountries.txt",hierarchy_filename="../data/geonamesData/hierarchy.txt")
+    d= DataGenerator([c,a,i],ng) 
+    for x in tqdm(range(len(d))):d[i]
diff --git a/lib/data_generatorv3.py b/lib/data_generatorv3.py
new file mode 100644
index 0000000..9bd88db
--- /dev/null
+++ b/lib/data_generatorv3.py
@@ -0,0 +1,354 @@
+import os
+from gzip import GzipFile
+
+import keras
+from keras.utils import to_categorical
+import numpy as np
+import pandas as pd
+
+from .utils_geo import zero_one_encoding
+
+from helpers import parse_title_wiki,read_geonames
+from gensim.models.keyedvectors import KeyedVectors
+
+from sklearn.preprocessing import LabelEncoder
+
+
+def wc_l(filename,gzip=True):
+    lc = 0
+    if not gzip:
+        f = open(filename)
+    if gzip:
+        f = GzipFile(filename)
+    while f.readline():
+        lc += 1 
+    f.close()       
+    return lc
+
+class SamplingProbabilities:
+    def __init__(self):
+        self.count = {}
+    
+    def get_probs(self,item):
+        if not item in self.count:
+            self.count[item] = 0
+        self.count[item]+=1
+        return 1/self.count[item]
+    def __call__(self,a):
+        return self.get_probs(a)
+        
+
+class DataSource(object):
+    def __init__(self,name,input_filename):
+        self.name = name
+        assert os.path.exists(input_filename)
+        self.input_filename = input_filename
+        self.len = 0
+
+        self.is_there_healpix = False
+
+    def __next__(self):
+        raise NotImplementedError()
+
+    def __iter__(self):
+        return self
+    
+    def __len__(self):
+        return self.len
+    
+    def __reset__(self):
+        raise NotImplementedError()
+
+    def isOver(self):
+        raise NotImplementedError()
+
+class Adjacency(DataSource):
+    def __init__(self,filename,geonames_filename,sampling=3,len_=None,gzip=True):
+        DataSource.__init__(self,"Adjacency SRC",filename)
+
+        assert os.path.exists(geonames_filename)
+        self.geonames_data_dict = {row.geonameid:row.name for row in read_geonames(geonames_filename).itertuples()}
+        
+        self.gzip = gzip
+        if not self.gzip:
+            self.data_src = open(self.input_filename,'rb')
+        else:
+            self.data_src = GzipFile(self.input_filename,'rb')
+
+        if len_:
+            self.len = len_*sampling
+        else:
+            self.len = wc_l(filename,gzip=gzip)
+        
+        self.data_src.readline() # header line
+
+        self.sampling = sampling
+        if self.sampling:
+            self.probs_storage = SamplingProbabilities() 
+
+        self.topo = None
+        self.context_topo_context = []
+        self.curr_probs = None
+        self.lat, self.lon = None, None
+
+
+        self.i = 0
+        self.is_over = False
+    
+    def __next__(self):
+        if  self.i >= len(self.context_topo_context):
+            line = self.data_src.readline()
+            if not line:
+                self.is_over = True
+                raise StopIteration
+            line = line.decode("utf-8").rstrip("\n")
+            _,geonameid, adjacent_geoname_id,latitude,longitude = tuple(line.split(","))
+
+            self.topo = int(geonameid)
+            self.context_topo_context = [int(x) for x in adjacent_geoname_id.split("|")]
+            if self.sampling:
+                self.curr_probs = [self.probs_storage(x) for x in self.context_topo_context]
+                self.context_topo_context = np.random.choice(self.context_topo_context,self.sampling,self.curr_probs)
+            self.lat, self.lon = float(latitude),float(longitude)
+
+            self.i = 0
+        
+        self.i += 1
+        return (self.geonames_data_dict[self.topo],
+        self.geonames_data_dict[self.context_topo_context[self.i-1]],
+        self.lat,self.lon)
+
+    def __reset__(self):
+        if not self.gzip:
+            self.data_src = open(self.input_filename,'rb')
+        else:
+            self.data_src = GzipFile(self.input_filename,'rb')
+
+        self.data_src.readline() # header line
+        self.is_over = False
+
+    def isOver(self):
+        return self.is_over
+
+
+class Inclusion(DataSource):
+    def __init__(self, geonames_filename,hierarchy_filename,mask_ids=None):
+        super().__init__("Inclusion SRC",hierarchy_filename)
+        assert os.path.exists(geonames_filename)
+        self.geonames_data_dict = {row.geonameid:(row.name,row.latitude,row.longitude) for row in read_geonames(geonames_filename).itertuples()}
+        
+        self.data_src = pd.read_csv(self.input_filename,
+            sep="\t",
+            header=None,
+            names="parentId,childId,type".split(",")
+        ).fillna("")
+        
+        if mask_ids:
+            self.data_src = self.data_src[self.data_src.childId.isin(mask_ids)]
+        self.data_src= self.data_src[self.data_src.childId.isin(self.geonames_data_dict)]
+        self.data_src= self.data_src[self.data_src.parentId.isin(self.geonames_data_dict)]
+
+        self.data_src = self.data_src["childId parentId".split()].values.tolist()
+        self.len = len(self.data_src)
+
+        self.i = 0
+
+        self.is_over = False
+
+    def __next__(self):
+        if self.i+1 >= self.len:
+            self.eof = True
+            raise StopIteration
+        else:
+            self.i += 1
+            tup_ = tuple(self.data_src[self.i-1])
+            return (self.geonames_data_dict[tup_[0]][0],
+            self.geonames_data_dict[tup_[1]][0],
+            self.geonames_data_dict[tup_[0]][2],
+            self.geonames_data_dict[tup_[0]][1])
+
+    def __reset__(self):
+        self.i = 0
+        self.is_over = False
+    
+    def isOver(self):
+        return (self.i == self.len)
+    
+
+
+
+class CoOccurrences(DataSource):
+    def __init__(self, filename, label_encoder,sampling=3,resolution = 256,use_healpix=False):
+        super().__init__("Co-Occurrence data",filename)
+        self.is_there_healpix = use_healpix
+        # LOAD DATA
+
+        self.data_src = pd.read_csv(filename,sep="\t")
+
+        # CHECK IF THE HEALPIX RESOLUTION DATA APPEARS IN THE DATA
+        if not "healpix_{0}".format(resolution) in self.data_src.columns:
+            raise KeyError("healpix_{0} column does not exists ! ".format(resolution))
+        
+        # PARSE TOPONYMS
+        self.data_src["title"] = self.data_src.title.apply(parse_title_wiki)
+        try:
+            self.data_src["interlinks"] = self.data_src.interlinks.apply(parse_title_wiki)
+        except:
+            pass
+
+        # LOOP parameter
+        self.sampling = sampling
+        if self.sampling:
+            self.probs_storage = SamplingProbabilities()
+            
+        # LOOP INDICES
+        self.i = 0
+        self.j = 0
+        self.is_over = False
+        self.len = len(self.data_src)*(self.sampling-1)
+
+        
+        # BUFFER VARIABLE
+        self.topo = None
+        self.context_topo_context = []
+        self.curr_probs = None
+        self.lat, self.lon = None, None
+
+
+        self.resolution = resolution
+        self.classes = self.data_src["healpix_{0}".format(self.resolution)].unique().tolist()
+
+        self.class_encoder = label_encoder
+        self.class_encoder.fit(self.classes)
+
+        self.healpix = None
+
+    def __next__(self):
+        if self.isOver() or self.i*self.sampling == self.len:
+            self.is_over = True
+            raise StopIteration 
+
+        if  self.j >= len(self.context_topo_context):
+            line = self.data_src.iloc[self.i]
+            
+            self.topo = line.title
+            self.context_topo_context = [x for x in str(line.interlinks).split("|")]
+            N = len(self.context_topo_context)
+            triple = []
+            for i in range(N):
+                if i+1 == N:
+                    break
+                triple.append((self.context_topo_context[i],self.context_topo_context[i+1]))
+                
+
+            self.context_topo_context = triple
+            np.random.shuffle(self.context_topo_context)
+            self.lat, self.lon = line.latitude,line.longitude
+            
+            self.healpix = line["healpix_{0}".format(self.resolution)]
+            
+            self.i += 1
+            self.j = 0
+        
+        self.j += 1
+        return (self.topo,
+        *self.context_topo_context[self.j-1],
+        self.lat,self.lon,self.class_encoder.transform([self.healpix])[0])
+
+    def __reset__(self):
+        self.i = 0
+        self.is_over = False
+    
+    def isOver(self):
+        return self.is_over
+    
+class DataGenerator(keras.utils.Sequence):
+    'Generates data for Keras'
+    def __init__(self,data_sources,ngram_index,class_encoder,**kwargs):
+        'Initialization'
+        self.data_src = data_sources
+        self.ngram_index = ngram_index
+
+        self.batch_size = kwargs.get("batch_size",1000)
+        self.only_healpix = kwargs.get("only_healpix",False)
+        
+        self.len = sum([len(d) for d in self.data_src])
+        self.datasrc_index = 0
+
+        self.num_classes = class_encoder.get_num_classes()
+
+        self.is_there_healpix = self.data_src[self.datasrc_index].is_there_healpix
+    def __len__(self):
+        'Denotes the number of batches per epoch'
+        return int(np.floor(self.len / self.batch_size))
+
+    def return_(self,X,y,y2=None):
+        if self.is_there_healpix and self.only_healpix:
+            return [X[:,0],X[:,1],X[:,2]],y2
+
+        elif self.is_there_healpix:
+            return [X[:,0],X[:,1],X[:,2]],[y,y2]
+        else:
+            return [X[:,0],X[:,1],X[:,2]],y
+
+    def __getitem__(self, index):
+        'Generate one batch of data'
+        X = np.empty((self.batch_size,3,self.ngram_index.max_len),dtype=np.int32) # toponym
+        y = np.empty((self.batch_size,2),dtype=float) #lat lon coord
+
+        y2=None # For healpix
+        if self.is_there_healpix:
+            y2 = np.empty((self.batch_size,self.num_classes),dtype=float) # healpix class
+
+        if self.data_src[self.datasrc_index].isOver():
+                self.datasrc_index += 1
+                self.is_there_healpix = self.data_src[self.datasrc_index].is_there_healpix
+
+        if self.datasrc_index >= len(self.data_src):
+            self.return_(X,y,y2)
+        
+        for i in range(self.batch_size):
+            if self.data_src[self.datasrc_index].isOver():
+                return self.return_(X,y,y2)
+            try:
+                topo, topo_context_1,topo_context_2, latitude, longitude, healpix_class = self.data_src[self.datasrc_index].__next__()
+            except StopIteration as e:
+                return self.return_(X,y,y2)
+            
+            X[i] = [ self.ngram_index.encode(topo),self.ngram_index.encode(topo_context_1),self.ngram_index.encode(topo_context_2)]
+            y[i] =  [*zero_one_encoding(longitude,latitude)]
+            if self.is_there_healpix:
+                y2[i] = to_categorical(healpix_class, num_classes=self.num_classes, dtype='int32'
+)
+
+            #y[i] = [longitude,latitude]
+        return self.return_(X,y,y2)
+
+    def on_epoch_end(self):
+        'Updates indexes after each epoch'
+        [d.__reset__() for d in self.data_src]
+        self.datasrc_index = 0
+
+
+    
+def load_embedding(model_fn,dim_vector=100):
+    model = KeyedVectors.load(model_fn)
+    N = len(model.wv.vocab)
+    M = np.zeros((N,dim_vector))
+    for i in range(N):
+        try:
+            M[i] = model.wv[str(i)]
+        except KeyError:
+            pass
+    return M
+
+if __name__ == "__main__":
+    # All adj nb of line :7955000-1
+    from lib.ngram_index import NgramIndex
+    from tqdm import tqdm
+    ng = NgramIndex.load("../data/embeddings/word2vec4gram/4gramWiki+geonames_index.json")
+    c= CoOccurrences("../data/wikipedia/cooccurrence_FR.txt_test.csv",sampling=3)
+    a = Adjacency("/home/jacques/sample_adjacency.txt",geonames_filename="../data/geonamesData/allCountries.txt",gzip=False,sampling=10)
+    i= Inclusion(geonames_filename="../data/geonamesData/allCountries.txt",hierarchy_filename="../data/geonamesData/hierarchy.txt")
+    d= DataGenerator([c,a,i],ng) 
+    for x in tqdm(range(len(d))):d[i]
diff --git a/lib/datageneratorv4.py b/lib/datageneratorv4.py
new file mode 100644
index 0000000..e451035
--- /dev/null
+++ b/lib/datageneratorv4.py
@@ -0,0 +1,65 @@
+import os
+from gzip import GzipFile
+
+import keras
+from keras.utils import to_categorical
+import numpy as np
+import pandas as pd
+
+from lib.utils_geo import zero_one_encoding
+
+from helpers import parse_title_wiki,read_geonames
+from gensim.models.keyedvectors import KeyedVectors
+
+from sklearn.preprocessing import LabelEncoder
+
+import numpy as np
+import keras
+
+class DataGenerator(keras.utils.Sequence):
+    'Generates data for Keras'
+    def __init__(self, pairs_of_toponyms,encoder, batch_size=32, shuffle=True):
+        'Initialization'
+        self.data= pairs_of_toponyms
+        self.encoder = encoder
+        self.dim = self.encoder.max_len
+        self.shuffle = shuffle
+    
+        self.batch_size = batch_size
+        self.on_epoch_end()
+
+    def __len__(self):
+        'Denotes the number of batches per epoch'
+        return int(np.floor(len(self.data) / self.batch_size))
+
+    def __getitem__(self, index):
+        'Generate one batch of data'
+        # Generate indexes of the batch
+        indexes = self.indexes[index*self.batch_size:(index+1)*self.batch_size]
+
+        # Generate data
+        return self.__data_generation(indexes)
+
+
+    def on_epoch_end(self):
+        'Updates indexes after each epoch'
+        self.indexes = np.arange(len(self.data))
+        if self.shuffle == True:
+            np.random.shuffle(self.indexes)
+
+    def __data_generation(self, list_ids):
+        'Generates data containing batch_size samples' # X : (n_samples, *dim, n_channels)
+        # Initialization
+        X1 = np.empty((self.batch_size, self.dim))
+        X2 = np.empty((self.batch_size, self.dim))
+        y = np.zeros((self.batch_size,2), dtype=float)
+
+        # Generate data
+        for ix,i in enumerate(list_ids):
+            # Store sample
+            X1[ix,] = self.encoder.encode(self.data.toponym.iloc[i])
+            X2[ix,] = self.encoder.encode(self.data.toponym_context.iloc[i])
+            # Store class
+            y[ix,] = list(zero_one_encoding(self.data.longitude.iloc[i],self.data.latitude.iloc[i]))
+
+        return [X1,X2],y
\ No newline at end of file
diff --git a/lib/geocoder/__init__.py b/lib/geocoder/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/lib/geocoder/bert_geocoder.py b/lib/geocoder/bert_geocoder.py
new file mode 100644
index 0000000..037ddad
--- /dev/null
+++ b/lib/geocoder/bert_geocoder.py
@@ -0,0 +1,67 @@
+import os
+import sys
+import time
+import random
+import argparse
+import datetime
+
+import pandas as pd
+import numpy as np
+
+import tensorflow as tf
+import torch
+
+from tqdm import tqdm
+tqdm.pandas()
+
+from torch.utils.data import TensorDataset, DataLoader, RandomSampler, SequentialSampler
+from keras.preprocessing.sequence import pad_sequences
+from transformers import BertTokenizer
+from transformers import BertForSequenceClassification, AdamW, BertConfig
+from transformers import get_linear_schedule_with_warmup
+
+from ..torch_generator import SentenceDataset
+from ..utils_geo import latlon2healpix,healpix2latlon
+
+import pickle
+
+# If there's a GPU available...
+if torch.cuda.is_available():    
+
+    # Tell PyTorch to use the GPU.    
+    device = torch.device("cuda")
+    print('There are %d GPU(s) available.' % torch.cuda.device_count())
+    print('We will use the GPU:', torch.cuda.get_device_name(0))
+# If not...
+else:
+    print('No GPU available, using the CPU instead.')
+    device = torch.device("cpu")
+
+
+class BertGeocoder():
+    def __init__(self,bert_model_dir,label_healpix_file,healpix_nside=128,batch_size=1):
+        self.bert_model = BertForSequenceClassification.from_pretrained(bert_model_dir)
+        self.bert_model.to(device)
+        self.tokenizer = BertTokenizer.from_pretrained(bert_model_dir,truncation=True)
+        self.label_healpix = {v:k for k, v in pickle.load(open(label_healpix_file,'rb')).items()}
+
+        self.nside = healpix_nside
+
+        self.batch_size = batch_size
+
+    def geocode(self,toponyms, context_toponyms):
+        data = SentenceDataset(pd.DataFrame([[toponyms[i] + " " + context_toponyms[i],0] for i in range(len(toponyms))],columns=["sentence","label"]),self.tokenizer,batch_size=len(toponyms),shuffle=False)
+        dataloader = DataLoader(data,  batch_size=self.batch_size)
+        results = []
+        for step, batch in enumerate(dataloader):
+            b_input_ids = batch[0].to(device)
+            b_input_mask = batch[1].to(device)
+            with torch.no_grad():
+                outputs = self.bert_model(b_input_ids, 
+                                token_type_ids=None, 
+                                attention_mask=b_input_mask)
+            results.append(outputs[0].detach().cpu().numpy())
+        label = np.argmax(np.concatenate(results),axis=1)
+        healpix_label = [self.label_healpix[l] for l in label]
+        lat,lon = healpix2latlon(healpix_label,self.nside)
+        return np.concatenate((lat.reshape(-1,1),lon.reshape(-1,1)),axis=1)
\ No newline at end of file
diff --git a/lib/geocoder/heuristics.py b/lib/geocoder/heuristics.py
new file mode 100644
index 0000000..82d7110
--- /dev/null
+++ b/lib/geocoder/heuristics.py
@@ -0,0 +1,55 @@
+import pandas as pd
+import numpy as np
+
+from haversine import haversine_vector, Unit
+from sklearn.cluster import DBSCAN
+
+def heuristic_mean(geocoder,toponyms):
+    input_ = np.asarray([[t1,t2] for t2 in toponyms for t1 in toponyms if t2 != t1])
+    res_geocode = pd.DataFrame(input_,columns="t tc".split())
+    lons,lats = geocoder.get_coords(input_[:,0],input_[:,1])
+    res_geocode["lon"] = lons
+    res_geocode["lat"] = lats
+    results = {}
+    for tp in toponyms:
+        lat = res_geocode[res_geocode.t == tp].lat.mean()
+        lon = res_geocode[res_geocode.t == tp].lon.mean()
+        results[tp]={"lat":lat,"lon":lon}
+    return results
+
+def heuristic_no_context(geocoder,toponyms):
+    input_ = np.asarray([[t1,t1] for t2 in toponyms for t1 in toponyms if t2 != t1])
+    res_geocode = pd.DataFrame(input_,columns="t tc".split())
+    lons,lats = geocoder.get_coords(input_[:,0],input_[:,1])
+    res_geocode["lon"] = lons
+    res_geocode["lat"] = lats
+    results = {}
+    for tp in toponyms:
+        lat = res_geocode[res_geocode.t == tp].lat.mean()
+        lon = res_geocode[res_geocode.t == tp].lon.mean()
+        results[tp]={"lat":lat,"lon":lon}
+    return results
+
+def heuristic_cluster(geocoder,toponyms,eps=100):
+    results = {}
+    input_ = np.asarray([[t1,t2] for t2 in toponyms for t1 in toponyms if t2 != t1])
+    res_geocode = pd.DataFrame(input_,columns="t tc".split())
+    lons,lats = geocoder.get_coords(input_[:,0],input_[:,1])
+    res_geocode["lon"] = lons
+    res_geocode["lat"] = lats
+
+    clf = DBSCAN(eps=eps)
+    for t in toponyms:
+        tp_df = res_geocode[res_geocode.tc == t].copy()
+
+        coords = tp_df["lon lat".split()].values
+        clf.fit(haversine_vector(coords,coords,unit="km",comb=True))
+
+        tp_df["cluster"] = clf.labels_
+        counts_ = dict(tp_df.cluster.value_counts())
+        max_cluster = max(counts_, key=counts_.get)
+        tp_df = tp_df[tp_df.cluster == max_cluster]
+        lat = tp_df.lat.median()
+        lon = tp_df.lon.median() #
+        results[t]={"lat":lat,"lon":lon}
+    return results
\ No newline at end of file
diff --git a/lib/geocoder/our_geocoder.py b/lib/geocoder/our_geocoder.py
new file mode 100644
index 0000000..0345ea4
--- /dev/null
+++ b/lib/geocoder/our_geocoder.py
@@ -0,0 +1,113 @@
+# NATIVE LIB
+import os
+
+# DATA LIB
+import numpy as np
+import pandas as pd
+
+# DL LIB
+import tensorflow as tf
+import keras.backend as K
+from keras.models import load_model
+from tensorflow.python.keras.backend import set_session
+from tensorflow.python.keras.models import load_model
+
+# CUSTOM LIB
+from lib.word_index import WordIndex
+from lib.ngram_index import NgramIndex
+from lib.utils_geo import haversine_tf_1circle
+
+
+import stanza
+import spacy
+import os
+os.environ['CUDA_VISIBLE_DEVICES'] = '-1'
+
+class Geocoder(object):
+    """
+    >>>geocoder = Geocoder("LSTM_FR.txt_20_4_0.002_None_A_I_C.h5","index_4gram_FR_backup.txt")
+    >>>lon,lat = geocoder.get_coord("Paris","New-York")
+    >>>lon,lat = geocoder.wgs_coord(lon,lat)
+    >>>geocoder.plot_coord("Paris,New-York",lat,lon)
+
+    if you want an interactive map using leafletJS, set to True the `interactive_map` parameter of `Geocoder.plot_coord()`
+    """
+    def __init__(self,keras_model_fn,ngram_index_file,word_index=False):
+        self.keras_model = load_model(keras_model_fn,custom_objects={"loss":haversine_tf_1circle},compile=False)#custom_objects={"accuracy_at_k_lat":lat_accuracy(),"accuracy_at_k_lon":lon_accuracy()})
+        if not word_index:
+            self.ngram_encoder = NgramIndex.load(ngram_index_file)
+        else:
+            self.ngram_encoder = WordIndex.load(ngram_index_file)
+
+    def get_coord(self,toponym,context_toponym):
+        global sess
+        global graph
+        p = self.ngram_encoder.complete(self.ngram_encoder.encode(toponym),self.ngram_encoder.max_len)
+        c = self.ngram_encoder.complete(self.ngram_encoder.encode(context_toponym),self.ngram_encoder.max_len)
+        p = np.array(p)
+        c = np.array(c)       
+        coord = self.keras_model.predict([[p],[c]])
+        return self.wgs_coord(coord[0][0],coord[0][1])
+    
+    def get_coords(self,list_toponym,list_toponym_context):
+        p = [self.ngram_encoder.complete(self.ngram_encoder.encode(toponym),self.ngram_encoder.max_len) for toponym in list_toponym]
+        c = [self.ngram_encoder.complete(self.ngram_encoder.encode(toponym),self.ngram_encoder.max_len) for toponym in list_toponym_context]
+
+        p = np.array(p)
+        c = np.array(c)
+        
+        coords = self.keras_model.predict([p,c])
+        return self.wgs_coord(coords[:,0],coords[:,1]) #lon lat
+
+    def wgs_coord(self,lon,lat):
+        return ((lon*360)-180),((lat*180)-90)
+    
+    def plot_coord(self,toponym,lat,lon,interactive_map=False,**kwargs):
+        if interactive_map:
+            import folium
+            import tempfile
+            import webbrowser
+            fp = tempfile.NamedTemporaryFile(delete=False)
+            m = folium.Map()
+            folium.Marker([lat, lon], popup=toponym).add_to(m)
+            m.save(fp.name)
+            webbrowser.open('file://' + fp.name)
+        else:
+            import matplotlib.pyplot as plt
+            import geopandas
+            fig, ax = plt.subplots(1,**kwargs)
+            world = geopandas.read_file(geopandas.datasets.get_path('naturalearth_lowres'))
+            world.plot(color='white', edgecolor='black',ax=ax)
+            ax.plot(lon,lat,marker='o', color='red', markersize=5)
+            plt.show()
+
+
+    
+class TextGeocoder():
+    def __init__(self,geocoder_model,ner_name,lang,heuristic_func,n_jobs=None):
+        self.geocoder_model = geocoder_model
+        self.ner_name = ner_name
+        self.ner_model = None
+        if self.ner_name == "stanza":
+            self.ner_model = stanza.Pipeline(lang)
+        else:
+            self.ner_model = spacy.load(lang)
+            self.heuristic_func = heuristic_func
+    def __call__(self,a):
+        pass
+
+    def extract_geo_entities(self,text):
+        if self.ner_model == "stanza":
+            entities = [{"text":en.text,"type":en.type,"start":en.start_char,"end":en.end_char} for en in self.ner_model(text).entities  if en.type == "LOC"]
+        else:
+            entities = [{"text":en.text,"type":en.label_,"start":en.start_char,"end":en.end_char} for en in self.ner_model(text).ents if en.label_ in "LOC GPE".split()]
+        return entities
+
+    def geocode(self,entities):
+        df = pd.DataFrame(entities)
+        heuristic_results = self.heuristic_func(self.geocoder_model,df.text.values)
+        for e in range(len(entities)):
+            entities[e]["coord"] = heuristic_results[entities[e]["text"]]
+        return entities
+    
+    
diff --git a/lib/geocoder/svm_geocoder.py b/lib/geocoder/svm_geocoder.py
new file mode 100644
index 0000000..2997b29
--- /dev/null
+++ b/lib/geocoder/svm_geocoder.py
@@ -0,0 +1,36 @@
+import numpy as np
+
+from joblib import dump, load
+from tensorflow.keras.utils import to_categorical
+
+from lib.utils_geo import latlon2healpix
+from lib.ngram_index import NgramIndex
+
+
+def parse_bow(x,index):
+    return np.sum(to_categorical(x,num_classes=index.cpt+1),axis=0)
+
+def is_in(lat,lon,hp_predicted,hp_nside):
+    hp_truth = latlon2healpix(lat,lon,hp_nside)
+    return hp_truth == hp_predicted
+
+class SVMGeocoder(object):
+    
+    def __init__(self,model_fn,ngram_index_filename):
+        self.model = load(model_fn)
+        self.ng_index = NgramIndex.load(ngram_index_filename)
+    
+    def geocode(self,phrase1,phrase2):
+        if not phrase1 or not phrase2:
+            return None
+        vec = parse_bow(np.array(self.ng_index.encode(phrase1)),self.ng_index)+\
+            parse_bow(np.array(self.ng_index.encode(phrase2)),self.ng_index)
+        return self.model.predict([vec])[0]
+    
+    def geocode_multi(self,phrases1,phrases2):
+        vecs = np.array([ parse_bow(np.array(self.ng_index.encode(ph)),self.ng_index) for ph in phrases1 if ph])
+        vecs += np.array([ parse_bow(np.array(self.ng_index.encode(ph)),self.ng_index) for ph in phrases2 if ph])
+        return self.model.predict(vecs)
+
+hp = SVMGeocoder("SVMLINEAR_US_FR_AC.bin", "../../outputs/US_FR.txt_100_4_0.002__A_C_index")
+hp.geocode("paris","montpellier")
diff --git a/lib/metrics.py b/lib/metrics.py
new file mode 100644
index 0000000..e82c548
--- /dev/null
+++ b/lib/metrics.py
@@ -0,0 +1,37 @@
+import tensorflow as tf
+
+def lat_accuracy(LAT_TOL =1/180.):
+    def accuracy_at_k_lat(y_true, y_pred):
+        """
+        Metrics use to measure the accuracy of the coordinate prediction. But in comparison to the normal accuracy metrics, we add a tolerance threshold due to the (quasi) impossible 
+        task for neural network to obtain the exact  coordinate.
+
+        Parameters
+        ----------
+        y_true : tf.Tensor
+            truth data
+        y_pred : tf.Tensor
+            predicted output
+        """
+        diff = tf.abs(y_true - y_pred)
+        fit = tf.dtypes.cast(tf.less(diff,LAT_TOL),tf.int64)
+        return tf.reduce_sum(fit)/tf.size(y_pred,out_type=tf.dtypes.int64)
+    return accuracy_at_k_lat
+
+def lon_accuracy(LON_TOL=1/360.):
+    def accuracy_at_k_lon(y_true, y_pred):
+        """
+        Metrics use to measure the accuracy of the coordinate prediction. But in comparison to the normal accuracy metrics, we add a tolerance threshold due to the (quasi) impossible 
+        task for neural network to obtain the exact  coordinate.
+
+        Parameters
+        ----------
+        y_true : tf.Tensor
+            truth data
+        y_pred : tf.Tensor
+            predicted output
+        """
+        diff = tf.abs(y_true - y_pred)
+        fit = tf.dtypes.cast(tf.less(diff,LON_TOL),tf.int64)
+        return tf.reduce_sum(fit)/tf.size(y_pred,out_type=tf.dtypes.int64)
+    return accuracy_at_k_lon
\ No newline at end of file
diff --git a/lib/ngram_index.py b/lib/ngram_index.py
new file mode 100644
index 0000000..5f86220
--- /dev/null
+++ b/lib/ngram_index.py
@@ -0,0 +1,229 @@
+import json
+
+import numpy as np
+
+from ngram import NGram
+from transformers import BertTokenizer
+
+# Machine learning 
+from gensim.models import Word2Vec
+
+
+class bertTokenizer:
+    def __init__(self):
+        self.tokenizer = BertTokenizer.from_pretrained('bert-base-multilingual-cased',do_lower_case=False)
+    
+    def split(self,string):
+        return self.tokenizer.tokenize(string)
+
+class NgramIndex():
+    """
+    Class used for encoding words in ngram representation
+    """
+    def __init__(self,n,bert_tokenization=False,loaded = False):
+        """
+        Constructor
+        
+        Parameters
+        ----------
+        n : int
+            ngram size
+        """
+        self.ngram_gen = NGram(N=n)
+        self.empty_char = "$"
+        if bert_tokenization:
+            self.ngram_gen = bertTokenizer()
+            self.empty_char = "#"
+
+        self.size = n
+        self.ngram_index = {"":0}
+        self.index_ngram = {0:""}
+        self.cpt = 0
+        self.max_len = 0
+
+        self.loaded = loaded
+
+        
+    def split_and_add(self,word):
+        """
+        Split word in multiple ngram and add each one of them to the index
+        
+        Parameters
+        ----------
+        word : str
+            a word
+        """
+        ngrams = str(word).lower().replace(" ",self.empty_char)
+        ngrams = list(self.ngram_gen.split(ngrams))
+        [self.add(ngram) for ngram in ngrams]
+        self.max_len = max(self.max_len,len(ngrams))
+
+    def add(self,ngram):
+        """
+        Add a ngram to the index
+        
+        Parameters
+        ----------
+        ngram : str
+            ngram
+        """
+        if not ngram in self.ngram_index:
+            self.cpt+=1
+            self.ngram_index[ngram]=self.cpt
+            self.index_ngram[self.cpt]=ngram
+        
+
+    def encode(self,word):
+        """
+        Return a ngram representation of a word
+        
+        Parameters
+        ----------
+        word : str
+            a word
+        
+        Returns
+        -------
+        list of int
+            listfrom shapely.geometry import Point,box
+ of ngram index
+        """
+        ngrams = str(word).lower().replace(" ",self.empty_char)
+        ngrams = list(self.ngram_gen.split(ngrams))
+        ngrams = [ng for ng in ngrams if ng.count(self.empty_char)<2]
+        if not self.loaded:
+            [self.add(ng) for ng in ngrams if not ng in self.ngram_index]
+        return self.complete([self.ngram_index[ng] for ng in ngrams if ng in self.ngram_index],self.max_len)
+
+    def complete(self,ngram_encoding,MAX_LEN,filling_item=0):
+        """
+        Complete a ngram encoded version of word with void ngram. It's necessary for neural network.
+        
+        Parameters
+        ----------
+        ngram_encoding : list of int
+            first encoding of a word
+        MAX_LEN : int
+            desired length of the encoding
+        filling_item : int, optional
+            ngram index you wish to use, by default 0
+        
+        Returns
+        -------
+        list of int
+            list of ngram index
+        """
+        if self.loaded and len(ngram_encoding) >=MAX_LEN:
+            return ngram_encoding[:MAX_LEN]
+        assert len(ngram_encoding) <= MAX_LEN
+        diff = MAX_LEN - len(ngram_encoding)
+        ngram_encoding.extend([filling_item]*diff)  
+        return ngram_encoding
+    
+    def get_embedding_layer(self,texts,dim=100,**kwargs):
+        """
+        Return an embedding matrix for each ngram using encoded texts. Using gensim.Word2vec model.
+        
+        Parameters
+        ----------
+        texts : list of [list of int]
+            list of encoded word
+        dim : int, optional
+            embedding dimension, by default 100
+        
+        Returns
+        -------
+        np.array
+            embedding matrix
+        """
+        model = Word2Vec([[str(w) for w in t] for t in texts], size=dim,window=5, min_count=1, workers=4,**kwargs)
+        N = len(self.ngram_index)
+        embedding_matrix = np.zeros((N,dim))
+        for i in range(N):
+            if str(i) in model.wv:
+                embedding_matrix[i] = model.wv[str(i)]
+        return embedding_matrix
+
+    def get_glove_embedding_layer(self,texts,dim=100,**kwargs):
+        """
+        Return an embedding matrix for each ngram using encoded texts. Using gensim.Word2vec model.
+        
+        Parameters
+        ----------
+        texts : list of [list of int]
+            list of encoded word
+        dim : int, optional
+            embedding dimension, by default 100
+        
+        Returns
+        -------
+        np.array
+            embedding matrix
+        """
+        from glove import Corpus, Glove
+        corpus = Corpus()
+        corpus.fit([[str(w) for w in t] for t in texts], window=10)
+        glove = Glove(no_components=dim, learning_rate=0.05)
+        glove.fit(corpus.matrix, epochs=30, no_threads=4, verbose=True)
+        glove.add_dictionary(corpus.dictionary)
+        N = len(self.ngram_index)
+        embedding_matrix = np.zeros((N,dim))
+        for i in range(N):
+            if str(i) in glove.dictionary:
+                embedding_matrix[i] = glove.word_vectors[glove.dictionary[str(i)]]
+        return embedding_matrix
+        
+
+    def save(self,fn):
+        """
+
+        Save the NgramIndex
+        
+        Parameters
+        ----------
+        fn : str
+            output filename
+        """
+        data = {
+            "ngram_size": self.size,
+            "ngram_index": self.ngram_index,
+            "cpt_state": self.cpt,
+            "max_len_state": self.max_len
+        }
+        json.dump(data,open(fn,'w'))
+
+    @staticmethod
+    def load(fn):
+        """
+        
+        Load a NgramIndex state from a file.
+        
+        Parameters
+        ----------
+        fn : str
+            input filename
+        
+        Returns
+        -------
+        NgramIndex
+            ngram index
+        
+        Raises
+        ------
+        KeyError
+            raised if a required field does not appear in the input file
+        """
+        try:
+            data = json.load(open(fn))
+        except json.JSONDecodeError:
+            print("Data file must be a JSON")
+        for key in ["ngram_size","ngram_index","cpt_state","max_len_state"]:
+            if not key in data:
+                raise KeyError("{0} field cannot be found in given file".format(key))
+        new_obj = NgramIndex(data["ngram_size"],loaded=True)
+        new_obj.ngram_index = data["ngram_index"]
+        new_obj.index_ngram = {v:k for k,v in new_obj.ngram_index.items()}
+        new_obj.cpt = data["cpt_state"]
+        new_obj.max_len = data["max_len_state"]
+        return new_obj
+
diff --git a/lib/run.py b/lib/run.py
new file mode 100644
index 0000000..f2a7b79
--- /dev/null
+++ b/lib/run.py
@@ -0,0 +1,223 @@
+
+import subprocess
+import time
+import numpy as np
+
+class Chronometer:
+    """
+    To be used for mesure time execution of a block of code
+    >>> import time
+    >>> chrono = Chronometer()
+    >>> chrono.start("task1")
+    >>> time.sleep(1)
+    >>> duration = chrono.stop("task1")
+    >>> print(duration) #Should display '1'
+
+    """
+    def __init__(self):
+        self.__task_begin_timestamp = {}
+
+    def start(self, task_name):
+        """
+        Start a new task chronometer
+        
+        Parameters
+        ----------
+        task_name : str
+            task id
+        
+        Raises
+        ------
+        ValueError
+            if a running task already exists with that name
+        """
+        if task_name in self.__task_begin_timestamp:
+            raise ValueError(
+                "A running task exists with the name {0}!".format(task_name)
+            )
+        self.__task_begin_timestamp[task_name] = time.time()
+
+    def stop(self, task_name):
+        """
+        Stop and return the duration of the task
+        
+        Parameters
+        ----------
+        task_name : str
+            task id
+        
+        Returns
+        -------
+        float
+            duration of the task in seconds
+        
+        Raises
+        ------
+        ValueError
+            if no task exist with the id `task_name`
+        """
+        if not task_name in self.__task_begin_timestamp:
+            raise ValueError("The {0} task does not exist!".format(task_name))
+        
+        duration = time.time() - self.__task_begin_timestamp[task_name]
+        del self.__task_begin_timestamp[task_name]
+
+        return duration
+
+class Run(object):
+    """
+    Define a task to execute. A task here is associated to a command line. A task is defined by two entities :
+     * base_command : runnable
+     * kwargs : parameters associate to the command  
+    
+    Parmeters formating follows `argparse` format:
+    * "-i" or "--input" : optional parameter
+    * "input" : required parameter
+
+    >>> task1 = Run("task1","echo",text="hello word")
+    >>> task1.run()
+
+    With optional parameter, we have to use a trick ;)
+
+    >>> task1 = Run("task1","echo",**{"text":"hello word","-e":"args")
+    >>> task1.run()
+
+    To save the output, indicate an output filename when the task is run :
+    >>> task1.run("output_file.txt")
+    """
+    def __init__(self,task_name,base_command,**kwargs):
+        """
+        Constructor
+        
+        Parameters
+        ----------
+        command_base : str
+            command base
+        **kwargs : dict
+            parameters
+        """
+        self.chrono = Chronometer()
+        self.task_name = task_name
+        self.base_command = base_command
+
+        self.run_args = kwargs
+        
+
+    def get_command(self):
+        """
+        Return the shell command build on the task attributes (basic command and parameters)
+        
+        Returns
+        -------
+        str
+            command
+        """
+        command = self.base_command
+        for key,value in self.run_args.items():
+            if "-" in key:
+                command = command + " {0} {1}".format(key,value)
+            else:
+                command = command + " {0}".format(value)
+        return command
+
+    def add_parameter(self, key, value):
+        """
+        Add a parameter to the task
+        
+        Parameters
+        ----------
+        key : str
+            key
+        value : object
+            value
+        """ 
+        self.run_args[key] = value
+
+    def run(self,log_filename = None):
+        """
+        Run the task
+        
+        Parameters
+        ----------
+        log_filename : str, optional
+            log filename, by default None
+        """
+        self.chrono.start(self.task_name)
+
+        out_proc = subprocess.PIPE
+        if log_filename:
+            out_proc = open(log_filename,'a')
+            print(4)
+        process = subprocess.Popen(self.get_command().split(),stdout=out_proc)
+        _, _ = process.communicate() # We don't care of the output (if so, we use the log_filename argument)
+
+        duration = self.chrono.stop(self.task_name)
+        print("RUN {0} finished in {1}seconds OR {2}minutes OR {3}hours".format(\
+            self.task_name,duration,duration/60,(duration/60)/60
+            ))
+    def __repr__(self):
+        return "; ".join(["{0}={1}".format(k,v) for k,v in self.run_args.items()])
+
+
+class GridSearchModel:
+    """
+    Define a set of model executions based on a set of parameters and their values variations.
+
+    For the parameters format, please check the `Run` documentations.
+    
+    >>> grid = GridSearchModel("ls",test=["-l", "-h","-lh"])
+    >>> grid.run()
+    """
+    def __init__(self,command_base,**kwargs):
+        """
+        Constructor
+        
+        Parameters
+        ----------
+        command_base : str
+            command base
+        **kwargs : dict
+            parameters
+        """
+        self.parameters = kwargs
+        self.cpt = 0
+        self.number_of_combination = np.prod([len(v) for _,v in self.parameters.items()])
+        
+        
+
+        self.tasks = []
+        for cpt in range(self.number_of_combination):
+            new_task = Run(str(cpt),command_base)
+            self.tasks.append(new_task)
+
+        for key,values in self.parameters.items():
+            split_ = int(self.number_of_combination/len(values))
+            i = 0
+            for val in values:
+                for task in self.tasks[i:i+split_]:
+                    task.add_parameter(key,val)
+                i += split_
+
+    def __repr__(self):
+        return "\n".join([ t.__repr__() for t in self.tasks])           
+        
+    def run(self,log_filename=None):
+        """
+        Run all the tasks defined
+        
+        Parameters
+        ----------
+        log_filename : str, optional
+            log filename, by default None
+        """
+        i=0
+        for task in self.tasks:
+            task.run(log_filename=log_filename+"_"+str(i))
+            i+=1
+
+    
+if __name__ == "__main__":
+    g = GridSearchModel("ls",test=["-l", "-h","-lh"],rel=["-i"])
+    print(g)
+
+    #g.run()
diff --git a/lib/torch_generator.py b/lib/torch_generator.py
new file mode 100644
index 0000000..3613086
--- /dev/null
+++ b/lib/torch_generator.py
@@ -0,0 +1,50 @@
+import torch
+from keras.preprocessing.sequence import pad_sequences
+import numpy as np 
+
+def chunks(lst, n):
+    """Yield successive n-sized chunks from lst."""
+    for i in range(0, len(lst), n):
+        yield lst[i:i + n]
+
+class SentenceDataset(torch.utils.data.Dataset):
+    'Characterizes a dataset for PyTorch'
+    def __init__(self, dataframe,tokenizer,max_len=96,batch_size=32,shuffle=True):
+        'Initialization'
+        self.sentences = dataframe["sentence"].values
+        self.labels = dataframe["label"].values
+        self.tokenizer = tokenizer
+        self.max_len = max_len
+
+        self.batch_size = batch_size
+        a = np.arange(len(dataframe))
+        if shuffle:
+            np.random.shuffle(a)
+        self.batch_tokenization = list(chunks(a,batch_size))
+        assert(len(self.batch_tokenization[0])==batch_size)
+        self.current_batch_id = 0
+        self.boundaries = (0,0+batch_size)
+        self.current_batch_tokenized = self.tokenize(self.current_batch_id)
+
+    def tokenize(self,batch_index):
+        X = [ self.tokenizer.encode(self.sentences[x],add_special_tokens = True,max_length=512,truncation=True) for x in self.batch_tokenization[batch_index]]# Tokenizer
+        X = pad_sequences(X, maxlen=self.max_len, dtype="long", value=0, truncating="post", padding="post").tolist()
+        return X
+
+    def __len__(self):
+        'Denotes the total number of samples'
+        return len(self.sentences)
+    def __getitem__(self, index):
+        'Generates one sample of data'
+        if not index < self.boundaries[1] or not index >= self.boundaries[0]:
+            self.current_batch_id = index//self.batch_size
+            self.current_batch_tokenized = self.tokenize(self.current_batch_id)
+            self.boundaries= (self.current_batch_id*self.batch_size,self.current_batch_id*self.batch_size + self.batch_size)
+        # Load data and get label
+        
+        index_in_batch = index-self.boundaries[0]
+        #print(self.boundaries,index_in_batch)
+        X = self.current_batch_tokenized[index_in_batch]
+        M = [int(token_id > 0) for token_id in X] # attention mask
+        y = self.labels[index]
+        return torch.tensor(np.array(X)),torch.tensor(np.array(M)),torch.tensor(np.array(y))
\ No newline at end of file
diff --git a/lib/utils.py b/lib/utils.py
new file mode 100644
index 0000000..82531b3
--- /dev/null
+++ b/lib/utils.py
@@ -0,0 +1,220 @@
+# Basic import 
+import math
+import argparse
+import os
+import json
+import time
+import datetime
+
+# Data Structure
+import numpy as np
+import geopandas as gpd
+from shapely.geometry import Point,box
+
+# NLP 
+from nltk.tokenize import word_tokenize
+from ngram import NGram
+
+# Visualisation and parallelisation
+from tqdm import tqdm
+
+class LabelEncoder():
+    def __init__(self):
+        self.dict_ = {}
+        self.cpt = 0
+    
+    def fit_transform(self,list_element):
+        self.fit(list_element)
+        return self.transform(list_element)
+
+    def fit(self,list_element):
+        for l in list_element:
+            if not l in self.dict_:
+                self.dict_[l] = self.cpt
+                self.cpt+=1
+    def transform(self,list_element):
+        return [self.dict_[l] for l in list_element]
+    
+    def get_num_classes(self):
+        return self.cpt
+
+class TokenizerCustom():
+    def __init__(self,vocab):
+        self.word_index = {vocab[i]:i for i in range(len(vocab))}
+        self.index_word = {i:vocab[i] for i in range(len(vocab))}
+        self.N = len(self.index_word)
+    def texts_to_sequences(self,listText):
+        seqs = []
+        for text in listText:
+            seqs.append([self.word_index[word] for word in word_tokenize(text) if word in self.word_index])
+        return seqs
+
+
+class ConfigurationReader(object):
+    def __init__(self,configuration_file):
+        if not os.path.exists(configuration_file):
+            raise FileNotFoundError("'{0} file could not be found ! '".format(configuration_file))
+
+        self.configuration = json.load(open(configuration_file))
+
+        self.__argparser_desc = ("" if not "description" in self.configuration else self.configuration["description"])
+        self.parser = argparse.ArgumentParser(description=self.__argparser_desc)
+
+        self.parse_conf()
+    
+    def parse_conf(self):
+        if not "args" in self.configuration:
+            raise argparse.ArgumentError("","No args given in the configuration file")
+        
+        for dict_args in self.configuration["args"]:
+            if not isinstance(dict_args,dict):
+                raise ValueError("Args must be dictionnary")
+
+            short_command = dict_args.get("short",None)
+            long_command = dict_args.get("long",None)
+            
+            if not short_command and not long_command:
+                raise ValueError("No command name was given !") 
+            
+            add_func_dict_= {}
+            if "help" in dict_args:
+                add_func_dict_["help"]= dict_args["help"]
+            if "default" in dict_args:
+                add_func_dict_["default"]= dict_args["default"]
+            if "action" in dict_args:
+                add_func_dict_["action"]= dict_args["action"]
+            if "type" in dict_args:
+                add_func_dict_["type"]= eval(dict_args["type"])
+            if "choices" in dict_args:
+                add_func_dict_["choices"]= dict_args["choices"]
+
+            if not (short_command and long_command):
+                command = (short_command if not long_command else long_command)
+                self.parser.add_argument(command,**add_func_dict_)
+
+            elif long_command and short_command:
+                self.parser.add_argument(short_command,long_command,**add_func_dict_)
+    
+    def parse_args(self,input_=None):
+        if not input_:
+            return self.parser.parse_args()
+        return self.parser.parse_args(input_)
+
+
+class MetaDataSerializer(object):
+    def __init__(self,
+    model_name,
+    dataset_name,
+    rel_code,
+    cooc_sample_size,
+    adj_iteration,
+    ngram_size,
+    tolerance_value,
+    epochs,
+    embedding_dim,
+    word2vec_iter_nb,
+    index_fn,
+    keras_model_fn,
+    train_test_history_fn):
+        self.model_name = model_name
+        self.dataset_name = dataset_name
+        self.rel_code = rel_code
+        self.cooc_sample_size = cooc_sample_size
+        self.adj_iteration = adj_iteration
+        self.ngram_size = ngram_size
+        self.tolerance_value = tolerance_value
+        self.epochs = epochs
+        self.embedding_dim = embedding_dim
+        self.word2vec_iter_nb = word2vec_iter_nb
+        self.index_fn = index_fn
+        self.keras_model_fn = keras_model_fn
+        self.train_test_history_fn = train_test_history_fn
+    
+    def save(self,fn):
+        json.dump({
+        "model_name":self.model_name,
+        "dataset_name" : self.dataset_name,
+        "rel_code" : self.rel_code,
+        "cooc_sample_size" : self.cooc_sample_size,
+        "adj_iteration" : self.adj_iteration,
+        "ngram_size" : self.ngram_size,
+        "tolerance_value" : self.tolerance_value,
+        "epochs" : self.epochs,
+        "embedding_dim" : self.embedding_dim,
+        "word2vec_iter_nb" : self.word2vec_iter_nb,
+        "index_fn" : self.index_fn,
+        "keras_model_fn" : self.keras_model_fn,
+        "train_test_history_fn" : self.train_test_history_fn
+        },open(fn,'w'))
+
+import time
+
+class Chronometer:
+    def __init__(self):
+        self.__task_begin_timestamp = {}
+
+    def start(self, task_name):
+        """
+        Start a new task chronometer
+        
+        Parameters
+        ----------
+        task_name : str
+            task id
+        
+        Raises
+        ------
+        ValueError
+            if a running task already exists with that name
+        """
+        if task_name in self.__task_begin_timestamp:
+            raise ValueError(
+                "A running task exists with the name {0}!".format(task_name)
+            )
+        self.__task_begin_timestamp[task_name] = time.time()
+
+    def stop(self, task_name):
+        """
+        Stop and return the duration of the task
+        
+        Parameters
+        ----------
+        task_name : str
+            task id
+        
+        Returns
+        -------
+        float
+            duration of the task in seconds
+        
+        Raises
+        ------
+        ValueError
+            if no task exist with the id `task_name`
+        """
+        if not task_name in self.__task_begin_timestamp:
+            raise ValueError("The {0} task does not exist!".format(task_name))
+        
+        duration = time.time() - self.__task_begin_timestamp[task_name]
+        del self.__task_begin_timestamp[task_name]
+
+        return duration
+
+
+        # Function to calculate the accuracy of our predictions vs labels
+def flat_accuracy(preds, labels):
+    pred_flat = np.argmax(preds, axis=1).flatten()
+    labels_flat = labels.flatten()
+    return np.sum(pred_flat == labels_flat) / len(labels_flat)
+
+
+
+def format_time(elapsed):
+    '''
+    Takes a time in seconds and returns a string hh:mm:ss
+    '''
+    # Round to the nearest second.
+    elapsed_rounded = int(round((elapsed)))
+    
+    # Format as hh:mm:ss
+    return str(datetime.timedelta(seconds=elapsed_rounded))
\ No newline at end of file
diff --git a/lib/utils_geo.py b/lib/utils_geo.py
new file mode 100644
index 0000000..00b8a1a
--- /dev/null
+++ b/lib/utils_geo.py
@@ -0,0 +1,444 @@
+
+import geopandas as gpd
+import numpy as np
+import pandas as pd
+
+from shapely.geometry import Point,box 
+import healpy
+
+from tqdm import tqdm
+
+
+import pandas as pd, numpy as np
+from numba import njit
+from helpers import read_geonames
+from tqdm import tqdm
+from joblib import Parallel,delayed
+
+import tensorflow as tf
+import keras.backend as K
+
+def tf_deg2rad(deg):
+    pi_on_180 = 0.017453292519943295
+    return deg * pi_on_180
+
+# convert lat and lon to a healpix code encoding a region, with a given resolution
+def latlon2healpix( lat , lon , res ):
+    lat = np.radians(lat)
+    lon = np.radians(lon)
+    xs = ( np.cos(lat) * np.cos(lon) ) #
+    ys = ( np.cos(lat) * np.sin(lon) ) # -> Sphere coordinates: https://vvvv.org/blog/polar-spherical-and-geographic-coordinates
+    zs = ( np.sin(lat) ) # 
+    return healpy.vec2pix( int(res) , xs , ys , zs )
+
+def healpix2latlon( code , nside ):
+    xs, ys, zs = healpy.pix2vec( nside , code )
+    lat =  np.arctan2(zs, np.sqrt(xs * xs + ys * ys)) * 180.0 / np.pi 
+    lon =  np.arctan2(ys, xs) * 180.0 / np.pi 
+    return lat, lon
+
+def haversine_tf(y_true,y_pred):
+    """
+    Return the geodesic distance between (lon1,lat1) and (lon2,lat2) coordinates
+    
+    Parameters
+    ----------
+    lon1 : numeric or array-like (pandas Dataframe works also)
+        longitude of first coordinates
+    lat1 :  numeric or array-like (pandas Dataframe works also)
+        latitude of first coordinates
+    lon2 :  numeric or array-like (pandas Dataframe works also)
+        longitude of second coordinates
+    lat2 :  numeric or array-like (pandas Dataframe works also)
+        longitude of second coordinates
+    
+    Returns
+    -------
+    float or array-like
+        distance(s) value(s)
+    """
+    lon1, lat1, lon2, lat2 = map(tf_deg2rad, [y_true[:,0], y_true[:,1], y_pred[:,0], y_pred[:,1]])
+    dlon = lon2 - lon1
+    dlat = lat2 - lat1
+    a = K.sin(dlat/2.0)**2 + K.cos(lat1) * K.cos(lat2) * K.sin(dlon/2.0)**2
+    
+    return 6367 * 2 * tf.math.asin(K.sqrt(a))
+
+def haversine_tf_1circle(y_true,y_pred):
+    """
+    Return the geodesic distance between (lon1,lat1) and (lon2,lat2) coordinates
+    
+    Parameters
+    ----------
+    lon1 : numeric or array-like (pandas Dataframe works also)
+        longitude of first coordinates
+    lat1 :  numeric or array-like (pandas Dataframe works also)
+        latitude of first coordinates
+    lon2 :  numeric or array-like (pandas Dataframe works also)
+        longitude of second coordinates
+    lat2 :  numeric or array-like (pandas Dataframe works also)
+        longitude of second coordinates
+    
+    Returns
+    -------
+    float or array-like
+        distance(s) value(s)
+    """
+    lon1, lat1, lon2, lat2 = map(tf_deg2rad, [y_true[:,0], y_true[:,1], y_pred[:,0], y_pred[:,1]])
+    dlon = lon2 - lon1
+    dlat = lat2 - lat1
+    a = K.sin(dlat/2.0)**2 + K.cos(lat1) * K.cos(lat2) * K.sin(dlon/2.0)**2
+    
+    return 1 * 2 * tf.math.asin(K.sqrt(a))
+
+def to_wgs84_lat(lat):
+    return ((lat*180)-90)
+def to_wgs84_lon(lon):
+    return ((lon*360)-180)
+
+def to_wgs84(x):
+    lon=to_wgs84_lon(x[:,0])
+    lat=to_wgs84_lat(x[:,1])
+    return tf.stack([lon,lat],axis=1)
+
+def accuracy_k(k=100):#km
+    def compute_metric(y_true,y_pred):
+        return K.less_equal(haversine_tf(to_wgs84(y_true),to_wgs84(y_pred)),k) 
+    return compute_metric
+
+def haversine_pd(lon1, lat1, lon2, lat2):
+    """
+    Return the geodesic distance between (lon1,lat1) and (lon2,lat2) coordinates
+    
+    Parameters
+    ----------
+    lon1 : numeric or array-like (pandas Dataframe works also)
+        longitude of first coordinates
+    lat1 :  numeric or array-like (pandas Dataframe works also)
+        latitude of first coordinates
+    lon2 :  numeric or array-like (pandas Dataframe works also)
+        longitude of second coordinates
+    lat2 :  numeric or array-like (pandas Dataframe works also)
+        longitude of second coordinates
+    
+    Returns
+    -------
+    float or array-like
+        distance(s) value(s)
+    """
+    lon1, lat1, lon2, lat2 = map(np.radians, [lon1, lat1, lon2, lat2])
+    dlon = lon2 - lon1
+    dlat = lat2 - lat1
+    a = np.sin(dlat/2.0)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon/2.0)**2
+    
+    return 6367 * 2 * np.arcsin(np.sqrt(a))
+
+
+def get_adjacent(ids,lon1, lat1, lon2, lat2,threshold):
+    dist_ = haversine_pd(lon1, lat1, lon2, lat2)
+    return ids[dist_<threshold]
+
+def get_geonames_adjacency(geoname_data,threshold):
+    return Parallel(n_jobs=-1,backend="multiprocessing")(delayed(get_adjacent)(geoname_data.geonameid.values,
+    geoname_data.longitude,
+    geoname_data.latitude,
+    row.longitude,
+    row.latitude,
+    threshold) for ix,row in tqdm(geoname_data.iterrows(),total=len(geoname_data)))
+
+
+def generate_couple(object_list):
+    """
+    Return a randomly selected couple from an object list.
+    
+    Parameters
+    ----------
+    object_list : list
+        object list
+    
+    Returns
+    -------
+    list
+        list of coupled object
+    """
+    couples = []
+    lst = np.arange(len(object_list))
+    for _ in range(len(object_list)):
+        if len(lst) == 1:
+            break
+        idx = np.random.choice(np.arange(len(lst)))
+        idx2 = np.random.choice(np.arange(len(lst)))
+        while idx2 == idx:
+            idx2 = np.random.choice(np.arange(len(lst)))
+        couples.append([object_list[lst[idx]],object_list[lst[idx2]]])
+        lst = np.delete(lst,idx)
+    return couples
+
+def _hash_couple(o1,o2):
+    """
+    Return an hash for two object ids.
+    
+    Parameters
+    ----------
+    o1 : str or int
+        id of the first objeeect
+    o2 : str of int
+        id of the second object
+    
+    Returns
+    -------
+    str
+        hash
+    """
+    return "|".join(map(str,sorted([int(o1),int(o2)])))
+
+
+
+def zero_one_encoding(long,lat):
+    """
+    Encode coordinates (WGS84) between 0 and 1
+    
+    Parameters
+    ----------
+    long : float
+        longitude value
+    lat : float
+        latitude value
+    
+    Returns
+    -------
+    float,float
+        longitude, latitude
+    """
+    return ((long + 180.0 ) / 360.0), ((lat + 90.0 ) / 180.0) 
+
+class Cell(object):
+    """
+    A cell is box placed in geeographical space.
+    """
+    def __init__(self,upperleft_x,upperleft_y,bottomright_x,bottomright_y,x,y):
+        """
+        Constructor
+        
+        Parameters
+        ----------
+        upperleft_x : float
+            upperleft longitude
+        upperleft_y : float
+            upperleft latitude
+        bottomright_x : float
+            bottom right longitude
+        bottomright_y : float
+            bottom right latitude
+        x : int
+            cell x coordinates in the grid
+        y : int
+            cell y coordinates in the grid
+        """
+        self.upperleft_x,self.upperleft_y,self.bottomright_x,self.bottomright_y = upperleft_x,upperleft_y,bottomright_x,bottomright_y
+        self.box_ = box(self.upperleft_x,self.upperleft_y,self.bottomright_x,self.bottomright_y)
+        self.list_object={} # {id:Point(coord)}
+
+        self.x,self.y = x, y
+
+    def contains(self,lat,lon):
+        """
+        Return true if the cell contains a point at given coordinates
+        
+        Parameters
+        ----------
+        lat : float
+            latitude
+        lon : float
+            longitude
+        
+        Returns
+        -------
+        bool
+            true if contains
+        """ 
+        x,y = lon,lat
+        if x < self.upperleft_x or x > self.bottomright_x:
+            return False
+        if y < self.upperleft_y or y > self.bottomright_y:
+            return False
+        return True
+    
+    def add_object(self,id_,lat,lon):
+        """
+        Connect an object to the cell
+        
+        Parameters
+        ----------
+        id_ : int
+            id
+        lat : float
+            latitude
+        lon : float
+            longitude
+        """
+        self.list_object[id_] = Point(lon,lat)
+            
+    def __repr__(self):
+        return  "upperleft:{0}_{1}_;bottom_right:{2}_{3}".format(self.upperleft_x,self.upperleft_y,self.bottomright_x,self.bottomright_y)
+    
+        
+class Grid(object):
+    """
+    Define a grid 
+    
+    """
+    def __init__(self,upperleft_x,upperleft_y,bottomright_x,bottomright_y,cell_sub_div_index=[100,50]):
+        """
+        Constructor
+        
+        Parameters
+        ----------
+        upperleft_x : float
+            upperleft longitude
+        upperleft_y : float
+            upperleft latitude
+        bottomright_x : float
+            bottom right longitude
+        bottomright_y : float
+            bottom right latitude
+        cell_sub_div_index : list, optional
+            number of division in both latitude and longitude axis (longitude first), by default [100,50]
+        """
+        self.upperleft_x,self.upperleft_y,self.bottomright_x,self.bottomright_y = upperleft_x,upperleft_y,bottomright_x,bottomright_y
+        
+        self.x_r = abs(self.bottomright_x - self.upperleft_x)/cell_sub_div_index[0]
+        self.y_r = abs(self.upperleft_y - self.bottomright_y )/cell_sub_div_index[1]
+        
+        self.c_x_r = self.x_r/cell_sub_div_index[0] # Redivide
+        self.c_y_r = self.y_r/cell_sub_div_index[1]
+        
+        self.cells = []
+        self.inter_cells = []
+        for i in range(cell_sub_div_index[1]):
+            self.cells.append([])
+            for j in range(cell_sub_div_index[0]):
+                self.cells[-1].append(Cell(
+                    self.upperleft_x+j*self.x_r,
+                    self.upperleft_y+i*self.y_r,
+                    self.upperleft_x+((j+1)*self.x_r),
+                    self.upperleft_y+((i+1)*self.y_r),
+                    j,i)
+                )
+        dec_y = 0 
+        for i in range(cell_sub_div_index[1]):
+            self.inter_cells.append([])
+            dec_x = 0 
+            for j in range(cell_sub_div_index[0]):                 
+                self.inter_cells[-1].append(Cell(
+                    self.upperleft_x+(j*self.x_r)-self.c_x_r, # TOP
+                    self.upperleft_y+(i*self.y_r)-dec_y,
+                    self.upperleft_x+((j+1)*self.x_r)-self.c_x_r,#(self.u_pos*self.c_x_r),
+                    self.upperleft_y+((i+1)*self.y_r)+self.c_y_r,
+                    j,i)
+                )
+                self.inter_cells[-1].append(Cell(
+                    self.upperleft_x+(j*self.x_r)-self.c_x_r, # CENTER
+                    self.upperleft_y+(i*self.y_r)-self.c_y_r,
+                    self.upperleft_x+((j+1)*self.x_r)+self.c_x_r,
+                    self.upperleft_y+((i+1)*self.y_r)+self.c_y_r,
+                    j,i)
+                )
+                self.inter_cells[-1].append(Cell(
+                    self.upperleft_x+(j*self.x_r)+dec_x, # CENTER
+                    self.upperleft_y+(i*self.y_r)-self.c_y_r,
+                    self.upperleft_x+((j+1)*self.x_r)-self.c_x_r, #LEFT
+                    self.upperleft_y+((i+1)*self.y_r)+self.c_y_r,
+                    j,i)
+                )
+                dec_x = self.c_x_r
+            dec_y = self.c_y_r
+    
+    def fit_data(self,data = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))):
+        """
+        
+        To avoid unnecessary check when connecting an entity to one or multiple cells, we 
+        filter cells that does not appears in our geographic context (here countries surface).
+        
+        Parameters
+        ----------
+        data : GeoDataFrame
+            geographic context
+        """
+        world = data 
+        world["nn"] = 1
+        dissolved = world.dissolve(by="nn").iloc[0].geometry
+        new_cells= []
+        new_inter_cells=[]
+        for i in tqdm(range(len(self.cells))):
+            for j in range(len(self.cells[i])):
+                if dissolved.intersects(self.cells[i][j].box_):
+                    new_cells.append(self.cells[i][j])
+                    new_inter_cells.extend(self.inter_cells[i][j*3:(j+1)*3])
+                    
+        self.cells=new_cells
+        self.inter_cells = new_inter_cells
+        
+                    
+    def __add__(self,a): 
+        """
+        Add an object to the grid
+        
+        Parameters
+        ----------
+        a : tuple
+            (id, latitude, longitude)
+        """
+        for c1 in range(len(self.cells)):
+            if self.cells[c1].contains(a[1],a[2]):
+                self.cells[c1].add_object(*a)
+                
+        for c1 in range(len(self.inter_cells)):
+            if self.inter_cells[c1].contains(a[1],a[2]):
+                self.inter_cells[c1].add_object(*a)
+                
+    def get_adjacent_relationships(self,random_iteration=10):
+        """
+        Return a list of adjacent relationships founds in each cell.
+        
+        Parameters
+        ----------
+        random_iteration : int, optional
+            number of iteration for random selection of adjacency relationships, by default 10
+        
+        Returns
+        -------
+        list
+            adjacency relationships
+        """
+        relationships = set([])
+        for c1 in tqdm(range(len(self.cells))):
+            for _ in range(random_iteration):
+                for t in generate_couple(list(self.cells[c1].list_object.keys())):
+                    relationships.add(_hash_couple(t[0],t[1]))
+
+        for c1 in tqdm(range(len(self.inter_cells))):
+            for _ in range(random_iteration):
+                for t in generate_couple(list(self.inter_cells[c1].list_object.keys())):
+                    relationships.add(_hash_couple(t[0],t[1]))
+        return relationships
+    
+
+
+def get_adjacency_rels(geodataframe,bounds,subdiv_tuple,random_iter_adjacency):
+    g = Grid(*bounds,subdiv_tuple)
+    g.fit_data()
+    [g+(int(row.geonameid),row.latitude,row.longitude) for ix,row in tqdm(geodataframe["geonameid longitude latitude".split()].iterrows(),total=len(geodataframe))]
+    return [[int(i) for i in r.split("|")] for r in g.get_adjacent_relationships(random_iter_adjacency)]
+
+def get_geonames_inclusion_rel(geonames_data,geonames_hierarchy_data_fn):
+    geonames_hierarchy_data = pd.read_csv(geonames_hierarchy_data_fn,sep="\t",header=None,names="parentId,childId,type".split(",")).fillna("")
+    geonamesIDS = set(geonames_data.geonameid.values)
+    filter_mask = (geonames_hierarchy_data.childId.isin(geonamesIDS) & geonames_hierarchy_data.parentId.isin(geonamesIDS))
+    return (geonames_hierarchy_data[filter_mask]["childId parentId".split()].values.tolist())
+
+def get_bounds(geodataframe):
+    geodataframe["geometry"] = geodataframe["longitude latitude".split()].apply(lambda x: Point(x.longitude,x.latitude),axis=1)
+    geodataframe = gpd.GeoDataFrame(geodataframe)
+    geodataframe["i"]=1
+    return geodataframe.dissolve("i").bounds.values[0] # Required to get adjacency relationships
diff --git a/lib/word_index.py b/lib/word_index.py
new file mode 100644
index 0000000..98e66f8
--- /dev/null
+++ b/lib/word_index.py
@@ -0,0 +1,180 @@
+import json
+
+import numpy as np
+
+from ngram import NGram
+
+# Machine learning 
+from gensim.models import Word2Vec
+
+class WordIndex():
+    """
+    Class used for encoding words in ngram representation
+    """
+    def __init__(self,loaded = False):
+        """
+        Constructor
+        
+        Parameters
+        ----------
+        loaded : bool
+            if loaded from external file
+        """
+        self.ngram_index = {"":0}
+        self.index_ngram = {0:""}
+        self.cpt = 0
+        self.max_len = 0
+
+        self.loaded = loaded
+
+    def split_and_add(self,word):
+        """
+        Split word in multiple ngram and add each one of them to the index
+        
+        Parameters
+        ----------
+        word : str
+            a word
+        """
+        grams = word.lower().split(" ")
+        [self.add(subword) for subword in grams ]
+        self.max_len = max(self.max_len,len(grams))
+
+    def add(self,subword):
+        """
+        Add a ngram to the index
+        
+        Parameters
+        ----------
+        ngram : str
+            ngram
+        """
+        if not subword in self.ngram_index:
+            self.cpt+=1
+            self.ngram_index[subword]=self.cpt
+            self.index_ngram[self.cpt]=subword
+        
+
+    def encode(self,word):
+        """
+        Return a ngram representation of a word
+        
+        Parameters
+        ----------
+        word : str
+            a word
+        
+        Returns
+        -------
+        list of int
+            listfrom shapely.geometry import Point,box
+ of ngram index
+        """
+        subwords = [w.lower() for w in word.split(" ")]
+        if not self.loaded:
+            [self.add(ng) for ng in subwords if not ng in self.ngram_index]
+        if self.max_len < len(subwords):
+            self.max_len = max(self.max_len,len(subwords))
+        return self.complete([self.ngram_index[ng] for ng in subwords if ng in self.ngram_index],self.max_len)
+
+    def complete(self,ngram_encoding,MAX_LEN,filling_item=0):
+        """
+        Complete a ngram encoded version of word with void ngram. It's necessary for neural network.
+        
+        Parameters
+        ----------
+        ngram_encoding : list of int
+            first encoding of a word
+        MAX_LEN : int
+            desired length of the encoding
+        filling_item : int, optional
+            ngram index you wish to use, by default 0
+        
+        Returns
+        -------
+        list of int
+            list of ngram index
+        """
+        if self.loaded and len(ngram_encoding) >=MAX_LEN:
+            return ngram_encoding[:MAX_LEN]
+        assert len(ngram_encoding) <= MAX_LEN
+        diff = MAX_LEN - len(ngram_encoding)
+        ngram_encoding.extend([filling_item]*diff)  
+        return ngram_encoding
+    
+    def get_embedding_layer(self,texts,dim=100,**kwargs):
+        """
+        Return an embedding matrix for each ngram using encoded texts. Using gensim.Word2vec model.
+        
+        Parameters
+        ----------
+        texts : list of [list of int]
+            list of encoded word
+        dim : int, optional
+            embedding dimension, by default 100
+        
+        Returns
+        -------
+        np.array
+            embedding matrix
+        """
+        model = Word2Vec([[str(w) for w in t] for t in texts], size=dim,window=5, min_count=1, workers=4,**kwargs)
+        N = len(self.ngram_index)
+        embedding_matrix = np.zeros((N,dim))
+        for i in range(N):
+            if str(i) in model.wv:
+                embedding_matrix[i] = model.wv[str(i)]
+        return embedding_matrix
+
+    def save(self,fn):
+        """
+
+        Save the NgramIndex
+        
+        Parameters
+        ----------
+        fn : str
+            output filename
+        """
+        data = {
+            "word_index": self.ngram_index,
+            "cpt_state": self.cpt,
+            "max_len_state": self.max_len
+        }
+        json.dump(data,open(fn,'w'))
+
+    @staticmethod
+    def load(fn):
+        """
+        
+        Load a NgramIndex state from a file.
+        
+        Parameters
+        ----------
+        fn : str
+            input filename
+        
+        Returns
+        -------
+        NgramIndex
+            ngram index
+        
+        Raises
+        ------
+        KeyError
+            raised if a required field does not appear in the input file
+        """
+        try:
+            data = json.load(open(fn))
+        except json.JSONDecodeError:
+            print("Data file must be a JSON")
+        for key in ["word_index","cpt_state","max_len_state"]:
+            if not key in data:
+                raise KeyError("{0} field cannot be found in given file".format(key))
+        new_obj = WordIndex(loaded=True)
+        new_obj.ngram_index = data["ngram_index"]
+        new_obj.index_ngram = {v:k for k,v in new_obj.ngram_index.items()}
+        new_obj.cpt = data["cpt_state"]
+        new_obj.max_len = data["max_len_state"]
+        return new_obj
+
diff --git a/parser_config/toponym_combination_embedding.json b/parser_config/toponym_combination_embedding.json
new file mode 100644
index 0000000..260d6ec
--- /dev/null
+++ b/parser_config/toponym_combination_embedding.json
@@ -0,0 +1,20 @@
+{
+    "description": "Toponym Combination",
+    "args": [
+        { "short": "geoname_input", "help": "Filepath of the Geonames file you want to use." },
+        { "short": "geoname_hierachy_input", "help": "Filepath of the Geonames file you want to use." },
+        { "short": "-v", "long": "--verbose", "action": "store_true" },
+        { "short": "-i", "long": "--inclusion", "action": "store_true" },
+        { "short": "-a", "long": "--adjacency", "action": "store_true" },
+        { "short": "-w", "long": "--wikipedia-cooc", "action": "store_true" },
+        { "long": "--wikipedia-cooc-fn","help":"Cooccurrence data filename"},
+        { "long": "--cooc-sample-size", "type": "int", "default": 1 },
+        {"long": "--adjacency-iteration", "type":"int","default":1},
+        { "short": "-n", "long": "--ngram-size", "type": "int", "default": 4 },
+        { "long": "--ngram-word2vec-iter", "type": "int", "default": 50 },
+        { "short": "-t", "long": "--tolerance-value", "type": "float", "default": 0.002 },
+        { "short": "-e", "long": "--epochs", "type": "int", "default": 100 },
+        { "short": "-d", "long": "--dimension", "type": "int", "default": 256 },
+        {  "long": "--admin_code_1", "default": "None" }
+    ]
+}
\ No newline at end of file
diff --git a/parser_config/toponym_combination_embedding_v2.json b/parser_config/toponym_combination_embedding_v2.json
new file mode 100644
index 0000000..345c1d7
--- /dev/null
+++ b/parser_config/toponym_combination_embedding_v2.json
@@ -0,0 +1,20 @@
+{
+    "description": "Toponym Combination",
+    "args": [
+        { "short": "geoname_input", "help": "Filepath of the Geonames file you want to use." },
+        { "short": "geoname_hierachy_input", "help": "Filepath of the Geonames file you want to use." },
+        { "short": "-v", "long": "--verbose", "action": "store_true" },
+        { "short": "-i", "long": "--inclusion", "action": "store_true" },
+        { "short": "-a", "long": "--adjacency", "action": "store_true" },
+        { "short": "-w", "long": "--wikipedia-cooc", "action": "store_true" },
+        { "long": "--wikipedia-cooc-fn","help":"Cooccurrence data filename"},
+        { "long": "--cooc-sample-size", "type": "int", "default": 1 },
+        {"long": "--adjacency-iteration", "type":"int","default":1},
+        { "short": "-n", "long": "--ngram-size", "type": "int", "default": 4 },
+        { "long": "--ngram-word2vec-iter", "type": "int", "default": 50 },
+        { "short": "-t", "long": "--tolerance-value", "type": "float", "default": 100 },
+        { "short": "-e", "long": "--epochs", "type": "int", "default": 100 },
+        { "short": "-d", "long": "--dimension", "type": "int", "default": 256 },
+        {  "long": "--admin_code_1", "default": "None" }
+    ]
+}
\ No newline at end of file
diff --git a/parser_config/toponym_combination_embedding_v3.json b/parser_config/toponym_combination_embedding_v3.json
new file mode 100644
index 0000000..507e9c5
--- /dev/null
+++ b/parser_config/toponym_combination_embedding_v3.json
@@ -0,0 +1,20 @@
+{
+    "description": "Toponym Combination",
+    "args": [
+        { "short": "dataset_name", "help": "Filepath of the Geonames file you want to use." },
+        { "short": "geoname_inclusion", "help": "Filepath of the Geonames file you want to use." },
+        { "short": "geonames_adjacent", "help": "Filepath of the Geonames file you want to use." },
+        { "long": "wikipedia_cooc", "help": "Cooccurrence data filename" },
+        { "short": "-v", "long": "--verbose", "action": "store_true" },
+        { "short": "-i", "long": "--inclusion", "action": "store_true" },
+        { "short": "-a", "long": "--adjacency", "action": "store_true" },
+        { "short": "-w", "long": "--wikipedia", "action": "store_true" },
+        { "short": "-n", "long": "--ngram-size", "type": "int", "default": 4 },
+        { "long": "--ngram-word2vec-iter", "type": "int", "default": 50 },
+        { "short": "-t", "long": "--tolerance-value", "type": "float", "default": 100 },
+        { "short": "-e", "long": "--epochs", "type": "int", "default": 100 },
+        { "short": "-d", "long": "--dimension", "type": "int", "default": 256 },
+        { "short": "-l", "long": "--lstm-layer", "type": "int", "default": 2, "choices": [1, 2] },
+        { "long": "--tokenization-method", "type": "str", "default": "char-level", "choices": ["char-level", "word-level", "bert"] }
+    ]
+}
\ No newline at end of file
diff --git a/predict_toponym_coordinates.py b/predict_toponym_coordinates.py
new file mode 100644
index 0000000..ec5d967
--- /dev/null
+++ b/predict_toponym_coordinates.py
@@ -0,0 +1,133 @@
+from keras.models import load_model
+import os
+import tensorflow as tf
+import keras.backend as K
+from lib.ngram_index import NgramIndex
+from lib.word_index import WordIndex
+import numpy as np
+
+from tensorflow.python.keras.backend import set_session
+from tensorflow.python.keras.models import load_model
+
+
+from lib.utils_geo import haversine_tf_1circle
+sess = None
+graph = None
+
+def lat_accuracy(LAT_TOL =1/180.):
+    def accuracy_at_k_lat(y_true, y_pred):
+        """
+        Metrics use to measure the accuracy of the coordinate prediction. But in comparison to the normal accuracy metrics, we add a tolerance threshold due to the (quasi) impossible 
+        task for neural network to obtain the exact  coordinate.
+
+        Parameters
+        ----------
+        y_true : tf.Tensor
+            truth data
+        y_pred : tf.Tensor
+            predicted output
+        """
+        diff = tf.abs(y_true - y_pred)
+        fit = tf.dtypes.cast(tf.less(diff,LAT_TOL),tf.int64)
+        return tf.reduce_sum(fit)/tf.size(y_pred,out_type=tf.dtypes.int64)
+    return accuracy_at_k_lat
+
+def lon_accuracy(LON_TOL=1/360.):
+    def accuracy_at_k_lon(y_true, y_pred):
+        """
+        Metrics use to measure the accuracy of the coordinate prediction. But in comparison to the normal accuracy metrics, we add a tolerance threshold due to the (quasi) impossible 
+        task for neural network to obtain the exact  coordinate.
+
+        Parameters
+        ----------
+        y_true : tf.Tensor
+            truth data
+        y_pred : tf.Tensor
+            predicted output
+        """
+        diff = tf.abs(y_true - y_pred)
+        fit = tf.dtypes.cast(tf.less(diff,LON_TOL),tf.int64)
+        return tf.reduce_sum(fit)/tf.size(y_pred,out_type=tf.dtypes.int64)
+    return accuracy_at_k_lon
+
+class Geocoder(object):
+    """
+    >>>geocoder = Geocoder("LSTM_FR.txt_20_4_0.002_None_A_I_C.h5","index_4gram_FR_backup.txt")
+    >>>lon,lat = geocoder.get_coord("Paris","New-York")
+    >>>lon,lat = geocoder.wgs_coord(lon,lat)
+    >>>geocoder.plot_coord("Paris,New-York",lat,lon)
+
+    if you want an interactive map using leafletJS, set to True the `interactive_map` parameter of `Geocoder.plot_coord()`
+    """
+    def __init__(self,keras_model_fn,ngram_index_file):
+        # global sess
+        # global graph
+        # sess = tf.compat.v1.Session()
+        # graph = tf.compat.v1.get_default_graph()
+        # set_session(sess)
+        self.keras_model = load_model(keras_model_fn,custom_objects={"loss":haversine_tf_1circle},compile=False)#custom_objects={"accuracy_at_k_lat":lat_accuracy(),"accuracy_at_k_lon":lon_accuracy()})
+        self.ngram_encoder = NgramIndex.load(ngram_index_file)
+
+    def get_coord(self,toponym,context_toponym):
+        global sess
+        global graph
+        p = self.ngram_encoder.complete(self.ngram_encoder.encode(toponym),self.ngram_encoder.max_len)
+        c = self.ngram_encoder.complete(self.ngram_encoder.encode(context_toponym),self.ngram_encoder.max_len)
+        p = np.array(p)
+        c = np.array(c)       
+        # with sess.as_default():
+        #     with graph.as_default():
+        coord = self.keras_model.predict([[p],[c]])
+        return coord[0][0],coord[0][1]
+    
+    def get_coords(self,list_toponym,list_toponym_context):
+        p = [self.ngram_encoder.complete(self.ngram_encoder.encode(toponym),self.ngram_encoder.max_len) for toponym in list_toponym]
+        c = [self.ngram_encoder.complete(self.ngram_encoder.encode(toponym),self.ngram_encoder.max_len) for toponym in list_toponym_context]
+
+        p = np.array(p)
+        c = np.array(c)
+        
+        coords = self.keras_model.predict([p,c])
+        return coords[0],coords[1]
+
+    def wgs_coord(self,lon,lat):
+        return ((lon*360)-180),((lat*180)-90)
+    
+    def plot_coord(self,toponym,lat,lon,interactive_map=False,**kwargs):
+        if interactive_map:
+            import folium
+            import tempfile
+            import webbrowser
+            fp = tempfile.NamedTemporaryFile(delete=False)
+            m = folium.Map()
+            folium.Marker([lat, lon], popup=toponym).add_to(m)
+            m.save(fp.name)
+            webbrowser.open('file://' + fp.name)
+        else:
+            import matplotlib.pyplot as plt
+            import geopandas
+            fig, ax = plt.subplots(1,**kwargs)
+            world = geopandas.read_file(geopandas.datasets.get_path('naturalearth_lowres'))
+            world.plot(color='white', edgecolor='black',ax=ax)
+            ax.plot(lon,lat,marker='o', color='red', markersize=5)
+            plt.show()
+
+
+
+if __name__ == "__main__":
+    from flask import Flask, escape, request, render_template
+
+    app = Flask(__name__)
+
+
+    geocoder = Geocoder("outputs/LSTM_FR.txt_100_4_0.002_None_A_I_C.h5","./outputs/FR.txt_100_4_0.002_None_A_I_C_index")
+
+    @app.route('/',methods=["GET"])
+    def display():
+        toponym = request.args.get("top", "Paris")
+        c_toponym = request.args.get("c_top", "Cherbourg")
+        lon,lat = geocoder.get_coord(toponym,c_toponym)
+        lon,lat = geocoder.wgs_coord(lon,lat)
+        return  render_template("skeleton.html",lat=lat,lon=lon)
+
+    app.run(host='0.0.0.0')
\ No newline at end of file
diff --git a/region_model.py b/region_model.py
new file mode 100644
index 0000000..b7a6673
--- /dev/null
+++ b/region_model.py
@@ -0,0 +1,199 @@
+# Base module 
+import os
+
+# Structure
+import pandas as pd
+
+# DEEPL module
+from keras.layers import Dense, Input, Embedding,concatenate,Bidirectional,LSTM,Dropout
+from keras.models import Model
+from keras.callbacks import ModelCheckpoint
+from tensorflow.keras.layers import Lambda
+import keras.backend as K 
+import tensorflow as tf 
+from lib.custom_layer import *
+
+# Custom module
+from lib.ngram_index import NgramIndex
+from lib.utils import ConfigurationReader, MetaDataSerializer,LabelEncoder
+from lib.metrics import lat_accuracy,lon_accuracy
+from lib.data_generator import DataGenerator,CoOccurrences,load_embedding,Inclusion,Adjacency
+from lib.utils_geo import haversine_tf,accuracy_k,haversine_tf_1circle
+
+# Logging
+import logging
+
+logging.getLogger('gensim').setLevel(logging.WARNING)
+
+from helpers import EpochTimer
+
+# LOGGING CONF
+logging.basicConfig(
+    format='[%(asctime)s][%(levelname)s] %(message)s ', 
+    datefmt='%m/%d/%Y %I:%M:%S %p',
+    level=logging.INFO  
+    )
+
+args = ConfigurationReader("./parser_config/toponym_combination_embedding_v2.json")\
+    .parse_args()#("-i --inclusion-fn ../data/geonamesData/hierarchy.txt ../data/geonamesData/allCountries.txt ../data/embeddings/word2vec4gram/4gramWiki+geonames_index.json ../data/embeddings/word2vec4gram/embedding4gramWiki+Geonames.bin".split())
+
+#.parse_args("-w  --wikipedia-cooc-fn  subsetCoocALLv2.csv ../data/geonamesData/allCountries.txt ../data/embeddings/word2vec4gram/4gramWiki+geonames_index.json ../data/embeddings/word2vec4gram/embedding4gramWiki+Geonames.bin".split())
+
+#
+#################################################
+############# MODEL TRAINING PARAMETER ##########
+#################################################
+NGRAM_SIZE = args.ngram_size
+ACCURACY_TOLERANCE = args.k_value
+EPOCHS = args.epochs
+ADJACENCY_SAMPLING = args.adjacency_sample
+COOC_SAMPLING = args.cooc_sample
+WORDVEC_ITER = 50
+EMBEDDING_DIM = args.dimension
+BATCH_SIZE = args.batch_size
+#################################################
+########## FILENAME VARIABLE ####################
+#################################################
+# check for output dir
+if not os.path.exists("outputs/"):
+    os.makedirs("outputs/")
+
+GEONAME_FN = args.geoname_input
+DATASET_NAME = args.geoname_input.split("/")[-1]
+GEONAMES_HIERARCHY_FN = args.inclusion_fn
+ADJACENCY_REL_FILENAME = args.adjacency_fn
+COOC_FN = args.wikipedia_cooc_fn
+
+PREFIX_OUTPUT_FN = "REGION_{0}_{1}_{2}_{3}".format(
+    GEONAME_FN.split("/")[-1],
+    EPOCHS,
+    NGRAM_SIZE,
+    ACCURACY_TOLERANCE)
+
+REL_CODE=""
+if args.adjacency:
+    PREFIX_OUTPUT_FN += "_A"
+    REL_CODE+= "A"
+if args.inclusion:
+    PREFIX_OUTPUT_FN += "_I"
+    REL_CODE+= "I"
+if args.wikipedia_cooc:
+    PREFIX_OUTPUT_FN += "_C"
+    REL_CODE+= "C"
+
+MODEL_OUTPUT_FN = "outputs/{0}.h5".format(PREFIX_OUTPUT_FN)
+INDEX_FN = "outputs/{0}_index".format(PREFIX_OUTPUT_FN)
+HISTORY_FN = "outputs/{0}.csv".format(PREFIX_OUTPUT_FN)
+
+
+meta_data = MetaDataSerializer(
+    DATASET_NAME,
+    REL_CODE,
+    COOC_SAMPLING,
+    ADJACENCY_SAMPLING,
+    NGRAM_SIZE,
+    ACCURACY_TOLERANCE,
+    EPOCHS,
+    EMBEDDING_DIM,
+    WORDVEC_ITER,
+    INDEX_FN,
+    MODEL_OUTPUT_FN,
+    HISTORY_FN
+)
+meta_data.save("outputs/{0}.json".format(PREFIX_OUTPUT_FN))
+
+
+### PUT DATASRC + GENERATOR
+
+index = NgramIndex.load(args.ngram_index_fn)
+
+train_src = []
+test_src = []
+
+class_encoder = LabelEncoder()
+if args.wikipedia_cooc:
+    train_src.append(CoOccurrences(COOC_FN + "_train.csv",class_encoder,sampling=4))
+    test_src.append(CoOccurrences(COOC_FN + "_test.csv",class_encoder,sampling=4))
+
+if args.adjacency:
+    a_train = Adjacency(ADJACENCY_REL_FILENAME + "_train.csv",GEONAME_FN,sampling=ADJACENCY_SAMPLING,gzip=False)
+    a_test = Adjacency(ADJACENCY_REL_FILENAME + "_test.csv",GEONAME_FN,sampling=ADJACENCY_SAMPLING,gzip=False)
+    train_src.append(a_train)
+    test_src.append(a_test)
+
+if args.inclusion:
+    i_train = Inclusion(GEONAME_FN,GEONAMES_HIERARCHY_FN+"_train.csv")
+    i_test = Inclusion(GEONAME_FN,GEONAMES_HIERARCHY_FN+"_test.csv")
+    train_src.append(i_train)
+    test_src.append(i_test)
+#Adjacency
+
+
+
+d_train = DataGenerator(train_src,index,class_encoder,batch_size=BATCH_SIZE,only_healpix=True) 
+d_test = DataGenerator(test_src,index,class_encoder,batch_size=BATCH_SIZE,only_healpix=True) 
+
+num_words = len(index.index_ngram)  
+
+#############################################################################################
+################################# NGRAM EMBEDDINGS ##########################################
+#############################################################################################
+
+embedding_weights = load_embedding(args.embedding_fn) 
+
+
+#############################################################################################
+################################# MODEL DEFINITION ##########################################
+#############################################################################################
+
+from keras import regularizers
+
+input_1 = Input(shape=(index.max_len,))
+input_2 = Input(shape=(index.max_len,))
+
+embedding_layer = Embedding(num_words, EMBEDDING_DIM,input_length=index.max_len,trainable=False)#, trainable=True)
+
+x1 = embedding_layer(input_1)
+x2 = embedding_layer(input_2)
+
+# Each LSTM learn on a permutation of the input toponyms
+biLSTM = Bidirectional(LSTM(32,activation="pentanh", recurrent_activation="pentanh"))
+x1 = biLSTM(x1)
+x2 = biLSTM(x2)
+x = concatenate([x1,x2])#,x3])
+
+#x = Dense(class_encoder.get_num_classes()*2,activation="relu")(x)
+
+
+aux_layer = Dense(class_encoder.get_num_classes(),activation="softmax",name="aux_layer")(x)
+
+model = Model(inputs = [input_1,input_2], outputs = aux_layer)#input_3
+
+model.compile(loss={"aux_layer":"categorical_crossentropy"}, optimizer='adam',metrics={"aux_layer":"accuracy"})
+
+
+#############################################################################################
+################################# TRAINING LAUNCH ###########################################
+#############################################################################################
+
+checkpoint = ModelCheckpoint(MODEL_OUTPUT_FN + ".part", monitor='loss', verbose=1,
+    save_best_only=True, mode='auto', period=1)
+
+epoch_timer = EpochTimer("outputs/"+PREFIX_OUTPUT_FN+"_epoch_timer_output.csv")
+
+
+history = model.fit_generator(generator=d_train,
+    validation_data=d_test,
+    verbose=True,
+    epochs=EPOCHS,
+    callbacks=[checkpoint,epoch_timer])
+
+
+hist_df = pd.DataFrame(history.history)
+hist_df.to_csv(HISTORY_FN)
+
+model.save(MODEL_OUTPUT_FN)
+
+# Erase Model Checkpoint file
+if os.path.exists(MODEL_OUTPUT_FN + ".part"):
+    os.remove(MODEL_OUTPUT_FN + ".part")
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..a2016e7
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,27 @@
+#pyroutelib3
+node2vec
+#osrm
+geopandas
+pandas
+numpy
+tqdm
+networkx
+matplotlib
+joblib
+gensim
+sklearn
+tensorflow
+keras
+ngram
+shapely
+sqlitedict
+nltk
+folium
+flask
+numba
+healpy
+stanza
+spacy
+torch
+torchvision
+transformers
\ No newline at end of file
diff --git a/run_multiple_configurations.py b/run_multiple_configurations.py
new file mode 100644
index 0000000..49753c5
--- /dev/null
+++ b/run_multiple_configurations.py
@@ -0,0 +1,22 @@
+from lib.run import GridSearchModel
+from collections import OrderedDict
+c_f = "--wikipedia-cooc-fn ../data/wikipedia/cooccurrence_FR.txt"
+
+# Init GridsearchModel
+grid = GridSearchModel(\
+    "python3 combination_embeddingsv3inverse.py",
+    **OrderedDict({ # necessary because some args have to be given in a certain order
+    "rel":["-w "+c_f,("-i -w "+c_f),"-a -w "+c_f,"-a -i -w "+c_f], # ,"-a -i -w "+c_f ,"-i -a"
+    "-n":[4],
+    "--ngram-word2vec-iter" :[100],
+    "-e":[100],
+    "geoname_fn":"../data/geonamesData/FR.txt".split(),
+    "hierarchy_fn":"../data/geonamesData/hierarchy.txt".split()
+    }.items()))
+
+print("########### THE FOLLOWING COMMAND(S) WILL BE EXECUTED ###########" )
+[print(task.get_command()) for task in grid.tasks]
+print("#################################################################")
+grid.run("outputs/log_{0}".format("FR_model_v2"))
+
+#["-w --wikipedia-cooc-fn ../data/wikipedia/cooccurrence_FR.txt","-w --wikipedia-cooc-fn ../data/wikipedia/cooccurrence_FR.txt -a","-w --wikipedia-cooc-fn ../data/wikipedia/cooccurrence_FR.txt -i"]
\ No newline at end of file
diff --git a/scripts/embeddingngram.py b/scripts/embeddingngram.py
new file mode 100644
index 0000000..a9773eb
--- /dev/null
+++ b/scripts/embeddingngram.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+# coding: utf-8
+
+
+from lib.ngram_index import NgramIndex
+from lib.utils_geo import read_geonames
+
+
+
+import pandas as pd
+import numpy as np
+from tqdm import tqdm
+
+
+from tqdm import tqdm
+
+
+
+from gensim.models import Word2Vec
+import logging
+logging.basicConfig(level="INFO")
+
+
+
+df_cooc = pd.read_csv("../data/wikipedia/cooccurrence_ALL.txt",sep="\t")
+df_geo = read_geonames("../data/geonamesData/allCountries.txt") 
+
+
+geonames_label = df_geo.name.values.tolist()
+wiki_labels = df_cooc.title.values.tolist()
+p= [wiki_labels.extend(x.split("|")) for x in df_cooc["interlinks"].values]
+
+
+del df_geo
+del df_cooc
+
+N = 5
+
+
+ng = NgramIndex(N)
+p = [ng.split_and_add(x) for x in tqdm(geonames_label)]
+p = [ng.split_and_add(x) for x in tqdm(wiki_labels)]
+ng.save("{0}gramWiki+Geonames_index.json".format(N))
+
+geonames_label.extend(wiki_labels)
+
+class MySentences(object):
+    def __init__(self, texts):
+        self.texts = texts
+
+    def __iter__(self):
+        for w in self.texts:
+            yield [str(x)for x in ng.encode(w)]
+
+model = Word2Vec(MySentences(geonames_label), size=100, window=5, min_count=1, workers=4,sg=1)
+model.save("embedding{0}gramWiki+Geonames.bin".format(5))
+
+
+
diff --git a/scripts/generate_cooc_geocoding_dataset.py b/scripts/generate_cooc_geocoding_dataset.py
new file mode 100644
index 0000000..232f40b
--- /dev/null
+++ b/scripts/generate_cooc_geocoding_dataset.py
@@ -0,0 +1,41 @@
+import pandas as pd 
+import re
+
+#### TODO NEED TO add ARGPARSE !!!
+def parse_title_wiki(title_wiki):
+    """
+    Parse Wikipedia title
+    
+    Parameters
+    ----------
+    title_wiki : str
+        wikipedia title
+    
+    Returns
+    -------
+    str
+        parsed wikipedia title
+    """
+    return re.sub("\(.*\)", "", title_wiki).strip().lower()
+
+
+df = pd.read_csv("./cooccurrence_US_FR.txt",sep="\t")
+
+df["interlinks"] = df.interlinks.apply(lambda x : x.split("|"))
+df["interlinks"] = df.interlinks.apply(lambda x : [parse_title_wiki(i) for i in x])
+
+df["title"] = df.title.apply(parse_title_wiki)
+
+def generated_inputs(x):
+    output = []
+    for interlink in x.interlinks:
+        output.append([x.title,interlink,x.longitude,x.latitude])
+    return output
+
+output_ =  []
+for ix,row in df.iterrows():
+    output_.extend(generated_inputs(row))
+
+new_df = pd.DataFrame(output_,columns="name1 name2 longitude latitude".split())  
+new_df = new_df.sample(frac=1)
+new_df.to_csv("us_fr_cooc_test.csv",index=False)
\ No newline at end of file
diff --git a/scripts/get_all_adjacency_rel.py b/scripts/get_all_adjacency_rel.py
new file mode 100644
index 0000000..23382a6
--- /dev/null
+++ b/scripts/get_all_adjacency_rel.py
@@ -0,0 +1,88 @@
+import pandas as pd, numpy as np
+from numba import njit
+from helpers import read_geonames
+from tqdm import tqdm
+from joblib import Parallel,delayed
+import geopandas as gpd
+from lib.utils_geo import Grid,haversine_pd
+import matplotlib.pyplot as plt
+
+import argparse
+
+parser = argparse.ArgumentParser()
+
+parser.add_argument("geoname_fn")
+parser.add_argument("kilometer_threshold",type=int,default=20)
+parser.add_argument("output_fn_prefix")
+
+args = parser.parse_args("../data/geonamesData/allCountries.txt 20 /home/jacques/ALL_ADJ_224+_".split())
+
+GEONAME_FN = args.geoname_fn
+PREFIX_OUTPUT_FN = args.output_fn_prefix
+KM_THRESHOLD = args.kilometer_threshold
+
+df = read_geonames(GEONAME_FN)
+
+def to_str(list_):
+    """
+    Return str representation for each value in list_
+    
+    Parameters
+    ----------
+    list_ : array
+        array
+    
+    Returns
+    -------
+    array
+        str list
+    """
+    return list(map(str,list_))
+
+def get_adjacent(geonameid,ids,lon1, lat1, lon2, lat2,threshold):
+    """
+    Write adjacent entry in geonames for a selected entry
+    """
+    dist_ = haversine_pd(lon1, lat1, lon2, lat2)
+    adj_ids = ids[dist_<threshold]
+    out_.write("\n{0},{1},{2},{3}".format(geonameid,"|".join(to_str(adj_ids)),lat2,lon2))
+    out_.flush()
+
+
+# WE BUILD a grid over the world map
+# It allows to limit unnecessary calculus thus accelerate the whole process
+world = gpd.read_file("/media/jacques/DATA/GEODATA/WORLD/world.geo.50m.dissolved")
+g = Grid(*world.bounds.values[0],[40,20]) #We build a grid of cell of 40° by 20°
+g.fit_data(world)
+
+# Prepare first output
+first_output_fn = "{1}{0}_cells.csv".format(KM_THRESHOLD,PREFIX_OUTPUT_FN)
+out_ = open(first_output_fn,'w')
+out_.write("geonameid,adjacent_geonameid,latitude,longitude") # HEADER
+out_.flush() # Avoid writing bugs
+
+def get_rels(cells_list):
+    for c in tqdm(cells_list):
+        
+        mask1 = (df.latitude <= c.bottomright_y) & (df.latitude >= c.upperleft_y)
+        new_df = df[mask1].copy() 
+        mask2 = (new_df.longitude >= c.upperleft_x) & (new_df.longitude <= c.bottomright_x)
+        new_df = new_df[mask2]
+        for ix,row in new_df.iterrows():
+            get_adjacent(row.geonameid,new_df.geonameid.values,new_df.longitude,new_df.latitude,row.longitude,row.latitude,KM_THRESHOLD)
+        #Parallel(n_jobs=-1,backend="multiprocessing",temp_folder="/home/jacques/temp/")(delayed(get_adjacent)(row.geonameid,new_df.geonameid.values,new_df.longitude,new_df.latitude,row.longitude,row.latitude,KM_THRESHOLD) for ix,row in new_df.iterrows())
+
+world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
+ax = world.plot(color="white",edgecolor="black")
+for c in g.cells[224:]:
+    ax.plot(*c.box_.exterior.xy)
+plt.show()
+get_rels(g.cells[224:]) #~3h
+
+# Prepare second output
+# second_output_fn = "{1}{0}_inter_cells.csv".format(KM_THRESHOLD,PREFIX_OUTPUT_FN)
+# out_ = open(second_output_fn,'w')
+# out_.write("geonameid,adjacent_geonameid,latitude,longitude") # HEADER
+# out_.flush()# Avoid writing bugs
+
+# get_rels(g.inter_cells) 594
diff --git a/scripts/get_cooccurrence.py b/scripts/get_cooccurrence.py
new file mode 100644
index 0000000..4f2bced
--- /dev/null
+++ b/scripts/get_cooccurrence.py
@@ -0,0 +1,40 @@
+import gzip
+import json
+import re
+
+import argparse
+
+import pandas as pd
+
+from joblib import Parallel,delayed
+from tqdm import tqdm
+
+parser = argparse.ArgumentParser()
+
+parser.add_argument("page_of_interest_fn")
+parser.add_argument("output_fn")
+parser.add_argument("-c","--corpus",action="append")
+
+args = parser.parse_args()#("../wikidata/sample/place_en_fr_page_clean_onlyfrplace.csv test.txt -c frwiki-latest.json.gz -c enwiki-latest.json.gz".split())
+
+PAGES_OF_INTEREST_FILE = args.page_of_interest_fn
+WIKIPEDIA_CORPORA = args.corpus
+OUTPUT_FN = args.output_fn
+
+if len(WIKIPEDIA_CORPORA)<1:
+    raise Exception('No corpora was given!')
+
+df = pd.read_csv(PAGES_OF_INTEREST_FILE)
+page_of_interest = set(df.title.values)
+
+page_coord = {row.title : (row.longitude,row.latitude) for ix,row in df.iterrows()}
+
+output = open(OUTPUT_FN,'w')
+output.write("title\tinterlinks\tlongitude\tlatitude\n")
+for wikipedia_corpus in WIKIPEDIA_CORPORA:
+    for line in tqdm(gzip.GzipFile(wikipedia_corpus,'rb')):
+        data = json.loads(line)
+        if data["title"] in page_of_interest:
+            occ = page_of_interest.intersection(data["interlinks"].keys())
+            coord = page_coord[data["title"]]
+            if len(occ) >0:output.write(data["title"]+"\t"+"|".join(occ)+"\t{0}\t{1}".format(*coord)+"\n")
diff --git a/scripts/gethealpix.py b/scripts/gethealpix.py
new file mode 100644
index 0000000..6e572fd
--- /dev/null
+++ b/scripts/gethealpix.py
@@ -0,0 +1,32 @@
+
+
+import pandas as pd
+
+from tqdm import tqdm
+tqdm.pandas()
+import argparse
+
+import numpy as np
+import healpy
+# convert lat and lon to a healpix code encoding a region, with a given resolution
+def latlon2healpix( lat , lon , res ):
+    lat = np.radians(lat)
+    lon = np.radians(lon)
+    xs = ( np.cos(lat) * np.cos(lon) )#
+    ys = ( np.cos(lat) * np.sin(lon) )# -> Sphere coordinates: https://vvvv.org/blog/polar-spherical-and-geographic-coordinates
+    zs = ( np.sin(lat) )#
+    return healpy.vec2pix( int(res) , xs , ys , zs )
+
+parser = argparse.ArgumentParser()
+parser.add_argument("input_file")
+parser.add_argument("output_file")
+
+args = parser.parse_args()
+
+df = pd.read_csv(args.input_file,sep="\t") 
+df["healpix_256"] = df.progress_apply(lambda row:latlon2healpix(lat=row.latitude,lon=row.longitude,res=256),axis=1)
+df["healpix_64"] = df.progress_apply(lambda row:latlon2healpix(lat=row.latitude,lon=row.longitude,res=64),axis=1)
+df["healpix_32"] = df.progress_apply(lambda row:latlon2healpix(lat=row.latitude,lon=row.longitude,res=32),axis=1)
+df["healpix_1"] = df.progress_apply(lambda row:latlon2healpix(lat=row.latitude,lon=row.longitude,res=1),axis=1)
+
+df.to_csv(args.output_file,sep="\t",index=False)
\ No newline at end of file
diff --git a/scripts/randoludo.py b/scripts/randoludo.py
new file mode 100644
index 0000000..3862d52
--- /dev/null
+++ b/scripts/randoludo.py
@@ -0,0 +1,50 @@
+import pandas as pd
+import numpy as np
+
+from lib.geocoder import Geocoder
+
+geocoder = Geocoder("./outputs/IGN_4_100_A_C.h5","./outputs/IGN_4_100_A_C_index")
+
+df = pd.read_csv("data/rando_toponymes.tsv",sep="\t")
+df["name"]=df.name.apply(lambda x:x.split("¦")[0])
+
+def heuristic_mean(toponyms):
+	input_ = np.asarray([[t1,t2] for t2 in toponyms for t1 in toponyms if t2 != t1])
+	if len(input_)<1:
+		input_=np.asarray([[toponyms[0],toponyms[0]]])
+	res_geocode = pd.DataFrame(input_,columns="t tc".split())
+	lons,lats = geocoder.wgs_coord(*geocoder.get_coords(input_[:,0],input_[:,1]))
+	res_geocode["lon"] = lons
+	res_geocode["lat"] = lats
+	results = {}
+	for tp in toponyms:
+		lat = res_geocode[res_geocode.t == tp].lat.mean()
+		lon = res_geocode[res_geocode.t == tp].lon.mean()
+		results[tp]={"lat":lat,"lon":lon}
+	return results
+
+def heuristic_one_couple(toponyms):
+	input_ = np.asarray([[t1,t2] for t2 in toponyms for t1 in toponyms if t2 == t1])
+	if len(input_)<1:
+		input_=np.asarray([[toponyms[0],toponyms[0]]])
+	res_geocode = pd.DataFrame(input_,columns="t tc".split())
+	lons,lats = geocoder.wgs_coord(*geocoder.get_coords(input_[:,0],input_[:,1]))
+	res_geocode["lon"] = lons
+	res_geocode["lat"] = lats
+	results = {}
+	for tp in toponyms:
+		lat = res_geocode[res_geocode.t == tp].lat.mean()
+		lon = res_geocode[res_geocode.t == tp].lon.mean()
+		results[tp]={"lat":lat,"lon":lon}
+	return results
+
+results_fin = []
+for ix,group in df.groupby("filename"):
+    res_geocode = heuristic_one_couple(group.name_gazetteer.values)
+    results_fin.extend(group.name_gazetteer.apply(lambda x : res_geocode[x]).values.tolist())
+dd = pd.DataFrame(results_fin).rename(columns={"lat":"lat_pred","lon":"lon_pred"})
+df2 = pd.concat((df,dd),axis=1)
+
+from lib.utils_geo import haversine_pd
+df2["dist_error"] = haversine_pd(df2.longitude,df2.latitude,df2.lon_pred,df2.lat_pred)
+print(df2.dist_error.mean())
diff --git a/templates/pair_topo.html b/templates/pair_topo.html
new file mode 100644
index 0000000..3366643
--- /dev/null
+++ b/templates/pair_topo.html
@@ -0,0 +1,55 @@
+{% extends 'skeleton.html' %}
+
+{% block content %}
+<!-- MAP RENDER -->
+<div id="mapid"></div>
+
+<!-- TOPONYM FORM -->
+<div class="container" style="background-color: white;padding: 5px;">
+    <p>
+
+    </p>
+    <form action="/" method="get">
+        <div class="form-group">
+            <label for="formGroupExampleInput">Toponym</label>
+            <input type="text" class="form-control" name="top"
+                placeholder="Paris">
+        </div>
+        <div class="form-group">
+            <label for="formGroupExampleInput2">Context Toponym</label>
+            <input type="text" class="form-control" name="c_top"
+                placeholder="Cherbourg">
+        </div>
+        <button type="submit" class="btn btn-primary">Get Coords !</button>
+    </form>
+</div>
+{% endblock %}
+
+{% block script %}
+<script>
+
+    // Initialize the map
+    // [50, -0.1] are the latitude and longitude
+    // 4 is the zoom
+    // mapid is the id of the div where the map will appear
+    var mymap = L
+        .map('mapid')
+        .setView([50, -0.1], 4);
+
+    // Add a tile to the map = a background. Comes from OpenStreetmap
+    L.tileLayer(
+        'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
+        attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a>',
+    }).addTo(mymap);
+    {% if lat and lon %}
+    var marker = L.marker([{{lat}}, {{lon}}]).addTo(mymap);
+    var circle = L.circle([{{lat}}, {{lon}}], {
+          color: "red",
+          fillColor: "#f03",
+          fillOpacity: 0.5,
+          radius: 100000.0
+      }).addTo(mymap); 
+    {% endif %}
+
+</script>
+{% endblock %}
\ No newline at end of file
diff --git a/templates/skeleton.html b/templates/skeleton.html
new file mode 100644
index 0000000..8687b4e
--- /dev/null
+++ b/templates/skeleton.html
@@ -0,0 +1,116 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=auto, initial-scale=1.0">
+    <meta http-equiv="X-UA-Compatible" content="ie=edge">
+    <title>Geocoder Interface</title>
+    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
+
+    <link href="https://fonts.googleapis.com/css2?family=Kumbh+Sans:wght@300;400;700&display=swap" rel="stylesheet">
+
+    <!-- Load Leaflet -->
+    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.4/dist/leaflet.css" integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA==" crossorigin="" />
+    <script src="https://unpkg.com/leaflet@1.3.4/dist/leaflet.js" integrity="sha512-nMMmRyTVoLYqjP9hrbed9S+FzjZHW5gY1TWCHA5ckwXZBadntCNs8kEqAWdrb9O7rxbCaA4lKTIWjDXZxflOcA==" crossorigin=""></script>
+</head>
+
+<body>
+    <style>
+        body {
+            font-family: 'Kumbh Sans', sans-serif;
+        }
+        
+        #mapid {
+            height: 400px;
+            width: 100%;
+        }
+        
+        .container-fluid {
+            padding: 0 !important;
+        }
+        
+        .text_annotated {
+            line-height: 2em;
+        }
+        
+        .annotation {
+            border-radius: 5px;
+            color: white;
+            padding: 4px;
+        }
+        
+        .person {
+            background-color: #cf000f;
+        }
+        
+        .place {
+            background-color: #2c82c9;
+        }
+        
+        .org {
+            background-color: #00b16a;
+        }
+    </style>
+
+    <main class="container-fluid">
+        <!-- NAVBAR -->
+        <nav class="navbar navbar-expand-lg navbar-light bg-light">
+            <a class="navbar-brand" href="#">Geocoding using pair of toponyms</a>
+            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
+              <span class="navbar-toggler-icon"></span>
+            </button>
+            <div class="collapse navbar-collapse" id="navbarNavAltMarkup">
+                <div class="navbar-nav">
+                    <a class="nav-link" href="/">Toponyms Pair Geocoder</a>
+                    <a class="nav-link" href="/text">Text Geocoder</a>
+
+
+                </div>
+                <div class="navbar-nav ml-auto">
+                    <li class="nav-item dropdown">
+                        <a class="nav-link dropdown-toggle" href="#" id="navbarModelDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+                          Choose Model
+                        </a>
+
+                        <div class="dropdown-menu" aria-labelledby="navbarModelDropdown">
+                            {% for id_ in dict_model %}
+                            <a class="dropdown-item" href="/loadmodel/{{id_}}">{{id_}}</a>
+                            <br>{% endfor %}
+                        </div>
+                    </li>
+                    <li class="nav-item dropdown">
+                        <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+                        Choose Lang for Spacy
+                        </a>
+                        <div class="dropdown-menu" aria-labelledby="navbarDropdown">
+                            <a class="dropdown-item" href="/loadlang/fr">fr</a>
+                            <a class="dropdown-item" href="/loadlang/en">en</a>
+                        </div>
+                    </li>
+                </div>
+            </div>
+        </nav>
+        {% if request.args.get("msg","") != "" %}
+        <div class="alert alert-{{msg_code}} alert-dismissible fade show" role="alert">
+            {{request.args.get("msg") }}
+            <button type="button" class="close" data-dismiss="alert" aria-label="Close">
+              <span aria-hidden="true">&times;</span>
+            </button>
+        </div>
+
+        {% endif %}
+        <h2 class="text-center" style="margin-top: 0.5em;">{{title}}</h2>
+
+        <br>{% block content %}{% endblock %}
+    </main>
+
+    <!-- JS SCRIPTS -->
+    <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
+    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
+    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
+
+    {% block script%} {% endblock %}
+</body>
+
+</html>
\ No newline at end of file
diff --git a/templates/text.html b/templates/text.html
new file mode 100644
index 0000000..677b26e
--- /dev/null
+++ b/templates/text.html
@@ -0,0 +1,60 @@
+{% extends 'skeleton.html' %} {% block content %}
+<!-- MAP RENDER -->
+<div id="mapid"></div>
+
+<!-- TOPONYM FORM -->
+<div class="container">
+    <p>
+        
+    </p>
+    <form action="/geocode" method="post">
+        <div class="form-group">
+            <label for="text"><h5>Your text</h5></label>
+            <textarea class="form-control" id="text" name="text" rows="3"></textarea>
+            <br>
+            <button class="btn btn-info" id="submit">Geocode</button>
+        </div>
+    </form>
+    <h5>Results :</h5>
+    <div class="col-lg-12" style="border:1px solid #999;border-radius:5px;">
+        <p class="text_annotated" id="result_container">
+            {% if data %} {{data["output"]}} {% endif %}
+        </p>
+    </div>
+</div>
+
+{% endblock %} {% block script %}
+<script>
+    // Initialize the map
+    // [50, -0.1] are the latitude and longitude
+    // 4 is the zoom
+    // mapid is the id of the div where the map will appear
+    var mymap = L
+        .map('mapid')
+        .setView([50, -0.1], 4);
+
+    // Add a tile to the map = a background. Comes from OpenStreetmap
+    L.tileLayer(
+        'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
+            attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a>',
+        }).addTo(mymap);
+    
+</script>
+{% if data %} 
+<script>
+    {% for place,coords in data["place_coords"].items() %}
+        var mark = L.marker([{{coords["lat"]}}, {{coords["lon"]}}],);
+        mark.bindPopup("{{place}}")
+        mark.addTo(mymap);
+        var circle = L.circle([{{coords["lat"]}}, {{coords["lon"]}}], {
+          color: "red",
+          fillColor: "#f03",
+          fillOpacity: 0.5,
+          radius: 100000.0
+      }).addTo(mymap); 
+
+    {% endfor %}
+</script>
+{% endif %}
+
+{% endblock %}
\ No newline at end of file
diff --git a/train_bert_geocoder.py b/train_bert_geocoder.py
new file mode 100644
index 0000000..d0749b6
--- /dev/null
+++ b/train_bert_geocoder.py
@@ -0,0 +1,353 @@
+# REQUIREMENTS : pandas keras torch numpy transformers
+
+"""
+Based from the article : https://mccormickml.com/2019/07/22/BERT-fine-tuning/
+by Chris McCormick
+
+"""
+import os
+import sys
+import time
+import random
+import argparse
+import datetime
+
+import pandas as pd
+import numpy as np
+
+import tensorflow as tf
+import torch
+
+from tqdm import tqdm
+tqdm.pandas()
+
+from torch.utils.data import TensorDataset, DataLoader, RandomSampler, SequentialSampler
+from keras.preprocessing.sequence import pad_sequences
+from transformers import BertTokenizer
+from transformers import BertForSequenceClassification, AdamW, BertConfig
+from transformers import get_linear_schedule_with_warmup
+
+from sklearn import preprocessing
+from joblib import dump
+
+def flat_accuracy(preds, labels):
+    pred_flat = np.argmax(preds, axis=1).flatten()
+    labels_flat = labels.flatten()
+    return np.sum(pred_flat == labels_flat) / len(labels_flat)
+
+
+def format_time(elapsed):
+    '''
+    Takes a time in seconds and returns a string hh:mm:ss
+    '''
+    # Round to the nearest second.
+    elapsed_rounded = int(round((elapsed)))
+
+    # Format as hh:mm:ss
+    return str(datetime.timedelta(seconds=elapsed_rounded))
+
+parser = argparse.ArgumentParser()
+
+parser.add_argument("train" ,help="TSV with two columns : 'sentence' and 'label'")
+parser.add_argument("test",help="TSV with two columns : 'sentence' and 'label'")
+parser.add_argument("outputdir",help="TSV with two columns : 'sentence' and 'label'")
+parser.add_argument("-e","--epochs",type=int,default=5)
+parser.add_argument("-b","--batch_size",default=32,type=int)
+
+args = parser.parse_args()#("-b 32 -e 10 cooc_adj_bert_train.csv cooc_adj_bert_test.csv output_bert_allcooc_adjsampling3radius20km_batch32_epoch10".split())
+
+if not os.path.exists(args.train) or not os.path.exists(args.test):
+    raise FileNotFoundError("Train or Test filepath is incorrect !")
+
+# Number of training epochs (authors recommend between 2 and 4)
+epochs = args.epochs
+
+# The DataLoader needs to know the batch size for training, so I specify it here.
+# For fine-tuning BERT on a specific task, the authors recommend a batch size of
+# 16 or 32.
+
+batch_size = args.batch_size
+
+# OUTPUT DIR
+output_dir = args.outputdir
+
+if not os.path.exists(args.outputdir):
+    raise FileNotFoundError("{0} directory does not exists ! ".format(args.output_dir))
+if not os.path.isdir(args.outputdir):
+    raise NotADirectoryError("{0} is not a directory".format(args.output_dir))
+
+df_train = pd.read_csv(args.train, sep="\t")
+df_test = pd.read_csv(args.test, sep="\t")
+
+label_encoder = preprocessing.LabelEncoder()
+label_encoder.fit(np.concatenate((df_train.label.values,df_test.label.values)))
+dump(label_encoder,filename=output_dir+"/label_encoder.dump")
+
+df_train["label"] = label_encoder.transform(df_train.label.values)
+df_test["label"] = label_encoder.transform(df_test.label.values)
+
+# Get the GPU device name.
+device_name = tf.test.gpu_device_name()
+
+# The device name should look like the following:
+if device_name == '/device:GPU:0':
+    print('Found GPU at: {}'.format(device_name))
+else:
+    raise SystemError('GPU device not found')
+
+# If there's a GPU available...
+if torch.cuda.is_available():    
+
+    # Tell PyTorch to use the GPU.    
+    device = torch.device("cuda")
+    print('There are %d GPU(s) available.' % torch.cuda.device_count())
+    print('We will use the GPU:', torch.cuda.get_device_name(0))
+# If not...
+else:
+    print('No GPU available, using the CPU instead.')
+    device = torch.device("cpu")
+
+
+# Load the BERT tokenizer.
+print('Loading {0} tokenizer...'.format("bert-base-multilingual-cased"))
+tokenizer = BertTokenizer.from_pretrained('bert-base-multilingual-cased',do_lower_case=False)
+
+from lib.torch_generator import SentenceDataset
+# Create the DataLoader for training set.
+train_data = SentenceDataset(df_train,tokenizer,batch_size=batch_size)
+train_dataloader = DataLoader(train_data,  batch_size=batch_size)#,sampler=train_sampler,)
+
+# Create the DataLoader for validation set.
+validation_data = SentenceDataset(df_test,tokenizer,batch_size=batch_size)
+#validation_sampler = SequentialSampler(validation_data)
+validation_dataloader = DataLoader(validation_data, batch_size=batch_size)#, sampler=validation_sampler)
+
+# Load BertForSequenceClassification, the pretrained BERT model with a single
+# linear classification layer on top. 
+model = BertForSequenceClassification.from_pretrained(
+    "bert-base-multilingual-cased", # Use the 12-layer BERT model, with an uncased vocab.
+    num_labels = max(df_test.label.max(),df_train.label.max())+1, # The number of output labels--2 for binary classification.
+                    # You can increase this for multi-class tasks.   
+    output_attentions = False, # Whether the model returns attentions weights.
+    output_hidden_states = False, # Whether the model returns all hidden-states.
+)
+
+# Tell pytorch to run this model on the GPU.
+model.cuda()
+
+optimizer = AdamW(model.parameters(),
+                  lr = 2e-5, # args.learning_rate - default is 5e-5, our notebook had 2e-5
+                  eps = 1e-8 # args.adam_epsilon  - default is 1e-8.
+                )
+
+
+
+# Total number of training steps is number of batches * number of epochs.
+total_steps = len(train_data) * epochs
+
+# Create the learning rate scheduler.
+scheduler = get_linear_schedule_with_warmup(optimizer, 
+                                            num_warmup_steps = 0, # Default value in run_glue.py
+                                            num_training_steps = total_steps)
+
+
+
+# Set the seed value all over the place to make this reproducible.
+seed_val = 42
+
+random.seed(seed_val)
+np.random.seed(seed_val)
+torch.manual_seed(seed_val)
+torch.cuda.manual_seed_all(seed_val)
+
+# Store the average loss after each epoch so I can plot them.
+loss_values = []
+
+history = []
+# For each epoch...
+for epoch_i in range(0, epochs):
+    epoch_data={}
+    
+    # ========================================
+    #               Training
+    # ========================================
+    
+    # Perform one full pass over the training set.
+
+    print("")
+    print('======== Epoch {:} / {:} ========'.format(epoch_i + 1, epochs))
+    print('Training...')
+
+    # Measure how long the training epoch takes.
+    t0 = time.time()
+
+    # Reset the total loss for this epoch.
+    total_loss = 0
+
+    # Put the model into training mode.
+    model.train()
+
+    # For each batch of training data...
+    for step, batch in enumerate(train_dataloader):
+
+        # Progress update every 40 batches.
+        if step % 100 == 0 and not step == 0:
+            # Calculate elapsed time in minutes.
+            elapsed = format_time(time.time() - t0)
+            
+            # Report progress.#Changed to sys.stdout to avoid uneccessary \n
+            sys.stdout.write('\r  Batch {:>5,}  of  {:>5,}.    Elapsed: {:}.'.format(step, len(train_dataloader), elapsed))
+
+        # Unpack this training batch from the dataloader. 
+        #
+        # As I unpack the batch, I'll also copy each tensor to the GPU using the 
+        # `to` method.
+        #
+        # `batch` contains three pytorch tensors:
+        #   [0]: input ids 
+        #   [1]: attention masks
+        #   [2]: labels 
+        b_input_ids = batch[0].to(device)
+        b_input_mask = batch[1].to(device)
+        b_labels = batch[2].to(device)
+
+        # Always clear any previously calculated gradients before performing a
+        # backward pass. PyTorch doesn't do this automatically because 
+        # accumulating the gradients is "convenient while training RNNs". 
+        # (source: https://stackoverflow.com/questions/48001598/why-do-we-need-to-call-zero-grad-in-pytorch)
+        model.zero_grad()        
+
+        # Perform a forward pass (evaluate the model on this training batch).
+        # This will return the loss (rather than the model output) because I
+        # have provided the `labels`.
+        # The documentation for this `model` function is here: 
+        # https://huggingface.co/transformers/v2.2.0/model_doc/bert.html#transformers.BertForSequenceClassification
+        outputs = model(b_input_ids, 
+                    token_type_ids=None, 
+                    attention_mask=b_input_mask, 
+                    labels=b_labels)
+        
+        # The call to `model` always returns a tuple, so I need to pull the 
+        # loss value out of the tuple.
+        loss = outputs[0]
+
+        # Accumulate the training loss over all of the batches so that I can
+        # calculate the average loss at the end. `loss` is a Tensor containing a
+        # single value; the `.item()` function just returns the Python value 
+        # from the tensor.
+        
+        total_loss += loss.item()
+
+        # Perform a backward pass to calculate the gradients.
+        loss.backward()
+
+        # Clip the norm of the gradients to 1.0.
+        # This is to help prevent the "exploding gradients" problem.
+        torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)
+
+        # Update parameters and take a step using the computed gradient.
+        # The optimizer dictates the "update rule"--how the parameters are
+        # modified based on their gradients, the learning rate, etc.
+        optimizer.step()
+
+        # Update the learning rate.
+        scheduler.step()
+
+    # Calculate the average loss over the training data.
+    avg_train_loss = total_loss / len(train_dataloader)            
+    
+    # Store the loss value for plotting the learning curve.
+    loss_values.append(avg_train_loss)
+
+    print("")
+    print("  Average training loss: {0:.2f}".format(avg_train_loss))
+    print("  Training epoch took: {:}".format(format_time(time.time() - t0)))
+    epoch_data["loss"]=avg_train_loss
+    epoch_data["epoch_duration"] = time.time() - t0
+
+    # ========================================
+    #               Validation
+    # ========================================
+    # After the completion of each training epoch, measure the performance on
+    # the validation set.
+
+    print("")
+    print("Running Validation...")
+
+    t0 = time.time()
+
+    # Put the model in evaluation mode--the dropout layers behave differently
+    # during evaluation.
+    model.eval()
+
+    # Tracking variables 
+    eval_loss, eval_accuracy = 0, 0
+    nb_eval_steps, nb_eval_examples = 0, 0
+
+    # Evaluate data for one epoch
+    for batch in validation_dataloader:
+        
+        # Add batch to GPU
+        batch = tuple(t.to(device) for t in batch)
+        
+        # Unpack the inputs from dataloader
+        b_input_ids, b_input_mask, b_labels = batch
+        
+        # Telling the model not to compute or store gradients, saving memory and
+        # speeding up validation
+        with torch.no_grad():        
+
+            # Forward pass, calculate logit predictions.
+            # This will return the logits rather than the loss because we have
+            # not provided labels.
+            # token_type_ids is the same as the "segment ids", which 
+            # differentiates sentence 1 and 2 in 2-sentence tasks.
+            # The documentation for this `model` function is here: 
+            # https://huggingface.co/transformers/v2.2.0/model_doc/bert.html#transformers.BertForSequenceClassification
+            outputs = model(b_input_ids, 
+                            token_type_ids=None, 
+                            attention_mask=b_input_mask)
+        
+        # Get the "logits" output by the model. The "logits" are the output
+        # values prior to applying an activation function like the softmax.
+        logits = outputs[0]
+
+        # Move logits and labels to CPU
+        logits = logits.detach().cpu().numpy()
+        label_ids = b_labels.to('cpu').numpy()
+        
+        # Calculate the accuracy for this batch of test sentences.
+        tmp_eval_accuracy = flat_accuracy(logits, label_ids)
+        
+        # Accumulate the total accuracy.
+        eval_accuracy += tmp_eval_accuracy
+
+        # Track the number of batches
+        nb_eval_steps += 1
+
+    
+    # Report the final accuracy for this validation run.
+    print("  Accuracy: {0:.2f}".format(eval_accuracy/nb_eval_steps))
+    print("  Validation took: {:}".format(format_time(time.time() - t0)))
+    epoch_data["accuracy"] = eval_accuracy/nb_eval_steps
+    epoch_data["validation_duration"] = time.time() - t0
+    history.append(epoch_data)
+print("")
+print("Training complete!")
+
+print("Save History")
+pd.DataFrame(history).to_csv(output_dir+"/history_bert.csv",sep="\t")
+
+
+
+# Create output directory if needed
+if not os.path.exists(output_dir):
+    os.makedirs(output_dir)
+
+print("Saving model to %s" % output_dir)
+
+# Save a trained model, configuration and tokenizer using `save_pretrained()`.
+# They can then be reloaded using `from_pretrained()`
+model_to_save = model.module if hasattr(model, 'module') else model  # Take care of distributed/parallel training
+model_to_save.save_pretrained(output_dir)
+tokenizer.save_pretrained(output_dir)
\ No newline at end of file
diff --git a/train_geocoder.py b/train_geocoder.py
new file mode 100644
index 0000000..71ff546
--- /dev/null
+++ b/train_geocoder.py
@@ -0,0 +1,401 @@
+# Base module 
+import re
+import os
+import json
+
+# Structure
+import pandas as pd
+import numpy as np
+import geopandas as gpd
+
+# DEEPL module
+from keras.layers import Dense, Input, Embedding,concatenate,Bidirectional,LSTM, Dropout
+from keras.models import Model
+from keras import backend as K
+from keras.callbacks import ModelCheckpoint
+
+import tensorflow as tf
+
+# Geometry
+from shapely.geometry import Point
+
+# Custom module
+from helpers import read_geonames
+from lib.utils_geo import Grid,zero_one_encoding, get_adjacency_rels, get_geonames_inclusion_rel,get_bounds
+from lib.ngram_index import NgramIndex
+from lib.utils import ConfigurationReader
+from lib.metrics import lat_accuracy,lon_accuracy
+from lib.utils_geo import haversine_tf,accuracy_k,haversine_tf_1circle
+
+
+# Logging
+from tqdm import tqdm
+import logging
+from helpers import parse_title_wiki,EpochTimer
+
+logging.getLogger('gensim').setLevel(logging.WARNING)
+
+def get_new_ids(cooc_data,id_first_value):
+    """
+    Return new ids from cooccurrence data
+    
+    Parameters
+    ----------
+    cooc_data : pd.DataFrame
+        cooccurrence da
+    id_first_value : int
+        id beginning value
+    
+    Returns
+    -------
+    dict
+        new ids for each toponyms 
+    """
+    topo_id = {}
+    id_ = id_first_value
+    for title in cooc_data.title.values:
+        if not title in topo_id:
+            id_+=1
+            topo_id[id_]=title
+    for interlinks in cooc_data.interlinks.values:
+        for interlink in interlinks.split("|"):
+            if not interlink in topo_id:
+                id_+=1
+                topo_id[id_]=interlink
+    return topo_id
+
+# LOGGING CONF
+logging.basicConfig(
+    format='[%(asctime)s][%(levelname)s] %(message)s ', 
+    datefmt='%m/%d/%Y %I:%M:%S %p',
+    level=logging.INFO  
+    )
+
+args = ConfigurationReader("./parser_config/toponym_combination_embedding_v2.json")\
+    .parse_args()#("-i -a -w --wikipedia-cooc-fn ../data/wikipedia/cooccurrence_FR.txt -n 4 --ngram-word2vec-iter 1 -e 100 ../data/geonamesData/FR.txt ../data/geonamesData/hierarchy.txt".split())
+
+#
+#################################################
+############# MODEL TRAINING PARAMETER ##########
+#################################################
+MODEL_NAME = "Bi-LSTM_NGRAM"
+NGRAM_SIZE = args.ngram_size
+ACCURACY_TOLERANCE = args.tolerance_value
+EPOCHS = args.epochs
+ITER_ADJACENCY = args.adjacency_iteration
+COOC_SAMPLING_NUMBER = args.cooc_sample_size
+WORDVEC_ITER = args.ngram_word2vec_iter
+EMBEDDING_DIM = 256
+#################################################
+########## FILENAME VARIABLE ####################
+#################################################
+GEONAME_FN = args.geoname_input
+DATASET_NAME = args.geoname_input.split("/")[-1]
+GEONAMES_HIERARCHY_FN = args.geoname_hierachy_input
+REGION_SUFFIX_FN = "" if args.admin_code_1 == "None" else "_" + args.admin_code_1
+ADJACENCY_REL_FILENAME = "{0}_{1}{2}adjacency.json".format(
+        GEONAME_FN,
+        ITER_ADJACENCY,
+        REGION_SUFFIX_FN)
+
+COOC_FN = args.wikipedia_cooc_fn
+PREFIX_OUTPUT_FN = "{0}_{1}_{2}_{3}_{4}".format(
+    GEONAME_FN.split("/")[-1],
+    EPOCHS,
+    NGRAM_SIZE,
+    ACCURACY_TOLERANCE,
+    REGION_SUFFIX_FN)
+
+REL_CODE=""
+if args.adjacency:
+    PREFIX_OUTPUT_FN += "_A"
+    REL_CODE+= "A"
+if args.inclusion:
+    PREFIX_OUTPUT_FN += "_I"
+    REL_CODE+= "I"
+if args.wikipedia_cooc:
+    PREFIX_OUTPUT_FN += "_C"
+    REL_CODE+= "C"
+
+MODEL_OUTPUT_FN = "outputs/{0}.h5".format(PREFIX_OUTPUT_FN)
+INDEX_FN = "outputs/{0}_index".format(PREFIX_OUTPUT_FN)
+HISTORY_FN = "outputs/{0}.csv".format(PREFIX_OUTPUT_FN)
+
+from lib.utils import MetaDataSerializer
+
+meta_data = MetaDataSerializer(
+    MODEL_NAME,
+    DATASET_NAME,
+    REL_CODE,
+    COOC_SAMPLING_NUMBER,
+    ITER_ADJACENCY,
+    NGRAM_SIZE,
+    ACCURACY_TOLERANCE,
+    EPOCHS,
+    EMBEDDING_DIM,
+    WORDVEC_ITER,
+    INDEX_FN,
+    MODEL_OUTPUT_FN,
+    HISTORY_FN
+)
+meta_data.save("outputs/{0}.json".format(PREFIX_OUTPUT_FN))
+
+#############################################################################################
+################################# LOAD DATA #################################################
+#############################################################################################
+
+# LOAD  Geonames DATA
+logging.info("Load Geonames data...")
+geoname_data = read_geonames(GEONAME_FN).fillna("")
+
+train_indices = set(pd.read_csv(GEONAME_FN+"_train.csv").geonameid.values)
+test_indices = set(pd.read_csv(GEONAME_FN+"_test.csv").geonameid.values)
+
+logging.info("Geonames data loaded!")
+
+# SELECT ENTRY with class == to A and P (Areas and Populated Places)
+filtered = geoname_data[geoname_data.feature_class.isin("A P".split())].copy() # Only take area and populated places
+#CLEAR RAM
+del geoname_data
+
+
+# IF REGION
+if args.admin_code_1 != "None":
+    filtered = filtered[filtered.admin1_code == args.admin_code_1].copy()
+
+# GET BOUNDS AND REDUCE DATA AVAILABLE FIELDS
+filtered = filtered["geonameid name longitude latitude".split()] # KEEP ONLY ID LABEL AND COORD
+
+
+
+#############################################################################################
+################################# RETRIEVE RELATIONSHIPS ####################################
+#############################################################################################
+
+
+# INITIALIZE RELATION STORE
+rel_store = []
+
+# Retrieve adjacency relationships
+if args.adjacency:
+    logging.info("Retrieve adjacency relationships ! ")
+
+    if not os.path.exists(ADJACENCY_REL_FILENAME):
+        bounds = get_bounds(filtered) # Required to get adjacency relationships
+        rel_store.extend(get_adjacency_rels(filtered,bounds,[360,180],ITER_ADJACENCY))
+        json.dump(rel_store,open(ADJACENCY_REL_FILENAME,'w'))
+    else:
+        logging.info("Open and load data from previous computation!")
+        rel_store=json.load(open(ADJACENCY_REL_FILENAME))
+
+    logging.info("{0} adjacency relationships retrieved ! ".format(len(rel_store)))
+
+# Retrieve inclusion relationships
+if args.inclusion:
+    logging.info("Retrieve inclusion relationships ! ")
+
+    cpt_rel = len(rel_store)
+    rel_store.extend(get_geonames_inclusion_rel(filtered,GEONAMES_HIERARCHY_FN))
+
+    logging.info("{0} inclusion relationships retrieved ! ".format(len(rel_store)-cpt_rel))
+
+
+
+if args.wikipedia_cooc:
+    logging.info("Load Wikipedia Cooccurrence data and merge with geonames")
+    
+    cooc_data = pd.read_csv(COOC_FN,sep="\t")
+    cooc_data["title"] = cooc_data.title.apply(parse_title_wiki)
+    cooc_data["interlinks"] = cooc_data.interlinks.apply(parse_title_wiki)
+    id_wikipediatitle = get_new_ids(cooc_data,filtered.geonameid.max())
+    wikipediatitle_id = {v:k for k,v in id_wikipediatitle.items()}
+    title_coord = {row.title: (row.longitude,row.latitude) for _,row in tqdm(cooc_data.iterrows(),total=len(cooc_data))}
+    cooc_data["geonameid"] = cooc_data.title.apply(lambda x: wikipediatitle_id[x])
+    filtered = pd.concat((filtered,cooc_data["geonameid title longitude latitude".split()].rename(columns={"title":"name"}).copy()))
+    train_cooc_indices,test_cooc_indices = pd.read_csv(COOC_FN+"_train.csv",sep="\t"), pd.read_csv(COOC_FN+"_test.csv",sep="\t")
+    if not "title" in train_cooc_indices:
+        train_cooc_indices,test_cooc_indices = pd.read_csv(COOC_FN+"_train.csv"), pd.read_csv(COOC_FN+"_test.csv")
+    train_indices = train_indices.union(set(train_cooc_indices.title.apply(lambda x: wikipediatitle_id[parse_title_wiki(x)]).values))
+    test_indices = test_indices.union(set(test_cooc_indices.title.apply(lambda x: wikipediatitle_id[parse_title_wiki(x)]).values))
+
+    logging.info("Merged with Geonames data !")
+
+    # EXTRACT rel
+    logging.info("Extracting cooccurrence relationships")
+    cpt=0
+    for ix, row in tqdm(cooc_data.iterrows(),total=len(cooc_data),desc="Extracting Wikipedia Cooccurrence"):
+        for inter in np.random.choice(row.interlinks.split("|"),COOC_SAMPLING_NUMBER):
+            cpt+=1
+            rel_store.extend([[row.geonameid,wikipediatitle_id[inter]]])
+    logging.info("Extract {0} cooccurrence relationships !".format(cpt))
+
+
+# STORE ID to name
+geoname2name = dict(filtered["geonameid name".split()].values)
+
+# ENCODING NAME USING N-GRAM SPLITTING
+logging.info("Encoding toponyms to ngram...")
+index = NgramIndex(NGRAM_SIZE)
+
+ # Identify all ngram available
+filtered.name.apply(lambda x : index.split_and_add(x))
+if args.wikipedia_cooc:[index.split_and_add(k) for k in wikipediatitle_id]
+
+geoname2encodedname = {row.geonameid : index.encode(row.name) for row in filtered.itertuples()} #init a dict with the 'geonameid' --> 'encoded toponym' association
+
+if args.wikipedia_cooc:
+    geoname2encodedname.update({v:index.encode(k) for k,v in wikipediatitle_id.items()})
+
+# SAVE THE INDEX TO REUSE THE MODEL
+index.save(INDEX_FN)
+
+logging.info("Done !")
+
+
+#############################################################################################
+################################# ENCODE COORDINATES ########################################
+#############################################################################################
+
+
+
+# Encode each geonames entry coordinates
+geoname_vec = {row.geonameid : zero_one_encoding(row.longitude,row.latitude) for row in filtered.itertuples()}
+# CLEAR RAM
+del filtered
+
+
+EMBEDDING_DIM = 256
+num_words = len(index.index_ngram) # necessary for the embedding matrix 
+
+logging.info("Preparing Input and Output data...")
+
+
+#############################################################################################
+################################# BUILD TRAIN/TEST DATASETS #################################
+#############################################################################################
+
+X_1_train,X_2_train,y_lat_train,y_lon_train=[],[],[],[]
+X_1_test,X_2_test,y_lat_test,y_lon_test=[],[],[],[]
+y_train,y_test = [],[]
+
+for couple in rel_store:
+    geonameId_1,geonameId_2 = couple[0],couple[1]
+    if not geonameId_1 in geoname2encodedname:
+        continue
+    top1,top2 = geoname2encodedname[geonameId_1],geoname2encodedname[geonameId_2]
+    if geonameId_1 in train_indices: #and geonameId_2 in train_indices:
+        
+        X_1_train.append(top1)
+        X_2_train.append(top2)
+
+        y_train.append([geoname_vec[geonameId_1][0],geoname_vec[geonameId_1][1]])
+        #y_lon_train.append(geoname_vec[geonameId_1][0])
+        #y_lat_train.append(geoname_vec[geonameId_1][1])
+    
+    else:
+        X_1_test.append(top1)
+        X_2_test.append(top2)
+
+        y_test.append([geoname_vec[geonameId_1][0],geoname_vec[geonameId_1][1]])
+        #y_lon_test.append(geoname_vec[geonameId_1][0])
+        #y_lat_test.append(geoname_vec[geonameId_1][1])
+
+# NUMPYZE inputs and output lists
+X_1_train = np.array(X_1_train)
+X_2_train = np.array(X_2_train)
+y_lat_train = np.array(y_lat_train)
+y_lon_train = np.array(y_lon_train)
+y_train = np.array(y_train)
+
+X_1_test = np.array(X_1_test)
+X_2_test = np.array(X_2_test)
+y_lat_test = np.array(y_lat_test)
+y_lon_test = np.array(y_lon_test)
+y_test = np.array(y_test)
+
+logging.info("Data prepared !")
+
+
+# check for output dir
+if not os.path.exists("outputs/"):
+    os.makedirs("outputs/")
+
+#############################################################################################
+################################# NGRAM EMBEDDINGS ##########################################
+#############################################################################################
+
+
+logging.info("Generating N-GRAM Embedding...")
+embedding_weights = index.get_embedding_layer(geoname2encodedname.values(),dim= EMBEDDING_DIM,iter=WORDVEC_ITER)
+logging.info("Embedding generated !")
+
+#############################################################################################
+################################# MODEL DEFINITION ##########################################
+#############################################################################################
+
+
+input_1 = Input(shape=(index.max_len,))
+input_2 = Input(shape=(index.max_len,))
+
+embedding_layer = Embedding(num_words, EMBEDDING_DIM,input_length=index.max_len,weights=[embedding_weights],trainable=False)#, trainable=True)
+
+x1 = embedding_layer(input_1)
+x2 = embedding_layer(input_2)
+
+# Each LSTM learn on a permutation of the input toponyms
+x1 = Bidirectional(LSTM(98))(x1)
+x2 = Bidirectional(LSTM(98))(x2)
+
+x = concatenate([x1,x2])#,x3])
+
+x1 = Dense(500,activation="relu")(x)
+# x1 = Dropout(0.3)(x1)
+x1 = Dense(500,activation="relu")(x1)
+# x1 = Dropout(0.3)(x1)
+
+x2 = Dense(500,activation="relu")(x)
+# x2 = Dropout(0.3)(x2)
+x2 = Dense(500,activation="relu")(x2)
+# x2 = Dropout(0.3)(x2)
+
+output_lon = Dense(1,activation="sigmoid",name="Output_LON")(x1)
+output_lat = Dense(1,activation="sigmoid",name="Output_LAT")(x2)
+
+output_coord = concatenate([output_lon,output_lat],name="output_coord")
+
+model = Model(inputs = [input_1,input_2], outputs = output_coord)#input_3
+
+model.compile(loss={"output_coord":haversine_tf_1circle}, optimizer='adam',metrics={"output_coord":accuracy_k(ACCURACY_TOLERANCE)})
+
+# model = Model(inputs = [input_1,input_2], outputs = [output_lon,output_lat])#input_3
+
+# model.compile(loss=['mean_squared_error','mean_squared_error'], optimizer='adam',metrics={"Output_LON":lon_accuracy(),"Output_LAT":lat_accuracy()})
+
+
+#############################################################################################
+################################# TRAINING LAUNCH ###########################################
+#############################################################################################
+
+checkpoint = ModelCheckpoint(MODEL_OUTPUT_FN + ".part", monitor='loss', verbose=1,
+    save_best_only=True, mode='auto', period=1)
+
+epoch_timer = EpochTimer("outputs/"+PREFIX_OUTPUT_FN+"_epoch_timer_output.csv")
+
+
+history = model.fit(x=[X_1_train,X_2_train],
+    y=y_train,#[y_lon_train,y_lat_train],
+    verbose=True, batch_size=100,
+    epochs=EPOCHS,
+    validation_data=([X_1_test,X_2_test],y_test),#[y_lon_test,y_lat_test]),
+    callbacks=[checkpoint,epoch_timer])
+
+
+hist_df = pd.DataFrame(history.history)
+hist_df.to_csv(HISTORY_FN)
+
+model.save(MODEL_OUTPUT_FN)
+
+# Erase Model Checkpoint file
+if os.path.exists(MODEL_OUTPUT_FN + ".part"):
+    import shutil
+    shutil.rmtree(MODEL_OUTPUT_FN + ".part")
\ No newline at end of file
diff --git a/train_geocoder_v2.py b/train_geocoder_v2.py
new file mode 100644
index 0000000..b44fada
--- /dev/null
+++ b/train_geocoder_v2.py
@@ -0,0 +1,242 @@
+# Base module 
+import os
+import sys
+
+# Structure
+import pandas as pd
+import numpy as np
+
+# DEEPL module
+from keras.layers import Dense, Input, Embedding,concatenate,Bidirectional,LSTM, Dropout
+from keras.models import Model
+from keras.callbacks import ModelCheckpoint
+
+# Custom module
+from lib.utils_geo import zero_one_encoding
+from lib.ngram_index import NgramIndex
+from lib.word_index import WordIndex
+from lib.utils import ConfigurationReader
+from lib.utils_geo import accuracy_k,haversine_tf_1circle
+from helpers import EpochTimer
+from lib.datageneratorv4 import DataGenerator
+
+# Logging
+import logging
+logging.getLogger('gensim').setLevel(logging.WARNING)
+logging.basicConfig( # LOGGING CONF
+    format='[%(asctime)s][%(levelname)s] %(message)s ', 
+    datefmt='%m/%d/%Y %I:%M:%S %p',
+    level=logging.INFO  
+    )
+
+import tensorflow as tf
+try:
+    physical_devices = tf.config.list_physical_devices('GPU')
+    tf.config.experimental.set_memory_growth(physical_devices[0], enable=True)
+except:
+    print("NO GPU FOUND...")
+
+# COMMAND ARGS
+args = ConfigurationReader("./parser_config/toponym_combination_embedding_v3.json")\
+    .parse_args()#("IGN ../data/IGN/IGN_inclusion.csv ../data/IGN/IGN_adjacent_corrected.csv ../data/IGN/IGN_cooc.csv -i -w  -a -n 4 --ngram-word2vec-iter 1".split())
+
+#
+#################################################
+############# MODEL TRAINING PARAMETER ##########
+#################################################
+MODEL_NAME = "Bi-LSTM_NGRAM"
+NGRAM_SIZE = args.ngram_size
+ACCURACY_TOLERANCE = args.tolerance_value
+EPOCHS = args.epochs
+WORDVEC_ITER = args.ngram_word2vec_iter
+EMBEDDING_DIM = args.dimension
+#################################################
+########## FILENAME VARIABLE ####################
+#################################################
+INCLUSION_FN = args.geoname_inclusion
+ADJACENT_FN = args.geonames_adjacent
+COOC_FN = args.wikipedia_cooc
+
+DATASET_NAME = args.dataset_name
+
+PREFIX_OUTPUT_FN = DATASET_NAME
+PREFIX_OUTPUT_FN+="_{0}".format(NGRAM_SIZE)
+PREFIX_OUTPUT_FN+="_{0}".format(EPOCHS)
+
+if args.adjacency:
+    PREFIX_OUTPUT_FN += "_A"
+if args.inclusion:
+    PREFIX_OUTPUT_FN += "_I"
+if args.wikipedia:
+    PREFIX_OUTPUT_FN += "_P"
+
+MODEL_OUTPUT_FN = "outputs/{0}.h5".format(PREFIX_OUTPUT_FN)
+INDEX_FN = "outputs/{0}_index".format(PREFIX_OUTPUT_FN)
+HISTORY_FN = "outputs/{0}.csv".format(PREFIX_OUTPUT_FN)
+
+#############################################################################################
+################################# LOAD DATA #################################################
+#############################################################################################
+
+data_used = []
+
+if args.wikipedia:
+    data_used.append(pd.read_csv(COOC_FN,sep="\t"))
+
+if args.inclusion:
+    data_used.append(pd.read_csv(INCLUSION_FN,sep="\t"))
+
+if args.adjacency:
+    data_used.append(pd.read_csv(ADJACENT_FN, sep="\t"))
+
+if  len(data_used) <1:
+    print("No Type of toponyms indicated. Stopping the program...")
+    sys.exit(1)
+
+pairs_of_toponym = pd.concat(data_used)
+
+#############################################################################################
+################################# RETRIEVE RELATIONSHIPS ####################################
+#############################################################################################
+
+# ENCODING NAME USING N-GRAM SPLITTING
+logging.info("Encoding toponyms to ngram...")
+index = NgramIndex(NGRAM_SIZE)
+if args.tokenization_method == "word-level":
+    index = WordIndex()
+if args.tokenization_method == "bert":
+    index = NgramIndex(NGRAM_SIZE,bert_tokenization=True)
+
+ # Identify all ngram available
+pairs_of_toponym.toponym.apply(lambda x : index.split_and_add(x))
+pairs_of_toponym.toponym_context.apply(lambda x : index.split_and_add(x))
+
+num_words = len(index.index_ngram) # necessary for the embedding matrix
+
+# SAVE THE INDEX TO REUSE THE MODEL
+index.save(INDEX_FN)
+logging.info("Done !")
+
+#############################################################################################
+################################# NGRAM EMBEDDINGS ##########################################
+#############################################################################################
+
+logging.info("Generating N-GRAM Embedding...")
+embedding_weights = index.get_embedding_layer([index.encode(p) for p in np.concatenate((pairs_of_toponym.toponym.unique(),pairs_of_toponym.toponym_context.unique()))],dim= EMBEDDING_DIM,iter=WORDVEC_ITER)
+logging.info("Embedding generated !")
+
+#############################################################################################
+################################# BUILD TRAIN/TEST DATASETS #################################
+#############################################################################################
+logging.info("Preparing Input and Output data...")
+
+training_generator = DataGenerator(pairs_of_toponym[pairs_of_toponym.split == "train"],index)
+validation_generator = DataGenerator(pairs_of_toponym[pairs_of_toponym.split == "test"],index)
+# X_1_train,X_2_train=[],[]
+# X_1_test,X_2_test=[],[]
+# y_train,y_test = [],[]
+
+# for couple in pairs_of_toponym["toponym toponym_context split longitude latitude".split()].itertuples():
+#     top,top_c,split_ = couple[1], couple[2], couple[3]
+#     coord = zero_one_encoding(couple[-2],couple[-1]) # 0 and 1 encoding
+#     enc_top, enc_top_c = index.encode(top),index.encode(top_c)
+#     if split_ == "train":
+#         X_1_train.append(enc_top)
+#         X_2_train.append(enc_top_c)
+#         y_train.append(list(coord))
+#     else:
+#         X_1_test.append(enc_top)
+#         X_2_test.append(enc_top_c)
+#         y_test.append(list(coord))
+
+# # "NUMPYZE" inputs and output lists
+# X_1_train = np.array(X_1_train)
+# X_2_train = np.array(X_2_train)
+# y_train = np.array(y_train)
+
+# X_1_test = np.array(X_1_test)
+# X_2_test = np.array(X_2_test)
+# y_test = np.array(y_test)
+
+logging.info("Data prepared !")
+
+
+# check for output dir
+if not os.path.exists("outputs/"):
+    os.makedirs("outputs/")
+
+
+#############################################################################################
+################################# MODEL DEFINITION ##########################################
+#############################################################################################
+
+input_1 = Input(shape=(index.max_len,))
+input_2 = Input(shape=(index.max_len,))
+
+embedding_layer = Embedding(num_words, EMBEDDING_DIM,input_length=index.max_len,weights=[embedding_weights],trainable=False)#, trainable=True)
+
+x1 = embedding_layer(input_1)
+x2 = embedding_layer(input_2)
+
+# Each LSTM learn on a permutation of the input toponyms
+if args.lstm_layer == 2:
+    x1 = Bidirectional(LSTM(100))(x1)
+    x2 = Bidirectional(LSTM(100))(x2)
+    x = concatenate([x1,x2])
+else:
+    lstm_unique_layer = Bidirectional(LSTM(100))
+    x1 = lstm_unique_layer(x1)
+    x2 = lstm_unique_layer(x2)
+    x = concatenate([x1,x2])
+
+x1 = Dense(500,activation="relu")(x)
+x1 = Dense(500,activation="relu")(x1)
+
+x2 = Dense(500,activation="relu")(x)
+x2 = Dense(500,activation="relu")(x2)
+
+output_lon = Dense(1,activation="sigmoid",name="Output_LON")(x1)
+output_lat = Dense(1,activation="sigmoid",name="Output_LAT")(x2)
+
+output_coord = concatenate([output_lon,output_lat],name="output_coord")
+
+model = Model(inputs = [input_1,input_2], outputs = output_coord)#input_3
+model.compile(loss={"output_coord":haversine_tf_1circle}, optimizer='adam',metrics={"output_coord":accuracy_k(ACCURACY_TOLERANCE)})
+
+print("Neural Network Architecture : ")
+print(model.summary())
+#############################################################################################
+################################# TRAINING LAUNCH ###########################################
+#############################################################################################
+
+checkpoint = ModelCheckpoint(MODEL_OUTPUT_FN + ".part", monitor='loss', verbose=1,
+    save_best_only=True, mode='auto', period=1)
+
+epoch_timer = EpochTimer("outputs/"+PREFIX_OUTPUT_FN+"_epoch_timer_output.csv")
+
+
+
+history = model.fit(training_generator,verbose=True,
+                    validation_data=validation_generator,
+                    callbacks=[checkpoint,epoch_timer],epochs=EPOCHS)
+
+# history = model.fit(x=[X_1_train,X_2_train],
+#     y=y_train,
+#     verbose=True, batch_size=100,
+#     epochs=EPOCHS,
+#     validation_data=([X_1_test,X_2_test],y_test),#[y_lon_test,y_lat_test]),
+#     callbacks=[checkpoint,epoch_timer])
+
+
+hist_df = pd.DataFrame(history.history)
+hist_df.to_csv(HISTORY_FN)
+
+model.save(MODEL_OUTPUT_FN)
+
+# Erase Model Checkpoint file
+if os.path.exists(MODEL_OUTPUT_FN + ".part"):
+    try:
+        import shutil
+        shutil.rmtree(MODEL_OUTPUT_FN + ".part")
+    except: # Depends on Keras version
+        os.remove(MODEL_OUTPUT_FN + ".part")
\ No newline at end of file
diff --git a/train_test_split_cooccurrence_data.py b/train_test_split_cooccurrence_data.py
new file mode 100644
index 0000000..47fb607
--- /dev/null
+++ b/train_test_split_cooccurrence_data.py
@@ -0,0 +1,68 @@
+import argparse
+
+import pandas as pd
+import numpy as np
+import geopandas as gpd
+
+import logging
+logging.basicConfig(
+    format='[%(asctime)s][%(levelname)s] %(message)s ', 
+    datefmt='%m/%d/%Y %I:%M:%S %p',
+    level=logging.INFO
+    )
+
+from sklearn.model_selection import train_test_split
+from shapely.geometry import Point
+
+from lib.utils_geo import latlon2healpix
+
+from tqdm import tqdm 
+
+parser = argparse.ArgumentParser()
+parser.add_argument("cooccurrence_file")
+parser.add_argument("-s",action="store_true")
+
+args = parser.parse_args()#("data/wikipedia/cooccurrence_FR.txt".split())#("data/geonamesData/FR.txt".split())
+
+# LOAD DATAgeopandas
+COOC_FN = args.cooccurrence_file
+
+logging.info("Load Cooc DATA data...")
+cooc_data = pd.read_csv(COOC_FN,sep="\t").fillna("")
+logging.info("Cooc data loaded!")
+
+
+cooc_data["cat"] = cooc_data.apply(lambda x:latlon2healpix(x.latitude,x.longitude,64),axis=1)
+
+# TRAIN AND TEST SPLIT
+logging.info("Split Between Train and Test")
+
+#  Cell can be empty
+i=0
+while 1:
+    if len(cooc_data[cooc_data.cat == i])> 1:
+        X_train,X_test = train_test_split(cooc_data[cooc_data.cat == i])
+        break
+    i+=1
+
+for i in np.unique(cooc_data.cat.values):
+    try:
+        if not args.s:
+            x_train,x_test = train_test_split(cooc_data[cooc_data.cat == i])
+        else:
+            x_train,x_test = train_test_split(cooc_data[cooc_data.cat == i].sample(frac=0.1))
+
+        X_train,X_test = pd.concat((X_train,x_train)),pd.concat((X_test,x_test))
+    except Exception as e:
+        print(e) #print("Error",len(filtered[filtered.cat == i]))
+
+del X_train["cat"]
+del X_test["cat"]
+
+# SAVING THE DATA
+logging.info("Saving Output !")
+suffix =""
+if args.s:
+    suffix = "10per"
+X_train.to_csv(COOC_FN+suffix+"_train.csv")
+X_test.to_csv(COOC_FN+suffix+"_test.csv")
diff --git a/train_test_split_geonames.py b/train_test_split_geonames.py
new file mode 100644
index 0000000..9aaf449
--- /dev/null
+++ b/train_test_split_geonames.py
@@ -0,0 +1,66 @@
+import argparse
+
+import numpy as np
+import pandas as pd
+import geopandas as gpd
+
+import logging
+logging.basicConfig(
+    format='[%(asctime)s][%(levelname)s] %(message)s ', 
+    datefmt='%m/%d/%Y %I:%M:%S %p',
+    level=logging.INFO
+    )
+
+from sklearn.model_selection import train_test_split
+
+from lib.utils_geo import latlon2healpix
+from helpers import read_geonames
+
+from tqdm import tqdm 
+
+parser = argparse.ArgumentParser()
+parser.add_argument("geoname_file")
+parser.add_argument("--feature_classes",help="List of class",default="A P")
+
+args = parser.parse_args()#("data/geonamesData/FR.txt".split())
+
+# LOAD DATAgeopandas
+GEONAME_FN = args.geoname_file
+FEATURE_CLASSES = args.feature_classes
+
+
+logging.info("Load Geonames data...")
+geoname_data = read_geonames(GEONAME_FN).fillna("")
+logging.info("Geonames data loaded!")
+
+# SELECT ENTRY with class == to A and P (Areas and Populated Places)
+filtered = geoname_data[geoname_data.feature_class.isin(FEATURE_CLASSES.split())].copy() # Only take area and populated places
+
+filtered["cat"] = filtered.apply(lambda x:latlon2healpix(x.latitude,x.longitude,64),axis=1)
+# TRAIN AND TEST SPLIT
+logging.info("Split Between Train and Test")
+
+#  Cell can be empty
+cat_unique = filtered.cat.unique()
+ci=0
+while 1:
+    if len(filtered[filtered.cat == cat_unique[ci]])> 1:
+        X_train,X_test = train_test_split(filtered[filtered.cat == cat_unique[ci]])
+        break
+    ci+=1
+
+for i in cat_unique[ci:] :
+    try:
+        x_train,x_test = train_test_split(filtered[filtered.cat == i])
+        X_train,X_test = pd.concat((X_train,x_train)),pd.concat((X_test,x_test))
+    except:
+        pass #print("Error",len(filtered[filtered.cat == i]))
+
+
+del X_train["cat"]
+del X_test["cat"]
+
+# SAVING THE DATA
+logging.info("Saving Output !")
+X_train.to_csv(GEONAME_FN+"_train.csv")
+X_test.to_csv(GEONAME_FN+"_test.csv")
\ No newline at end of file
-- 
GitLab