path = window.location.pathname.replace(".html", ".qmd");
path_modified = (path.includes('en/content')) ? path.replace('en/content', 'content/en') : path
html`${printBadges({fpath: path_modified})}`
Pour essayer les exemples présents dans ce tutoriel :
html`<div>${getConditionalHTML(path, true)}</div>`
function getConditionalHTML(path, print) {
if (print === false) return ``
if (isBetweenSeptAndDec()) {
return md`<i>La correction sera visible prochainement sur cette page. En attendant, la liste des corrections déjà acccessibles est [ici](/content/annexes/corrections.html)</i>`; // Return an empty string if not between the dates
else {
} return html`
<details>
<summary>
Pour ouvrir la version corrigée sous forme de <i>notebook</i>
</summary>
${printBadges({ fpath: path, correction: true })}
</details>
`;
} }
function renderCorrection({ fpath, correction }) {
if (correction) {
return html`${printBadges({ fpath: fpath, correction: true })}`;
else {
} return html`<i>La correction sera visible prochainement sur cette page.</i>`;
} }
Ce chapitre est issu du travail produit dans le cadre d’un hackathon de l’Insee avec Raphaële Adjerad et présente quelques éléments qui peuvent être utiles pour l’enrichissement de données d’entreprises à partir d’un répertoire officiel.
:warning: Il nécessite une version particulière du package elasticsearch
pour tenir compte de l’héritage de la version 7 du moteur Elastic. Pour cela, faire
==8.2.0 pip install elasticsearch
1 Introduction
Dans le cadre particulier de l’identification des entreprises, Elasticsearch fait partie de la solution retenue par l’API “Sirene données ouvertes” (DINUM) (cf https://annuaire-entreprises.data.gouv.fr/) l’API de recherche d’entreprises Française de la Fabrique numérique des Ministères Sociaux (cf https://api.recherche-entreprises.fabrique.social.gouv.fr/)le projet de l’Insee “Amélioration de l’identification de l’employeur dans le recensement”, pour faire une première sélection des établissements pertinents pour un bulletin de recensement donné. Dans le cadre de l’identification des individus, Elasticsearch fait partie de la solution envisagée pour l’identification des individus au RNIPP (Répertoire national des personnes physiques) pour le projet CSNS (Code statistique non signifiant), et est la solution technique sous-jacente au projet matchID du ministère de l’intérieur.
Au delà du secteur public, on peut citer qu’Amazon AWS fait partie des utilisateurs historiques d’Elasticsearch.
1.1 Objectif
Ce chapitre vise à approfondir les éléments présentés sur Elastic précédemment. L’idée est de se placer dans un contexte opérationnel où on reçoit des informations sur des entreprises telles que l’adresse et la localisation et qu’on désire associer à des données administratives considérées plus fliables.
1.2 Réplication de ce chapitre
Comme le précédent, ce chapitre est plus exigeant en termes d’infrastructures que les précédents. Il nécessite un serveur Elastic. Les utilisateurs du SSP Cloud pourront répliquer les exemples de ce cours car cette technologie est disponible (que ce soit pour indexer une base ou pour requêter une base existante).
La première partie de ce tutoriel, qui consiste à créer une base Sirene géolocalisée à partir des données open-data ne nécessite pas d’architecture particulière et peut ainsi être exécutée en utilisant les packages suivants :
import numpy as np
import pandas as pd
1.3 Sources
Ce chapitre va utiliser plusieurs sources de diffusion de l’Insee:
- Le stock des établissements présents dans les données de diffusion Sirene ;
- Les données Sirene géolocalisées
Les données à siretiser sont celles du registre Français des émissions polluantes établi par le Ministère de la Transition Energétique. Le jeu de données est disponible sur data.gouv
2 Préparation des données à identifier
Le jeu de données présente déjà
l’identifiant
de l’établissement, dit numéro siret
.
Nous allons faire comme si nous étions
en amont de cet appariement et que nous
désirons trouver ce numéro. La présence
dans la base de ce numéro nous permettra d’évaluer la qualité
de notre méthode de recherche avec
Elastic
.
import requests
import zipfile
import pandas as pd
= "https://www.data.gouv.fr/fr/datasets/r/9af639b9-e2b6-4d7d-8c5f-0c4953c48663"
url = requests.get(url)
req
with open("irep.zip", "wb") as f:
f.write(req.content)
with zipfile.ZipFile("irep.zip", "r") as zip_ref:
"irep")
zip_ref.extractall(
= pd.read_csv("irep/2019/etablissements.csv", sep=";") etablissements
3 Constitution du référentiel administratif géolocalisé
Dans un premier temps, on va combiner ensemble les différentes sources open-data pour créer un référentiel fiable d’entreprises géolocalisées.
3.1 Importer la base déjà créée
Les données à utiliser pour constuire une base Sirene géolocalisée
sont trop volumineuses pour les serveurs mis à disposition
gratuitement par Github
pour la compilation de ce site web.
Nous proposons ainsi une version déjà construite, stockée
dans l’espace de mise à disposition du SSP Cloud. Ce fichier est
au format parquet
et est ouvert à
tous, même pour les personnes ne disposant pas d’un compte.
Le code ayant construit cette base est présenté ci-dessous.
Pour importer cette base, on utilise les fonctionalités
de pyarrow
qui permettent d’importer un fichier sur
un système de stockage cloud comme s’il était
présent sur le disque :
from pyarrow import fs
import pyarrow as pa
import pyarrow.parquet as pq
= "lgaliana"
bucket = "diffusion/sirene_geolocalized.parquet"
path
= fs.S3FileSystem(endpoint_override="http://" + "minio.lab.sspcloud.fr")
s3
= (
df_geolocalized f"{bucket}/{path}", filesystem=s3).read_pandas().to_pandas()
pq.ParquetDataset(
)3) df_geolocalized.head(
3.2 Reproduire la construction de la base
La première base d’entrée à utiliser est disponible sur data.gouv
import requests
import zipfile
= (
url_download "https://www.data.gouv.fr/fr/datasets/r/0651fb76-bcf3-4f6a-a38d-bc04fa708576"
)= requests.get(url_download)
req
with open("sirene.zip", "wb") as f:
f.write(req.content)
with zipfile.ZipFile("sirene.zip", "r") as zip_ref:
"sirene") zip_ref.extractall(
On va importer seulement les colonnes utiles et simplifier la structure pour être en mesure de ne garder que les informations qui nous intéressent (nom de l’entreprise, adresse, commune, code postal…)
import pandas as pd
import numpy as np
= [
list_cols "siren",
"siret",
"activitePrincipaleRegistreMetiersEtablissement",
"complementAdresseEtablissement",
"numeroVoieEtablissement",
"typeVoieEtablissement",
"libelleVoieEtablissement",
"codePostalEtablissement",
"libelleCommuneEtablissement",
"codeCommuneEtablissement",
"etatAdministratifEtablissement",
"denominationUsuelleEtablissement",
"activitePrincipaleEtablissement",
]
= pd.read_csv("sirene/StockEtablissement_utf8.csv", usecols=list_cols)
df
"numero"] = (
df["numeroVoieEtablissement"]
df["-", np.NaN)
.replace(str.split()
.str[0]
.str.extract("(\d+)", expand=False)
."0")
.fillna(int)
.astype(
)
"numero"] = df["numero"].astype(str).replace("0", "")
df[
"adresse"] = (
df["numero"]
df[+ " "
+ df["typeVoieEtablissement"]
+ " "
+ df["libelleVoieEtablissement"]
)
"adresse"] = df["adresse"].replace(np.nan, "")
df[
= df.loc[df["etatAdministratifEtablissement"] == "A"]
df
df.rename(
{"denominationUsuelleEtablissement": "denom",
"libelleCommuneEtablissement": "commune",
"codeCommuneEtablissement": "code_commune",
"codePostalEtablissement": "code_postal",
},="columns",
axis=True,
inplace
)
"ape"] = df["activitePrincipaleEtablissement"].str.replace("\.", "", regex=True)
df["denom"] = df["denom"].replace(np.nan, "")
df[
= df.loc[
df_siret
:,
["siren",
"siret",
"adresse",
"ape",
"denom",
"commune",
"code_commune",
"code_postal",
],
]"code_postal"] = (
df_siret["code_postal"]
df_siret["0")
.replace(np.nan, int)
.astype(str)
.astype("0", "")
.replace( )
On importe ensuite les données géolocalisées
import zipfile
import shutil
import os
# os.remove("sirene.zip")
# shutil.rmtree('sirene/')
= "https://files.data.gouv.fr/insee-sirene-geo/GeolocalisationEtablissement_Sirene_pour_etudes_statistiques_utf8.zip"
url_geoloc = requests.get(url_geoloc)
r
with open("geoloc.zip", "wb") as f:
f.write(r.content)
with zipfile.ZipFile("geoloc.zip", "r") as zip_ref:
"geoloc")
zip_ref.extractall(
= pd.read_csv(
df_geoloc "geoloc/GeolocalisationEtablissement_Sirene_pour_etudes_statistiques_utf8.csv",
=["siret", "epsg", "x_longitude", "y_latitude"],
usecols=";",
sep )
Il ne reste plus qu’à associer les deux jeux de données
= df_siret.merge(df_geoloc, on="siret")
df_geolocalized "code_commune"] = df_geolocalized["code_commune"].astype(str) df_geolocalized[
Si vous avez accès à un espace de stockage cloud de type
S3
, il est possible d’utiliser pyarrow
pour enregister
cette base. Afin de l’enregistrer dans un espace de stockage
public, nous allons l’enregistrer dans un dossier diffusion
1
from pyarrow import fs
import pyarrow as pa
import pyarrow.parquet as pq
= "lgaliana"
bucket = "diffusion/sirene_geolocalized.parquet"
path
= fs.S3FileSystem(endpoint_override="http://" + "minio.lab.sspcloud.fr")
s3
= pa.Table.from_pandas(df_geolocalized) table
4 Connexion à ElasticSearch
On va supposer que l’utilisateur dispose déjà d’un serveur Elastic fonctionnel mais désire créer un nouvel index. Si vous utilisez le SSPCloud, la démarche de création d’un service Elastic est disponible dans le chapitre précédent.
from elasticsearch import Elasticsearch
= "elasticsearch-master"
HOST
def elastic():
"""Connection avec Elastic sur le data lab"""
= Elasticsearch(
es "host": HOST, "port": 9200, "scheme": "http"}],
[{=True,
http_compress=200,
request_timeout
)return es
= elastic()
es es
<Elasticsearch(['http://elasticsearch-master:9200'])>
5 Indexation de notre base Sirène géolocalisée
5.1 Définition du mapping
On va procéder par étape en essayant d’utiliser la structure la plus simple possible.
:one: On s’occupe d’abord de définir le mapping pour les variables textuelles.
= ["adresse", "denom", "ape", "commune"]
string_var = {
map_string "type": "text",
"fields": {"keyword": {"type": "keyword", "ignore_above": 256}},
}= {l: map_string for l in string_var} mapping_string
:two: Les variables catégorielles sont utilisées
par le biais du type keyword
:
# keywords
= ["siren", "siret", "code_commune", "code_postal"]
keyword_var = {
map_keywords "type": "text",
"fields": {"keyword": {"type": "keyword", "ignore_above": 256}},
}= {l: map_keywords for l in keyword_var} mapping_keywords
:three: La nouveauté par rapport à la partie
précédente est l’utilisation de la
dimension géographique. Elastic
propose
le type geo_point
pour cela.
# geoloc
= {"location": {"type": "geo_point"}} mapping_geoloc
On collecte tout cela ensemble dans un dictionnaire:
# mapping
= {
mapping_elastic "mappings": {"properties": {**mapping_string, **mapping_geoloc, **mapping_keywords}}
}
Il est tout à fait possible de définir un mapping plus raffiné. Ici, on va privilégier l’utilisation d’un mapping simple pour illustrer la recherche par distance géographique en priorité.
5.2 Création de l’index
Pour créer le nouvel index, on s’assure d’abord de ne pas déjà l’avoir créé et on passe le mapping défini précédemment.
if es.indices.exists("sirene"):
"sirene")
es.indices.delete(
="sirene", body=mapping_elastic) es.indices.create(index
5.3 Indexation de la base géolocalisée
Pour le moment, l’index est vide. Il convient de le peupler.
Il est néanmoins nécessaire de créer le champ location
au format attendu par elastic: lat, lon
à partir
de nos colonnes.
"location"] = (
df_geolocalized["y_latitude"].astype(str)
df_geolocalized[+ ", "
+ df_geolocalized["x_longitude"].astype(str)
)
La fonction suivante permet de structurer chaque
ligne du DataFrame
telle qu’Elastic l’attend:
def gen_dict_from_pandas(index_name, df):
"""
Lit un dataframe pandas Open Food Facts, renvoi un itérable = dictionnaire des données à indexer, sous l'index fourni
"""
for i, row in df.iterrows():
= {"_op_type": "index", "_index": index_name, "_id": i}
header yield {**header, **row}
Enfin, on peut industrialiser l’indexation
de notre DataFrame
en faisant tourner de
manière successive cette fonction :
from elasticsearch.helpers import bulk, parallel_bulk
from collections import deque
deque(
parallel_bulk(=es,
client=gen_dict_from_pandas("sirene", df_geolocalized),
actions=1000,
chunk_size=4,
thread_count
) )
="sirene") es.count(index
ObjectApiResponse({'count': 13059694, '_shards': {'total': 1, 'successful': 1, 'skipped': 0, 'failed': 0}})
6 Recherche
Pour se faciliter la création de cartes réactives, nous allons régulièrement utiliser la fonction suivante qui s’appuie sur un code déjà présenté dans un autre chapitre.
def plot_folium_sirene(df, yvar, xvar):
= df[[yvar, xvar]].mean().values.tolist()
center = df[[yvar, xvar]].min().values.tolist()
sw = df[[yvar, xvar]].max().values.tolist()
ne
= folium.Map(location=center, tiles="OpenStreetMap")
m
# I can add marker one by one on the map
for i in range(0, len(df)):
folium.Marker(
[df.iloc[i][yvar], df.iloc[i][xvar]],=df.iloc[i]["_source.denom"]
popup+ f'<br>(Score: {df.iloc[i]["_score"]:.2f})',
=folium.Icon(icon="home"),
icon
).add_to(m)
m.fit_bounds([sw, ne])
return m
6.1 Premier exemple de requête géographique
= es.search(
ex1 ="sirene",
index="""{
body "query": {
"bool": {
"must":
{ "match": { "denom": "institut national de la statistique"}}
}
}
}
""",
"hits"]["hits"]
)[
= pd.json_normalize(ex1)
echo_insee echo_insee
On remarque déjà que les intitulés ne sont pas bons. Quand est-il de leurs localisations ?
="_source.y_latitude", xvar="_source.x_longitude") plot_folium_sirene(echo_insee, yvar
Ce premier essai nous suggère qu’il est nécessaire d’améliorer notre recherche. Plusieurs voies sont possibles:
- Améliorer le preprocessing de nos champs textuels en excluant, par exemple, les stopwords ;
- Effectuer une restriction géographique pour mieux cibler l’ensemble de recherche
- Trouver une variable catégorielle jouant le rôle de variable de blocage2 pour mieux cibler les paires pertinentes
Concernant la restriction géographique, Elastic fournit une approche très efficace de ciblage géographique. En connaissant une position approximative de l’entreprise à rechercher, il est ainsi possible de rechercher dans un rayon d’une taille plus ou moins grande. En supposant qu’on connaisse précisément la localisation de l’Insee, on peut chercher dans un rayon relativement restreint. Si notre position était plus approximative, on pourrait rechercher dans un rayon plus large.
= es.search(
ex2 ="sirene",
index="""{
body "query": {
"bool": {
"must":
{ "match": { "denom": "institut national de la statistique"}}
,
"filter":
{"geo_distance": {
"distance": "1km",
"location": {
"lat": "48.8168",
"lon": "2.3099"
}
}
}
}
}
}
""",
"hits"]["hits"]
)[
= pd.json_normalize(ex2)
echo_insee echo_insee
Hint
Connaître la localisation précise d’une entreprise nécessite déjà une bonne remontée d’information sur celle-ci. Il est plus plausible de supposer qu’on dispose, dans une phase amont de la chaine de production, de l’adresse de celle-ci. Dans ce cas, il est utile d’utiliser un service de géocodage, comme l’API Adresse développée par Etalab.
Les résultats sont par construction mieux ciblés. Néanmoins ils sont toujours décevants puisqu’on ne parvient pas à identifier l’Insee dans les dix meilleurs échos.
= es.search(
specificsearch ="sirus_2020",
index="""{
body "query": {
"bool": {
"should":
{ "match": { "rs_denom": "CPCU - CENTRALE DE BERCY"}},
"filter": [
{"geo_distance": {
"distance": "0.5km",
"location": {
"lat": "48.84329",
"lon": "2.37396"
}
}
},
{ "prefix": { "apet": "3530" }}
]
}
}
}""",
)
Informations additionnelles
environment files have been tested on.
Latest built version: 2024-12-07
Python version used:
'3.12.6 | packaged by conda-forge | (main, Sep 30 2024, 18:08:52) [GCC 13.3.0]'
Package | Version |
---|---|
affine | 2.4.0 |
aiobotocore | 2.15.1 |
aiohappyeyeballs | 2.4.3 |
aiohttp | 3.10.8 |
aioitertools | 0.12.0 |
aiosignal | 1.3.1 |
alembic | 1.13.3 |
altair | 5.4.1 |
aniso8601 | 9.0.1 |
annotated-types | 0.7.0 |
anyio | 4.7.0 |
appdirs | 1.4.4 |
archspec | 0.2.3 |
asttokens | 2.4.1 |
attrs | 24.2.0 |
babel | 2.16.0 |
bcrypt | 4.2.0 |
beautifulsoup4 | 4.12.3 |
black | 24.8.0 |
blinker | 1.8.2 |
blis | 0.7.11 |
bokeh | 3.5.2 |
boltons | 24.0.0 |
boto3 | 1.35.23 |
botocore | 1.35.23 |
branca | 0.7.2 |
Brotli | 1.1.0 |
cachetools | 5.5.0 |
cartiflette | 0.0.2 |
Cartopy | 0.24.1 |
catalogue | 2.0.10 |
cattrs | 24.1.2 |
certifi | 2024.8.30 |
cffi | 1.17.1 |
charset-normalizer | 3.3.2 |
click | 8.1.7 |
click-plugins | 1.1.1 |
cligj | 0.7.2 |
cloudpathlib | 0.20.0 |
cloudpickle | 3.0.0 |
colorama | 0.4.6 |
comm | 0.2.2 |
commonmark | 0.9.1 |
conda | 24.9.1 |
conda-libmamba-solver | 24.7.0 |
conda-package-handling | 2.3.0 |
conda_package_streaming | 0.10.0 |
confection | 0.1.5 |
contextily | 1.6.2 |
contourpy | 1.3.0 |
cryptography | 43.0.1 |
cycler | 0.12.1 |
cymem | 2.0.10 |
cytoolz | 1.0.0 |
dask | 2024.9.1 |
dask-expr | 1.1.15 |
databricks-sdk | 0.33.0 |
dataclasses-json | 0.6.7 |
debugpy | 1.8.6 |
decorator | 5.1.1 |
Deprecated | 1.2.14 |
diskcache | 5.6.3 |
distributed | 2024.9.1 |
distro | 1.9.0 |
docker | 7.1.0 |
duckdb | 0.10.1 |
en-core-web-sm | 3.7.1 |
entrypoints | 0.4 |
et_xmlfile | 2.0.0 |
exceptiongroup | 1.2.2 |
executing | 2.1.0 |
fastexcel | 0.11.6 |
fastjsonschema | 2.21.1 |
fiona | 1.10.1 |
Flask | 3.0.3 |
folium | 0.17.0 |
fontawesomefree | 6.6.0 |
fonttools | 4.54.1 |
frozendict | 2.4.4 |
frozenlist | 1.4.1 |
fsspec | 2023.12.2 |
gensim | 4.3.2 |
geographiclib | 2.0 |
geopandas | 1.0.1 |
geoplot | 0.5.1 |
geopy | 2.4.1 |
gitdb | 4.0.11 |
GitPython | 3.1.43 |
google-auth | 2.35.0 |
graphene | 3.3 |
graphql-core | 3.2.4 |
graphql-relay | 3.2.0 |
graphviz | 0.20.3 |
great-tables | 0.12.0 |
greenlet | 3.1.1 |
gunicorn | 22.0.0 |
h11 | 0.14.0 |
h2 | 4.1.0 |
hpack | 4.0.0 |
htmltools | 0.6.0 |
httpcore | 1.0.7 |
httpx | 0.28.1 |
httpx-sse | 0.4.0 |
hyperframe | 6.0.1 |
idna | 3.10 |
imageio | 2.36.1 |
importlib_metadata | 8.5.0 |
importlib_resources | 6.4.5 |
inflate64 | 1.0.0 |
ipykernel | 6.29.5 |
ipython | 8.28.0 |
itsdangerous | 2.2.0 |
jedi | 0.19.1 |
Jinja2 | 3.1.4 |
jmespath | 1.0.1 |
joblib | 1.4.2 |
jsonpatch | 1.33 |
jsonpointer | 3.0.0 |
jsonschema | 4.23.0 |
jsonschema-specifications | 2024.10.1 |
jupyter-cache | 1.0.0 |
jupyter_client | 8.6.3 |
jupyter_core | 5.7.2 |
kaleido | 0.2.1 |
kiwisolver | 1.4.7 |
langchain | 0.3.10 |
langchain-community | 0.3.9 |
langchain-core | 0.3.22 |
langchain-text-splitters | 0.3.2 |
langcodes | 3.5.0 |
langsmith | 0.1.147 |
language_data | 1.3.0 |
lazy_loader | 0.4 |
libmambapy | 1.5.9 |
locket | 1.0.0 |
lxml | 5.3.0 |
lz4 | 4.3.3 |
Mako | 1.3.5 |
mamba | 1.5.9 |
mapclassify | 2.8.1 |
marisa-trie | 1.2.1 |
Markdown | 3.6 |
markdown-it-py | 3.0.0 |
MarkupSafe | 2.1.5 |
marshmallow | 3.23.1 |
matplotlib | 3.9.2 |
matplotlib-inline | 0.1.7 |
mdurl | 0.1.2 |
menuinst | 2.1.2 |
mercantile | 1.2.1 |
mizani | 0.11.4 |
mlflow | 2.16.2 |
mlflow-skinny | 2.16.2 |
msgpack | 1.1.0 |
multidict | 6.1.0 |
multivolumefile | 0.2.3 |
munkres | 1.1.4 |
murmurhash | 1.0.11 |
mypy-extensions | 1.0.0 |
narwhals | 1.16.0 |
nbclient | 0.10.0 |
nbformat | 5.10.4 |
nest_asyncio | 1.6.0 |
networkx | 3.3 |
nltk | 3.9.1 |
numpy | 1.26.4 |
opencv-python-headless | 4.10.0.84 |
openpyxl | 3.1.5 |
opentelemetry-api | 1.16.0 |
opentelemetry-sdk | 1.16.0 |
opentelemetry-semantic-conventions | 0.37b0 |
orjson | 3.10.12 |
OWSLib | 0.28.1 |
packaging | 24.1 |
pandas | 2.2.3 |
paramiko | 3.5.0 |
parso | 0.8.4 |
partd | 1.4.2 |
pathspec | 0.12.1 |
patsy | 0.5.6 |
Pebble | 5.1.0 |
pexpect | 4.9.0 |
pickleshare | 0.7.5 |
pillow | 10.4.0 |
pip | 24.2 |
platformdirs | 4.3.6 |
plotly | 5.24.1 |
plotnine | 0.13.6 |
pluggy | 1.5.0 |
polars | 1.8.2 |
preshed | 3.0.9 |
prometheus_client | 0.21.0 |
prometheus_flask_exporter | 0.23.1 |
prompt_toolkit | 3.0.48 |
protobuf | 4.25.3 |
psutil | 6.0.0 |
ptyprocess | 0.7.0 |
pure_eval | 0.2.3 |
py7zr | 0.20.8 |
pyarrow | 17.0.0 |
pyarrow-hotfix | 0.6 |
pyasn1 | 0.6.1 |
pyasn1_modules | 0.4.1 |
pybcj | 1.0.2 |
pycosat | 0.6.6 |
pycparser | 2.22 |
pycryptodomex | 3.21.0 |
pydantic | 2.10.3 |
pydantic_core | 2.27.1 |
pydantic-settings | 2.6.1 |
Pygments | 2.18.0 |
PyNaCl | 1.5.0 |
pynsee | 0.1.8 |
pyogrio | 0.10.0 |
pyOpenSSL | 24.2.1 |
pyparsing | 3.1.4 |
pyppmd | 1.1.0 |
pyproj | 3.7.0 |
pyshp | 2.3.1 |
PySocks | 1.7.1 |
python-dateutil | 2.9.0 |
python-dotenv | 1.0.1 |
python-magic | 0.4.27 |
pytz | 2024.1 |
pyu2f | 0.1.5 |
pywaffle | 1.1.1 |
PyYAML | 6.0.2 |
pyzmq | 26.2.0 |
pyzstd | 0.16.2 |
querystring_parser | 1.2.4 |
rasterio | 1.4.3 |
referencing | 0.35.1 |
regex | 2024.9.11 |
requests | 2.32.3 |
requests-cache | 1.2.1 |
requests-toolbelt | 1.0.0 |
retrying | 1.3.4 |
rich | 13.9.4 |
rpds-py | 0.22.3 |
rsa | 4.9 |
ruamel.yaml | 0.18.6 |
ruamel.yaml.clib | 0.2.8 |
s3fs | 2023.12.2 |
s3transfer | 0.10.2 |
scikit-image | 0.24.0 |
scikit-learn | 1.5.2 |
scipy | 1.13.0 |
seaborn | 0.13.2 |
setuptools | 74.1.2 |
shapely | 2.0.6 |
shellingham | 1.5.4 |
six | 1.16.0 |
smart-open | 7.0.5 |
smmap | 5.0.0 |
sniffio | 1.3.1 |
sortedcontainers | 2.4.0 |
soupsieve | 2.5 |
spacy | 3.7.5 |
spacy-legacy | 3.0.12 |
spacy-loggers | 1.0.5 |
SQLAlchemy | 2.0.35 |
sqlparse | 0.5.1 |
srsly | 2.4.8 |
stack-data | 0.6.2 |
statsmodels | 0.14.4 |
tabulate | 0.9.0 |
tblib | 3.0.0 |
tenacity | 9.0.0 |
texttable | 1.7.0 |
thinc | 8.2.5 |
threadpoolctl | 3.5.0 |
tifffile | 2024.9.20 |
toolz | 1.0.0 |
topojson | 1.9 |
tornado | 6.4.1 |
tqdm | 4.66.5 |
traitlets | 5.14.3 |
truststore | 0.9.2 |
typer | 0.15.1 |
typing_extensions | 4.12.2 |
typing-inspect | 0.9.0 |
tzdata | 2024.2 |
Unidecode | 1.3.8 |
url-normalize | 1.4.3 |
urllib3 | 1.26.20 |
wasabi | 1.1.3 |
wcwidth | 0.2.13 |
weasel | 0.4.1 |
webdriver-manager | 4.0.2 |
websocket-client | 1.8.0 |
Werkzeug | 3.0.4 |
wheel | 0.44.0 |
wordcloud | 1.9.3 |
wrapt | 1.16.0 |
xgboost | 2.1.1 |
xlrd | 2.0.1 |
xyzservices | 2024.9.0 |
yarl | 1.13.1 |
yellowbrick | 1.5 |
zict | 3.0.0 |
zipp | 3.20.2 |
zstandard | 0.23.0 |
View file history
SHA | Date | Author | Description |
---|---|---|---|
005d89b | 2023-12-20 17:23:04 | Lino Galiana | Finalise l’affichage des statistiques Git (#478) |
3fba612 | 2023-12-17 18:16:42 | Lino Galiana | Remove some badges from python (#476) |
1f23de2 | 2023-12-01 17:25:36 | Lino Galiana | Stockage des images sur S3 (#466) |
a06a268 | 2023-11-23 18:23:28 | Antoine Palazzolo | 2ème relectures chapitres ML (#457) |
b68369d | 2023-11-18 18:21:13 | Lino Galiana | Reprise du chapitre sur la classification (#455) |
889a71b | 2023-11-10 11:40:51 | Antoine Palazzolo | Modification TP 3 (#443) |
652009d | 2023-10-09 13:56:34 | Lino Galiana | Finalise le cleaning (#430) |
154f09e | 2023-09-26 14:59:11 | Antoine Palazzolo | Des typos corrigées par Antoine (#411) |
9977c5d | 2023-08-28 10:43:36 | Lino Galiana | Fix bug path pandas (#397) |
3bdf3b0 | 2023-08-25 11:23:02 | Lino Galiana | Simplification de la structure 🤓 (#393) |
29ff3f5 | 2023-07-07 14:17:53 | linogaliana | description everywhere |
f10815b | 2022-08-25 16:00:03 | Lino Galiana | Notebooks should now look more beautiful (#260) |
bacb5a0 | 2022-07-04 19:05:20 | Lino Galiana | Enrichir la partie elastic (#241) |
Notes de bas de page
Concernant la première piste, il aurait fallu mieux définir notre mapping pour autoriser des analyzers. A défaut, nous pourrons utiliser
nltk
ouspacy
pour transformer les champs textuels avant d’envoyer la requête. Cette solution présente l’inconvénient de ne pas formatter de la même manière l’ensemble indexé mais pourrait malgré tout améliorer la pertinence des recherches.↩︎Concernant la première piste, il aurait fallu mieux définir notre mapping pour autoriser des analyzers. A défaut, nous pourrons utiliser
nltk
ouspacy
pour transformer les champs textuels avant d’envoyer la requête. Cette solution présente l’inconvénient de ne pas formatter de la même manière l’ensemble indexé mais pourrait malgré tout améliorer la pertinence des recherches.↩︎
Citation
BibTeX
@book{galiana2023,
author = {Galiana, Lino},
title = {Python pour la data science},
date = {2023},
url = {https://pythonds.linogaliana.fr/},
doi = {10.5281/zenodo.8229676},
langid = {fr}
}
Veuillez citer ce travail comme suit :
Galiana, Lino. 2023. Python pour la data science. https://doi.org/10.5281/zenodo.8229676.