Code source de papierstat.datasets.duration

# -*- coding: utf-8 -*-
"""
Jeux de données artificiel lié à la prédiction de durées.


:githublink:`%|py|6`
"""
from datetime import datetime, timedelta
import pandas
from numpy.random import randn, rand, gamma


[docs]def duration_selling(date_begin=None, date_end=None, mean_per_day=10, sigma_per_day=5, week_pattern=None, hour_begin=9, hour_end=19, gamma_k=6., gamma_theta=0.25): """ Construit un jeu de données artificiel qui simule des paquets préparés par un magasin. Chaque paquet est préparé dès la réception d'une commande à une heure précise, il est ensuite stocké jusqu'à ce qu'un client viennent le chercher. :param date_begin: première date :param date_end: dernière date :param hour_begin: heure d'ouverture du magasin :param hour_end: heure de fermeture du magasin :param week_pattern: tableau de 7 valeurs ou None pour une distribution uniforme sur les jours de la semaine :param mean_per_day: nombre de paquets moyen par jour (suit une loi gaussienne) :param sigma_per_day: écart type pour la loi gaussienne :param gamma_k: paramètre *k* d'une loi gamma :param gamma_theta: paramètre :math:`\\theta` d'une loi gamma :return: jeu de données .. runpython:: :showcode: from papierstat.datasets.duration import duration_selling print(duration_selling().head()) Les commandes sont réparties de façon uniformes sur la journée même si c'est peu probable. La durée suit une loi :math:`\\Gamma`. Cette durée est ajoutée à l'heure où est passée la commande, les heures nocturnes et le week-end ne sont pas comptées. La durée ne peut excéder 10h. .. runpython:: :rst: from papierstat.datasets.documentation import list_notebooks_rst_links links = list_notebooks_rst_links('lectures', 'artificiel_duration') links = [' * %s' % s for s in links] print('\\n'.join(links)) :githublink:`%|py|54` """ if date_begin is None: date_begin = datetime.now() - timedelta(365, 1, 1) date_begin = datetime( date_begin.year, date_begin.month, date_begin.day) if date_end is None: date_end = datetime.now() date_end = datetime(date_end.year, date_end.month, date_end.day) if date_begin >= date_end: raise ValueError( # pragma: no cover "begin >= end {0} >= {1}".format(date_begin, date_end)) if week_pattern is None: week_pattern = [1.] * 5 + [0., 0.] gauss = randn(1000) pos_gauss = 0 uni = rand(1000) pos_uni = 0 gam = gamma(gamma_k, gamma_theta, 1000) pos_gam = 0 add1d = timedelta(seconds=24 * 3600) - \ (timedelta(seconds=hour_end * 3600) - timedelta(seconds=hour_begin * 3600)) day_duration = (hour_end - hour_begin) * 3600 date_begin += timedelta(seconds=hour_begin * 3600) rows = [] while date_begin <= date_end: wk = date_begin.weekday() nb = max(int(week_pattern[wk] * mean_per_day), 0) if nb == 0: date_begin += timedelta(days=1) continue nb += gauss[pos_gauss] * sigma_per_day # pylint: disable=E1136 nb = int(max(nb, 0)) pos_gauss += 1 if pos_gauss >= len(gauss): gauss = randn(1000) pos_gauss = 0 if nb == 0: date_begin += timedelta(days=1) continue for _ in range(0, int(nb)): db = uni[pos_uni] * day_duration # pylint: disable=E1136 pos_uni += 1 if pos_uni >= len(uni): uni = rand(1000) pos_uni = 0 g = min(gam[pos_gam] * 3600, 36000) # pylint: disable=E1136 pos_gam += 1 if pos_gam >= len(gam): gam = gamma(gamma_k, gamma_theta, 1000) pos_gam = 0 rec = dict(commande=date_begin + timedelta(seconds=db)) rec['true_duration'] = g / 3600 end = rec['commande'] + timedelta(seconds=g) if end.hour >= hour_end or end.hour < hour_begin: end += add1d while end.weekday() >= 5: end += timedelta(seconds=24 * 3600) rec["reception"] = end rows.append(rec) date_begin += timedelta(days=1) return pandas.DataFrame(rows)