Extraction d’échantillons à partir de fichiers à accès séquentiel ne tenant
pas en mémoire centrale – Stratégie pour la modélisation prédictive
Ricco Rakotomalala
Ricco Rakotomalala
Tutoriels Tanagra - [Link] 1
Echantillonnage dans le contexte big data
• Contexte big data : la taille des bases à traiter devient un enjeu essentiel
Chargement en mémoire de la totalité des données n’est plus possible parfois
Temps de traitements prohibitifs (lorsqu’ils sont possibles)
Développement des technologies big data (informatique distribuée essentiellement)
• Une stratégie alternative existe : travailler sur des échantillons.
Licite parce qu’il y a une forme de redondance (plus ou moins forte) dans les données
Traiter une fraction permet de généraliser (inférer) sur le reste de la base
• Deux enjeux importants :
Technique : échantillonner efficacement dans une base qu’on ne peut pas charger en
mémoire
Stratégique : S’assurer une qualité de modélisation équivalente à celle du modèle
construit sur la base complète (dans le cadre de l’apprentissage supervisé)
Ricco Rakotomalala
Tutoriels Tanagra - [Link] 2
Configuration technique
Base initiale
• Fichier texte CSV (comma separated value)
• Très gros volume, ne tient pas en mémoire centrale
• Accès séquentiel
• Individus non pondérés
Objectif – Extraction d’un échantillon de taille « n »
• Les individus doivent avoir une probabilité identique d’intégrer l’échantillon
• Traitement en une seule passe sur les données
• Production de l’échantillon directement dans un fichier à part ou
conservation de l’échantillon en mémoire
• Facilement extensible pour la partition d’une base en ensembles
d’apprentissage et de test pour la modélisation prédictive
Ricco Rakotomalala
Tutoriels Tanagra - [Link] 3
Plan
1. Echantillonnage lorsque la taille N est connue
2. Reservoir sampling (N inconnu)
3. Stratégies pour l’apprentissage supervisé
4. Conclusion
Ricco Rakotomalala
Tutoriels Tanagra - [Link] 4
La taille « N » de la base de sondage est connue. Soit fournie a priori, soit parce qu’il a été
possible d’effectuer une passe préalable (pas trop coûteuse en ressources) sur les données.
Ricco Rakotomalala
Tutoriels Tanagra - [Link] 5
Utilisation d’un index
sample(1:N,n,replace=F) # par exemple sous R
[Link](1,N,n) #par exemple sous Python
• Générer un vecteur d’index IDX de taille « n »,
extrait entre 1 et N sans répétition
• Ouvrir le fichier source en lecture # pour une
lecture ligne par ligne (séquentielle)
Attention à « i », selon que la
• i := 0 #numéro de ligne première correspond aux
• TANT QUE pas fin de fichier noms de variables ou non.
• Lire une ligne
• i := i + 1 L’opérateur %in% peut être
coûteux. En triant les indices
• SI i %in% IDX de manière croissante, on
• ALORS Charger ligne en mémoire ou peut imaginer une gestion
plus efficace, et même
l’écrire dans un fichier de sortie s’arrêter avant d’atteindre la
• FIN SI fin du fichier.
• FIN TANT QUE
Ricco Rakotomalala
Tutoriels Tanagra - [Link] 6
Création d’un index
Comment générer les index si l’on ne dispose pas d’une fonction dédiée ?
• Générer N valeurs aléatoires Ce tri de N valeurs
peut être coûteux
• Récupérer les indices des valeurs triées
en temps de calcul.
• Récupérer les n premiers indices
#valeurs aléatoires #valeurs aléatoires
N <- 1000 N = 1000
v <- runif(N) v = [Link](N)
#argument du tri #argument de tri
argument <- order(v) argument = [Link](v)
#prendre les n premiers indices #prendre les n premiers indices
n <- 10 n = 10
idx <- argument[1:n] idx = argument[:n]
print(idx) print(idx)
Code R Code Python
Ricco Rakotomalala
Tutoriels Tanagra - [Link] 7
Extraction sans utilisation d’un index – Méthode de sélection rejet
On peut s’affranchir du vecteur d’index avec une gestion fine de la
probabilité d’inclusion et un générateur de nombres aléatoires.
• Entrée : N, n et fichier source
• Ouvrir le fichier source # lecture séquentielle
• TANT QUE n > 0 ALEA() générateur de
• Lire une ligne valeurs aléatoires U(0,1)
• SI N * ALEA() <= n
Le dispositif fonctionne même si N = n
• ALORS
• Ecrire ligne dans sortie
• n := n - 1
• FIN SI
• N := N – 1 # péréquation de la probabilité d’inclusion
• FIN TANT QUE
Pour cette approche, les lignes dans l’échantillon sont forcément
dans le même ordre que dans la source initiale.
Ricco Rakotomalala
Tutoriels Tanagra - [Link] 8
Extraction sans utilisation d’un index (Python)
#vecteur de valeurs - représente le fichier source
N = 1000 Pour les besoins de l’illustration, la source ici est
source = [Link](N)
indicée. Mais la transposition à un fichier à accès
#n séquentiel est facile (« i » est incrémentée
n = 10 seulement d’une valeur à chaque passage dans la
boucle dans notre exemple)
#boucler tant qu'il y a des valeurs à extraire
i = -1
while (n > 0):
#simule la lecture de la ligne
i = i + 1
#test d’inclusion Pour une lecture ligne par ligne dans un fichier
if (N * [Link]() <= n): texte, voir readline() [Les fichiers sous Python,
#valeur récupérée
page 7]
print(source[i])
#un élément en moins à extraire
n = n - 1
#
N = N - 1
Ricco Rakotomalala
Tutoriels Tanagra - [Link] 9
Extraction sans utilisation d’un index (R)
#vecteur de valeurs
N <- 1000
source <- 1:N
#n
n <- 10
#échantillon initialisation
echantillon <- c()
Pour une lecture ligne par ligne dans un fichier #boucler
i = 0
texte sous R, voir readLines() [Read Text Lines while (n > 0){
from a Connection] #id pour lecture
i <- i + 1
#test d'inclusion
if (N * runif(1) <= n){
echantillon <- c(echantillon, source[i])
#un de moins à extraire
n <- n - 1
}
#un élément de moins de la source
#à traiter
N <- N - 1
}
#affichage
print(echantillon)
Ricco Rakotomalala
Tutoriels Tanagra - [Link] 10
La taille « N » de la base de sondage est inconnue ou trop coûteuse à acquérir
Ricco Rakotomalala
Tutoriels Tanagra - [Link] 11
Réservoir sampling (Algorithm R – Vitter, 1985)
Principe : Contrainte :
1. charger les « n » premiers individus dans une collection • Maintenir la collection en mémoire
2. mettre à jour cette collection au fur et à mesure de la • Ou tout du moins dans une structure
où un accès indicé est possible.
lecture des individus restants
Initialisation : remplissage
• Entrée : n et fichier source du « réservoir » avec les n
• Sortie : C un collection avec n lignes
premières lignes du fichier
• Pour i:= 0 à n-1 ; C[i]:= Lire une ligne
source.
• t := n
• TANT QUE pas fin de fichier
Permet une péréquation de la
• Lire une ligne
• t := t + 1 probabilité d’être dans le réservoir
• k := TRUNC(t * ALEA()) # 0 ≤ k ≤ t-1 au fil des intégrations / retraits.
• SI k < n
• ALORS C[k]:= ligne
• FIN SI Mise à jour du « réservoir »
• FIN TANT QUE à l’indice n°k.
𝑛
Chaque item a une probabilité d’inclusion (Wikipédia, Reservoir Sampling)
𝑐𝑎𝑟𝑑(𝑠𝑜𝑢𝑟𝑐𝑒)
Ricco Rakotomalala
Tutoriels Tanagra - [Link] 12
Réservoir sampling (Python) import math, numpy
#vecteur de valeurs - représente le fichier source
N = 1000
Ici aussi, pour les besoins de source = [Link](N)
l’illustration, la source est indicée. Mais
#collection à remplir
la transposition à un fichier à accès n = 10
séquentiel est facile (« i » est collection = [Link](n)
incrémentée seulement d’une valeur à #remplissage du réservoir
chaque passage dans la boucle dans for i in range(n):
collection[i] = source[i]
notre exemple)
#initialisation
t = n
L’ordre des lignes n’est pas préservée
#tant que pas fin de source
dans cette approche. for i in range(n,N):
t = t + 1
k = [Link](t * [Link]())
if (k < n):
collection[k] = source[i]
#
#
print(collection)
Ricco Rakotomalala
Tutoriels Tanagra - [Link] 13
Réservoir sampling (R)
#vecteur de valeurs
N <- 1000
source <- 1:N
#n
n <- 10
#réservoir initialisation
La similitude avec le code Python n’a rien
collection <- source[1:n]
de fortuit.
#initialisation
t = n + 1
Dans ce code R, la boucle for sur la
source n’est pas très efficace. Mais elle #tant que pas fin de source
est inévitable lorsque l’on devra la for (i in (n+1):N){
t <- t + 1
transposer en une lecture ligne par ligne
k <- floor(t * runif(1))
dans un fichier à accès séquentiel. if (k <= n){
collection[k] <- source[i]
}
}
#affichage
print(collection)
Ricco Rakotomalala
Tutoriels Tanagra - [Link] 14
Déterminer la taille suffisante d’échantillon (n*) pour obtenir un modèle
aussi performant que celui qui aurait été élaboré sur la totalité de la base
Ricco Rakotomalala
Tutoriels Tanagra - [Link] 15
Stratégie d’échantillonnage pour l’apprentissage supervisé
• Construire le modèle sur un échantillon
• Avec une qualité prédictive équivalente au modèle qui aurait été élaboré
Objectif
sur la totalité des données
Gain de temps, plus de possibilités d’optimisation des paramètres.
Parfois seule solution qui rend les calculs possibles.
• Choisir un critère d’évaluation du modèle
• Démarrer avec une taille d’échantillon initiale, modéliser, évaluer
Démarche
• Augmenter graduellement la taille de l’échantillon jusqu’à ce que le critère
stagne. C’est un signe que l’on épuisé l’information « utile » des données.
• Paramètres : taille initiale, nombre d’observations additionnelles à chaque
étape.
Ricco Rakotomalala
Tutoriels Tanagra - [Link] 16
Solution 1 – Random sampling – Augmentation graduelle
Augmentation de la taille de l’échantillon (n = n + na)
(pourrait être un
échantillon déjà)
Dataset pour la Echantillon, ensemble Construction de la fonction
modélisation d’apprentissage (n) f(.) à partir de l’échantillon
Y = f(X1,X2,…)
Application du modèle
(prédiction) sur l’ensemble de test
Dataset Mesures de
(Y , Yˆ )
performances par
confrontation
Y : valeurs observées entre Y et Y^ (ex.
Dataset pour l’évaluation Y^ : valeurs prédites par f(.) taux d’erreur)
(on pourrait choisir de ne travailler
que sur un échantillon pour le test) Evolution du taux d'erreur
0.40
0.35
0.30
0.25
Taux d'erreur
0.20
Courbe d’évolution du 0.15
critère d’évaluation 0.10
0.05
0.00
Ricco Rakotomalala 0 1 2 3 4 5 6 7
Tutoriels Tanagra - [Link]
Etapes 17
Solution 1 – Exemple : Analyse discriminante + Waveform
na = 200
Echantillon, ensemble Construction de la fonction f(.)
Dataset pour la modélisation d’apprentissage (n) à partir de l’échantillon
20.000 obs.
Y = f(X1,X2,…)
ninit = 200
Application du modèle (prédiction) sur l’ensemble d’évaluation
𝑒𝑟𝑟(𝑌, 𝑌)
Dataset
100.000 obs. Taux d'erreur vs. Taille Echantillon
80.000 obs.
Dataset pour l’évaluation
0.22
0.20
Taux d'erreur
A partir de n* 3000 individus, la
0.18
décroissance de l’erreur en évaluation est
marginale (taux d’erreur 14%) 0.16
0.14
1000 2000 3000 4000 5000
Taile d'échantillon
Ricco Rakotomalala
Tutoriels Tanagra - [Link] 18
Solution 2 – Windowing Les rajouter à l’ensemble
Ensemble
d’apprentissage
d’apprentissage
Construction de la fonction
f(.) à partir de l’échantillon
Y = f(X1,X2,…)
Application du modèle (prédiction) sur
l’ensemble de test
Dataset pour la
modélisation Identifier les
(Y , Yˆ )
Dataset
(soit la totalité, soit
individus mal classés
un échantillon)
Ensemble de test
Les individus bien classés à l’étape
courante deviennent l’ensemble de test
Arrêt du • Tous les individus de l’ensemble de test sont bien classés
processus,
lorsque • L’erreur ne décroît plus sur un ensemble d’évaluation à part
Ricco Rakotomalala
Tutoriels Tanagra - [Link] 19
Solution 2 – Windowing - Exemple Dégradation à la première itération puisqu’on a introduit toutes les
observations à problème (au détriment des données « utiles »).
Base de travail = 20000 Taux d'erreur vs. Taille Echantillon
Taille initiale échantillon = 200
0.40
0.35
Taux d'erreur en évaluation
Taille base évaluation = 80000
0.30
0.25
Non requis habituellement pour le
0.20
windowing, mais nous l’utilisons pour
suivre de taux d’erreur en généralisation.
0.15
0 2000 4000 6000 8000 10000 12000
Taile d'échantillon
Convergence plus rapide
(moins d’itérations). Mais taille
d’échantillon plus grande.
habituellement
• Convergence plus rapide (ici arrêt parce que tous les individus sont bien classés sur le reste de la base
Constaté
de travail). Taille de la base finale n* = 12570
• Mais le modèle final est moins bon parfois (à taille égale par rapport à la solution 1) lorsque la base
est bruitée (la méthode peut mettre excessivement l’accent sur le bruit et/ou sur les outliers)
• Bon comportement en revanche sur les bases « propres » (cf. Hoeksma)
Ricco Rakotomalala
Tutoriels Tanagra - [Link] 20
Ricco Rakotomalala
Tutoriels Tanagra - [Link] 21
Algorithmes d’échantillonnage rapides
• Des variantes plus rapides existent pourvu que l’on puisse « sauter » plusieurs enregistrements
vers l’avant lors de la sélection des lignes (soit parce que la source est en accès indexé, soit
parce que le saut est moins coûteux que la lecture ligne par ligne)
• Des variantes existent pour l’appréhension des pondérations des individus (tirage avec des
probabilités inégales)
• Des algorithmes distribués existent pour tirer parti des clusters de machines
Stratégies d’échantillonnage pour la modélisation prédictive
• L’expérimentation menée ici n’a pas valeur de preuve (une base, un algo de machine learning)
• Quoiqu’il en soit, travailler sur des échantillon peut être bénéfique
• La taille optimale n* de l’échantillon dépend de la base traitée et de la méthode de machine
learning utilisée : on doit passer par l’expérimentation.
Ricco Rakotomalala
Tutoriels Tanagra - [Link] 22
Ricco Rakotomalala
Tutoriels Tanagra - [Link] 23
Références
• Deville J.C., Grosbras J.M., « Chapitre 10 - Algorithmes de tirage », in « Les sondages »,
Droesbeke J.J., Fichet B., Tassi P., editeurs, Economica, 1988.
• Vitter J.S., « Random Sampling with a reservoir », in ACM Transactions on
Mathematical Software, 11(1), pp. 37-57, 1985.
• Wikipedia, « Reservoir Sampling ».
• Hoeksma S., « Machine Learning and Data: Exploring the Potential of Windowing ».
Ricco Rakotomalala
Tutoriels Tanagra - [Link] 24