Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# -*- coding: utf-8 -*- 

2""" 

3@file 

4@brief Jeux de données artificiel lié à la prédiction de durées. 

5""" 

6from datetime import datetime, timedelta 

7import pandas 

8from numpy.random import randn, rand, gamma 

9 

10 

11def duration_selling(date_begin=None, date_end=None, 

12 mean_per_day=10, sigma_per_day=5, 

13 week_pattern=None, 

14 hour_begin=9, hour_end=19, 

15 gamma_k=6., gamma_theta=0.25): 

16 """ 

17 Construit un jeu de données artificiel qui simule des paquets 

18 préparés par un magasin. Chaque paquet est préparé dès la réception 

19 d'une commande à une heure précise, il est ensuite stocké 

20 jusqu'à ce qu'un client viennent le chercher. 

21 

22 @param date_begin première date 

23 @param date_end dernière date 

24 @param hour_begin heure d'ouverture du magasin 

25 @param hour_end heure de fermeture du magasin 

26 @param week_pattern tableau de 7 valeurs ou None 

27 pour une distribution uniforme sur les jours 

28 de la semaine 

29 @param mean_per_day nombre de paquets moyen par jour (suit une loi gaussienne) 

30 @param sigma_per_day écart type pour la loi gaussienne 

31 @param gamma_k paramètre *k* d'une loi gamma 

32 @param gamma_theta paramètre :math:`\\theta` d'une loi gamma 

33 @return jeu de données 

34 

35 .. runpython:: 

36 :showcode: 

37 

38 from papierstat.datasets.duration import duration_selling 

39 print(duration_selling().head()) 

40 

41 Les commandes sont réparties de façon uniformes sur la journée 

42 même si c'est peu probable. La durée suit une loi :math:`\\Gamma`. 

43 Cette durée est ajoutée à l'heure où est passée la commande, 

44 les heures nocturnes et le week-end ne sont pas comptées. 

45 La durée ne peut excéder 10h. 

46 

47 .. runpython:: 

48 :rst: 

49 

50 from papierstat.datasets.documentation import list_notebooks_rst_links 

51 links = list_notebooks_rst_links('lectures', 'artificiel_duration') 

52 links = [' * %s' % s for s in links] 

53 print('\\n'.join(links)) 

54 """ 

55 if date_begin is None: 

56 date_begin = datetime.now() - timedelta(365, 1, 1) 

57 date_begin = datetime( 

58 date_begin.year, date_begin.month, date_begin.day) 

59 if date_end is None: 

60 date_end = datetime.now() 

61 date_end = datetime(date_end.year, date_end.month, date_end.day) 

62 if date_begin >= date_end: 

63 raise ValueError( # pragma: no cover 

64 "begin >= end {0} >= {1}".format(date_begin, date_end)) 

65 if week_pattern is None: 

66 week_pattern = [1.] * 5 + [0., 0.] 

67 

68 gauss = randn(1000) 

69 pos_gauss = 0 

70 uni = rand(1000) 

71 pos_uni = 0 

72 gam = gamma(gamma_k, gamma_theta, 1000) 

73 pos_gam = 0 

74 add1d = timedelta(seconds=24 * 3600) - \ 

75 (timedelta(seconds=hour_end * 3600) - timedelta(seconds=hour_begin * 3600)) 

76 

77 day_duration = (hour_end - hour_begin) * 3600 

78 date_begin += timedelta(seconds=hour_begin * 3600) 

79 

80 rows = [] 

81 while date_begin <= date_end: 

82 wk = date_begin.weekday() 

83 nb = max(int(week_pattern[wk] * mean_per_day), 0) 

84 if nb == 0: 

85 date_begin += timedelta(days=1) 

86 continue 

87 nb += gauss[pos_gauss] * sigma_per_day # pylint: disable=E1136 

88 nb = int(max(nb, 0)) 

89 pos_gauss += 1 

90 if pos_gauss >= len(gauss): 

91 gauss = randn(1000) 

92 pos_gauss = 0 

93 if nb == 0: 

94 date_begin += timedelta(days=1) 

95 continue 

96 for _ in range(0, int(nb)): 

97 db = uni[pos_uni] * day_duration # pylint: disable=E1136 

98 pos_uni += 1 

99 if pos_uni >= len(uni): 

100 uni = rand(1000) 

101 pos_uni = 0 

102 

103 g = min(gam[pos_gam] * 3600, 36000) # pylint: disable=E1136 

104 pos_gam += 1 

105 if pos_gam >= len(gam): 

106 gam = gamma(gamma_k, gamma_theta, 1000) 

107 pos_gam = 0 

108 

109 rec = dict(commande=date_begin + timedelta(seconds=db)) 

110 rec['true_duration'] = g / 3600 

111 end = rec['commande'] + timedelta(seconds=g) 

112 if end.hour >= hour_end or end.hour < hour_begin: 

113 end += add1d 

114 while end.weekday() >= 5: 

115 end += timedelta(seconds=24 * 3600) 

116 rec["reception"] = end 

117 rows.append(rec) 

118 date_begin += timedelta(days=1) 

119 return pandas.DataFrame(rows)