Le Deep Learning et le hasard – Prédiction du Loto

L’étude mathématique de la loterie est aussi ancienne que les mathématiques. On peut citer les travaux de Leonard Euler qui ont conduit à la théorie de la probabilité de Kolmogorov [Kolmogorov, 1933]. À ce jour peu d’ouvrages existent sur la résolution du problème très difficile voire impossible de prédire des tirages de numéros de loterie à cause de l’indépendance des tirages (aléatoires) et donc de l’inexistence de patterns à apprendre pour les modèles.

Une grande question me vient alors en tête : et si malgré leur caractère aléatoire, les boules lors des tirages se retrouvent dans les mêmes positions que certains tirages passés, et sont mélangés à la même vitesse, ces informations ne peuvent-elles pas permettre à des modèles d’apprendre ces patterns et nous conduire à prédire les prochains numéros tirés ?

L’apprentissage profond a prouvé ses capacités dans la résolution de nombreux problèmes différents, qu’il s’agisse de la reconnaissance vocale, la reconnaissance d’images ou encore la reconnaissance d’écriture manuscrite. Ses algorithmes dont la structure est inspirée du fonctionnement du cerveau humain sont capables de capturer la structure sous-jacente de n’importe quel jeu de données avec des résultats très concluants.

Ainsi l’objectif de cet article est de montrer les résultats de l’apprentissage profond sur un cas concret de hasard.

Pour ce faire je présenterai dans cet article un modèle de prédiction des tirages du loto français en utilisant les tirages du passé comme données d’apprentissage.

Généralités et présentation du loto français

Le Loto est un jeu célèbre qui fait appel au hasard. Celui-ci est tellement répandu dans le monde entier que même les petits états comme le Vatican dont la papauté était initialement contre les jeux d’argent et de hasard, dispose aujourd’hui de leur propre loto permettant de lever des fonds pour des actions caritatives.[1] La dynastie Han a même utilisé les bénéfices du loto pour financer la grande muraille de chine.[2]

Le principe de la loterie est très simple : les gens achètent un ticket qui correspond à un pari combiné sur un ensemble général de chiffres. Un tirage au sort sans remise est finalement effectué à une date et une heure fixes. Les gains sont liés à la façon dont la combinaison correspond au tirage au sort. Le jackpot est gagné si la combinaison est correcte.

Dans cet article, je me concentrerai sur le loto français.

Pour jouer, il suffit de cocher 6 numéros :

  • 5 numéros sur une grille de 49 numéros
  • 1 numéro de chance sur une grille de 10 numéros

Le jackpot est remporté si on a parié les 5 bons numéros plus le numéro de chance.

Le prix d’une grille est de 2,20 € et le jackpot minimum est de 2 millions d’euros.[3]

Collecte des données et calcul de features

Les données ont été scrapées sur le site de la française des jeux (fdj) qui recense tous les tirages du loto depuis 2008 à ce jour. Le dernier tirage à la date de rédaction de cet article datait du 21 octobre 2020 avec un total de 1921 tirages entre le 6 octobre 2008 et cette date.

Obtention dataset

La prédiction des numéros de loto est une tâche supervisée : les tirages du passé sont utilisés comme données d’entrées en supposant les tirages dépendants même si ce n’est pas le cas dans la réalité. Ainsi en apprenant ces numéros du passé, on suppose que ce sont des numéros obtenus à partir d’une certaine position initiale des boules dans l’urne et un mélange à une certaine vitesse.

Les données que j’ai retenues après calcul pour chaque tirage sont :

  • Le nombre de fois que chaque numéro est apparu dans les tirages précédents
  • La présence de nombre pair ou impair
  • La somme de la différence au carré entre chaque couple de numéros successifs dans le tirage
  • Le nombre de numéros en dessous de 24
  • Le nombre de numéros en dessous de 40
Code dataset

Modèle

Les réseaux de neurones récurrents (RNN) se sont révélés comme étant l’un des modèles les plus puissants pour le traitement de données séquentielles. La mémoire à long court terme est l’une des architectures RNN la plus réussie. LSTM introduit la cellule mémoire, une unité de calcul qui remplace les neurones artificiels traditionnels dans la couche cachée du réseau. Avec ces cellules de mémoire, les réseaux sont capables d’associer efficacement des mémoires et d’entrer dans le temps, ce qui permet de saisir la structure des données de manière dynamique dans le temps avec une capacité de prédiction élevée.

Architecture du LSTM
Architecture d’un LSTM [4]
\[f_t=\sigma(w_f[h_t-1, X_t]+b_f)\] \[i_t=\sigma(W_I[h_t-1, X_t] + b_i)\] \[c_t=tan(W_c[h_t-1, X_t] + b_c)\] \[O_t=\sigma(W_o[h_t-1, X_t] + b_o)\] \[C_t=f_t*C_t-1 + i_t*c_t\] \[h_t=O_t*\tanh(C_t)\]
– \(f_t\) : Porte d’oubli, décide s’il faut remettre à 0 le contenu de la cellule.
– \(O_t\) : porte de sortie, décide si le contenu de la cellule doit influer sur la sortie du neurone.
– \(i_t\) : Porte d’entrée, décide si l’entrée doit modifier le contenu de la cellule.

[5]

– \(C_t\) : Mise à jour de l’état de la cellule.
– \(h_t\) : Sortie de la cellule.

Formation du réseau

Notre modèle LSTM est composé d’une couche d’entrée séquentielle suivie d’une couche LSTM et d’une couche de sortie dense avec fonction d’activation linéaire.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import pickle
from sklearn.preprocessing import StandardScaler
from keras.models import Sequential
from keras.layers import LSTM, Dense, Bidirectional, TimeDistributed, RepeatVector, Flatten
from keras.callbacks import EarlyStopping

UNITS = 100
BATCHSIZE = 30
EPOCH = 1000
#ACTIVATION = "softmax"
OPTIMIZER ='adam' # rmsprop, adam, sgd
LOSS = 'mae'#'categorical_crossentropy' #mse
DROPOUT = 0.1
window_length =12 #12 
number_of_features = df.shape[1]

#Architecture du modèle
def define_model(number_of_features,nb_label_feature):
    #initialisation du rnn
    model = Sequential()
    #ajout de la premiere couche lstm
    model.add(LSTM(UNITS, input_shape=(window_length, number_of_features), return_sequences=True))
    model.add(LSTM(UNITS, dropout=0.1, return_sequences=False))
    #ajout de la couche de sortie
    model.add(Dense(nb_label_feature))
    model.compile(loss=LOSS, optimizer=OPTIMIZER, metrics=['acc'])
    return model

Optimiseur

J’ai choisi d’utiliser l’optimiseur Adam. L’optimiseur Adam combine les avantages de deux autres optimiseurs : ADAgrad et RMSprop. Cette méthode calcule les taux d’apprentissage adaptatif pour chaque paramètre en considérant la moyenne en décroissance exponentielle des gradients carrés passés et la moyenne en décroissance exponentielle des gradients passés.[6] Cela peut être représenté par :

Optimimiseur

Où v et m peuvent être considérés comme les estimations du premier et du deuxième moment des gradients respectivement, d’où le nom d’estimation de moment adaptatif.[7]

Les avantages de cet optimiseur sont résumés comme suit :

  • Le taux d’apprentissage est différent pour chaque paramètre et chaque itération
  • L’apprentissage ne diminue pas comme avec l’ADAgrad
  • Une descente plus solide d’un point de vue statistique.[6

Entraînement

Avant d’entraîner un modèle LSTM, il faut une préparation minimum de la donnée afin de s’accommoder à la dimension voulue par les RNNs en particulier le LSTM. En effet, la donnée en entrée doit avoir trois dimensions (samples, timesteps, feature).

  • Samples désigne le nombre d’échantillons ou d’observations
  • Timesteps est le pas de temps
  • Feature est le nombre de caractéristiques ou de variables à étudier

Ainsi pour notre suite de tirage, j’ai dû implémenter une fonction permettant de transformer la séquence initiale à la forme attendue en entrée du LSTM en choisissant un timesteps sur un mois soit 12 tirages car trois tirages sont réalisés par semaine pour le loto français.

Par exemple pour la première séquence de 13 tirages \(S=[t_1, t_2, t_3, …, t_{13}]\)
L’entrée \(X = [[t_1], [t_2], [t_3], [t_4], …, [t_{12}]]\) avec \(X\) de la forme \((1, 12, 19)\) car ayant \(19\) features calculés au total pour chaque tirage
La sortie \(Y = [[t_{13}]]\) avec Y de la forme \((1,1,6)\) car l’on désire ici prédire les bons numéros du tirage \(13\).

On peut donc concrètement représenter les entrées et sorties à partir des 13 premiers tirages avec des LSTM comme suit :

Architecture des entrées et sorties LSTM des 13 premiers tirages
Architecture des entrées et sorties LSTM des 13 premiers tirages

où les xi représentent les différents tirages.

Une fois l’architecture de mon modèle LSTM prête, il ne reste qu’à entrainer le modèle.

Pour ce faire, mon dataset d’entrainement est constitué de tous les tirages scrapés et ma donnée de test représente le prochain tirage.

C’est à dire que j’entraine le modèle sur toutes les données disponibles, et j’effectue une prédiction sur le prochain tirage qui représente ma donnée de test. Je procède de la sorte afin de m’assurer qu’à chaque tirage, le modèle ait appris du tirage précédent. Ainsi à chaque nouvelle date de tirage, un nouveau modèle est entrainé. Cette méthode a fait ces preuves, dans la mesure où j’arrive très souvent à prédire 3 numéros parmi les 6 tout en étant proche des autres numéros non trouvés. Voyons un exemple concret.

Résultats d’apprentissage sur le tirage du 21 octobre 2020

Pour ce test j’ai commencé par supprimer du dataset d’entraînement le tirage du 21 octobre afin de l’utiliser comme donnée de test.

Le modèle converge après 830 epochs avec une précision de 92% sur les données de train.

Epochs
Epochs

Résultats de prédiction pour le tirage du 21 octobre 2020

Résultats

Le résultat officiel du tirage du 21 octobre 2020 sur le site de la fdj est donné par les numéros suivants : [15 21 33 35 48 01]. [8]

Et comme vous pouvez le constater le modèle prédit bien 3 numéros à savoir le 15 le 21 et 1 pour le numéro de chance.

Résultats de prédiction pour le tirage du 24 octobre 2020

Résultat

Le résultat officiel du tirage du 24 octobre 2020 sur le site de la fdj est donné par les numéros suivants : [4 8 12 25 45 02]. [9]

Comme vous pouvez le constater pour ce tirage le numéro 8 a été bien prédit par contre deux autres numéros dont le 3 et le 46 sont très proches du vrai résultat respectivement à une somme et différence près de 1.

Jusque-là mon modèle n’arrive qu’à prédire au maximum pour certains tirages 3 bons numéros sur 6 ou s’en rapproche ce qui permet d’évaluer sa précision globale sur le loto français à ce jour à 50%.

Remarque

Le réapprentissage du modèle sur les mêmes données d’apprentissage risque de donner une prédiction différente s’approchant encore plus du vrai tirage ou même s’en éloignant. Quelqu’un me dira mais pourquoi ne pas effectuer une cross-validation sur le training set afin d’avoir un modèle robuste qui prédira toujours la même sortie même après plusieurs entraînements du modèle sur les mêmes données ?

Le principe même de la validation croisée qui consiste à diviser le dataset en plusieurs portions et d’utiliser de manière itérative chaque petite portion comme valeur de test et les grandes comme valeurs de train en supposant que les échantillons sont indépendants n’est pas adapté aux LSTM qui apprennent des valeurs historiques pour prédire l’avenir. Je laisse cette question ouverte à tout commentaire 😃

Conclusion

En dépit de l’indépendance des tirages, le modèle LSTM arrive très souvent à prédire certains bon numéros en supposant que ceux-ci sont dépendants. Ces résultats proviennent-ils du hasard ? non je ne pense pas. Plus de travail est nécessaire pour optimiser le modèle afin de pouvoir éventuellement remporter le jackpot un de ces jours. J’envisage par exemple de personnaliser le calcul de l’erreur en prenant en compte les erreurs de prédictions qui se traduisent par de petites différences de 1 ou 2 en plus ou en moins.

Le code du modèle est disponible ici.

N’hésitez pas à laisser votre avis si vous avez aimé cet article 😊

90 commentaires
  1. monnet dit

    travail trés instructifs , serait il possible d’avoir le code associé?
    cdt
    john

  2. wilfried dit

    Bien sûr , laissez votre mail où écrivez à l’adresse wilfriedkouadio3009@gmail.com.
    cdt
    Wilfried

  3. Nossi dit

    Article très intéressant, travail laborieux, j’y porte aussi un intérêt.
    Je vous contacterai.
    cdt
    Marius

  4. monnet dit

    fait !

  5. Zeph dit

    Un travail intéressant relaté dans cet article !
    Serait-il possible d’avoir accès au code source comme mentionné en fin d’article ?
    Merci beaucoup

  6. Arnaud dit

    Bonjour,

    Tout d’abord je tiens à vous remercier pour cet article fort intéressant !

    Je vous ai écrit il y a quelques temps à votre adresse e-mail mais n’ai pas eu de retour, vous n’avez peut être pas vu 🙂

    Bien à vous,
    Arnaud

  7. Laza dit

    très intéressant , est ce que je peux avoir le code source s’il vous plait?

  8. Doc dit

    Bonjour,
    Merci beaucoup pour cet article passionnant qui m’a permis d’avoir un premier aperçu de ce genre d’analyse.
    Je vous ai envoyé un mail il y a quelques jours afin d’obtenir le code source, histoire de mieux comprendre le fonctionnement du depp learning.
    En espérant avoir de vos nouvelles et de nouveaux articles à lire prochainement.
    A bientôt !

  9. Doc dit

    Re-bonjour,
    Petite question en attendant d’avoir le script, quel paramètre d’activation utilisez-vous en entrée et sortie ? Sur votre schéma de l’architecture LSTM, vous indiquez la fonction tanh tandis que dans l’image de votre script, on peut voir en commentaire la fonction softmax ?
    La fonction softmax ne semble pas être le meilleur choix puisque le tirage d’une boule n+1 constitue une probabilité conditionnelle après tirage de la boule n).

  10. sam dit

    Bonjour,
    Merci beaucoup pour cet article.
    serait il possible d’avoir le code?

  11. wilfried dit

    Bonjour,
    Merci pour ce coup d’oeil,
    J’utilise bien la fonction tanh qui est la fonction d’activation par défaut utilisée pour LSTM dans keras. La softmax en commentaire est un test que j’ai oublié de supprimer et comme vous pouvez le voir je n’utilise pas la variable ACTIVATION dans la définition du model (:

    Pour le code je pense avoir répondu à tous les mails reçus ce week-end. Si ce n’est pas le cas pour vous veuillez juste m’écrire à l’adresse wilfriedkouadio3009@gmail.com

    cdt,
    Wilfried

  12. Doc dit

    Bonjour,
    Merci beaucoup pour votre réponse, à la lecture de l’exemple je m’étais posé la question.
    Du coup non, moi je n’ai pas reçu le code. Je vous renvoie un mail de ce pas 🙂 J’aimerai beaucoup regarder d’un peu plus près la méthode que vous utilisez. J’ai trouvé d’autres scripts sur le net qui proposent des méthodes différentes (dont un qui est particulièrement bien expliqué). L’étude combinée de ces deux méthodes me permettra de progresser.
    Merci encore pour votre retour
    Doc.

  13. Alea dit

    Bonjour,
    Une remarque: vous fixez des conditions au départ (pair inférieur à… etc..), je pensais que l’ IA “apprenait” à chaque nouveau tirage et en tirait SES conditions?
    J’aimerais recevoir votre code merci
    Cordialement
    À.

  14. A dit

    Bonjour,
    je pensais que l’analyse IA apprenait SES paramètres au fur et à mesure des tirages, or je vois que vous lui donnez des paramètres au départ {pair, inférieur à…etc), ce qui ressemble à une simple analyse statistique (ce qui sort le plus souvent)?

    J’aimerais bien recevoir votre code, merci
    Cordialement.

  15. Ferd dit

    Bonjour , Après de nombreux mails envoyés , je n’ai toujours pas le code . Quelqu’un d’entre vous a eu la chance de le recevoir ?
    Si Oui peut-il me l’envoyer ?

  16. Wilfried dit

    Bonjour Ferd,
    Désolé de vous répondre que maintenant, j’ai du manquer vos maills précédents étant donné que je reçois beaucoup de demandes.
    Je viens de vous l’envoyer. Pouvez vous confirmer que vous l’avez bien reçu?

    Par ailleurs, pour tous ceux qui ne l’ont pas encore reçu, veuillez patienter un tout petit peu car à cause du grand nombre de demandes , je suis en train de déployer le code afin qu’il soit accessible à tous (:

  17. wilfried dit

    Bonjour Alea,
    Ce ne sont pas des conditions de départ mais des features calculées à partir des numéros (statistiques comme vous l’avez mentionné dans votre deuxième commentaire) qui permettent aux modèles de mieux apprendre des caractéristiques des numéros des tirages en entrée.

    Pour le code je viens de vérifier ma boîte mail et je ne trouve aucune demande associée à votre nom.
    Veuillez m’écrire en mentionnant votre pseudo.

    Bien à vous.

  18. wilfried dit

    Bonjour Doc,
    J’ai bien reçu votre mail ainsi que l’article traitant du même sujet qui est tout aussi très interessant.
    Pouvez vous me confirmer que vous avez bien reçu le code?

    Bien à vous.

  19. Ferd dit

    Bonjour, j’ai bien reçu le notebook , merci Mr Kouadio 🙏🏾

    1. Hugues dit

      Bonjour,
      Article super intéressant, bravo pour cette recherche!
      Pourrai-je avoir votre code svp?
      Merci
      hugtipialive.fr
      a=@

  20. Arnaud dit

    Bonjour,

    Je vous ai écris et je n’ai pas eu de retour à mon e-mail 🙁
    Arnaud

  21. hsai dit

    Bonjour,

    est-il possible d’avoir le code associé ? merci

  22. tiamat dit

    Bonjour,

    Comment faite vous pour gérer la dernier entrée X ? Elle n’est pas de la même taille que les autres ? Faites vous des paquets de 12 “glissants” ?

    merci d’avance,

  23. tiamat dit

    Bonjour,

    malgré plusieurs mails je n’ai toujours pas reçu votre code,.

    Bien cordialement,

  24. brown dit

    bonjour je vous ai envoyé plusieurs mails et essayé de vous joindre via ce site pour avoir le code. Ce-serais possible de me l’envoyer ?

    Merci d’avance

  25. Eric dit

    Bonjour, article très intéressant. Si vous pouvez m’envoyez votre code, ca m’aiderait à comprendre la méthode. je vous ai envoyé un mail pour vous le demander, mais il a du se perdre dans tous ceux que vous recevez 🙁 . Merci d’avance !

  26. Cyril dit

    Bonjour,
    Serait-il possible d’obtenir le code ?
    Merci,

  27. Cyril dit

    Je ne pas pu l’avoir malgré mes emails. dommage..

  28. john dit

    Bonjour,

    Merci pour cet article très intéressant, je vous ai déjà envoyé un mail mail je réitère par le biais de ce commentaire : est il possible d’avoir le code complet svp? merci
    bien cordialement

  29. tiamat dit

    Moi non plus…

  30. artyom dit

    Bonjour,

    Votre article est très intéressant, je suis moi même intéressé pour recevoir le script complet.
    Je vous ai envoyé un email.

    Merci par avance

  31. Damien dit

    Bel article sur un sujet passionnant !

  32. David dit

    Si quelqu’un a le code en entier, peut-il le partager ? Wilfried ne réponds plus aux mails :/
    Merci bien !

  33. Said dit

    Bonjour,

    Excellent travail , je suis tres curieux de voir votre code, Je vous ai écris par mail , je vous remercie d’avance.

    Cordialement

    Said

  34. Wilfried dit

    Hello Chers tous,

    Désolé pour ce retard, comme promis vous trouverez désormais le code sur git :
    https://github.com/berba1995/Deep_Learning_et_le_Hasard

    Bonne lecture (:

  35. Aliong dit

    Salut
    Merci pour ce super tuto, par contre je rentre une erreur à la fin je ne sais pas pour qu’elle raison :
    —-> 5 print(scaler.inverse_transform(scaled_predicted_output_1).astype(int)[0])

    NameError: name ‘scaled_predicted_output_1’ is not defined

    aurais tu l’explication stp ? probleme de déclaration ?

    par avance merci
    bien à toi

  36. Jarod dit

    J’ai testé votre code, il est intéressant par contre, j’ai l’impression que c’est instable. Pour la meme prediction du 21 octobre 2020, j’ai un resultat totalement different du votre. De meme si on rejoue l’algorithme le resultat est encore different, et il est tres loin du resultat escompté. Parfois, il prédit même des valeurs au dessus de 49. je me suis retrouvé avec une valeur de 51. Je me pose la question, si il existe reellement un model predictif car les tirages sont censés etre des evenements aleatoires. J’ai essayé d’optmiser la window_size et nb_unit en utilisant les algo genetiques mais sans succes. Avez vous par exemple, essayer de jouer l’ago plusieurs fois sur un meme tirage ? Avez vous eu la meme prediction sur celui-ci?

  37. Wilfried dit

    Bonjour Jarod,

    En effet j’ai noté cette instabilité dans l’article en remarque et j’ai laissé la question ouverte à ce sujet. C’est l’un des gros problème du Machine Learning. Pour espérer avoir un modèle robuste qui donne les mêmes résultats après le réentrainement sur les mêmes donnés il faudrait effectuer une validation croisée.

    Le principe de la validation croisée consiste à diviser le dataset en plusieurs portions et utiliser de manière itérative chaque petite portion comme valeur de test et les grandes comme valeurs de train.
    Dans notre cas, supposer que les échantillons sont indépendants n’est pas adapté aux LSTM qui apprennent des valeurs historiques pour prédire l’avenir.
    Du coup cette instabilité existera toujours à moins de trouver un moyen efficace de rendre le modèle plus robuste.
    Il y a encore du travail pour espérer remporter le Jackpot un de ces jours. (:

  38. Alex dit

    Bonjour, merci pour cet article fort intéressant. Je pense que ça pourrait fonctionner sur des combinaisons générées de façon pseudo-aléatoire (tirage numérique)
    Mais malheureusement, la procédure de tirage du loto comporte des paramètres physiques qui rendent les combinaisons réellement aléatoires : les balles sont placées manuellement dans la sphère (donc agencées de manière aléatoire), la durée entre le début du brassage dans la sphère et le tirage d’un boule n’est pas toujours identique, etc.

  39. thierry dit

    bravo pour cet article, très intéressant et une façon très pratique pour comprendre l’IA

  40. Said dit

    J’ai testé votre code sur euromillion (apres adaptation), du coup apres avoir essayé plusieur méthodes (adam, rmsprop, et d’autres) et en essayant de jouer sur les données d’entré, j’ai pu avoir une accuracy de 97%, 98%,

    par exemple sur le tirage du vendredi passé ([49,12,50,10,37 || 8,3]) j’ai pu avoir les resultats suivants ; [10, 11, 36, 50, 49] [8 3] ce qui est tres tres proche.

    Ma question: Comment je fais pour qu’il puisse prédire les prochains tirage s’il vous plait? pas le dernier… Merci encore à vous pour votre travail

    1. thierry dit

      Bravo Said pour tes resultats, tes modifications sont elles diponible?
      merci

    2. Wilfried dit

      Bonjour Said,

      Le processus pour prédire les prochains tirages est le même que celui décrit dans l’article qui prédit uniquement le prochain tirage sur base des résultats précédents.

      D’après votre question, si vous voulez prédire les 3 tirages suivant au lieu d’un seul tirage, le plus simple serait de faire 3 prédictions successives dont la première prédiction se basera sur les vrais résultats, la seconde sur votre première prédiction et la dernière sur votre deuxième prédiction. Dans ce cas les résultats obtenu risques d’être moins pertinants car les deux tirages suivants seront sur base de prédictions et non des vrais résultats selon l’hypothèse de départ.

      Une deuxième approche plus complexe serait d’adapter l’entrainement du modèle aux nombre de sorties(tirages suivants) que vous voulez obtenir

      Bien à vous,

      1. Said dit

        Merci Wilfried pour vos explications, au fait sur votre code, il prédit le dernier tirage déja joué (pour tester ses prédictions)
        Mais ce que je veux c’est de prédire le PROCHAIN Future tirage, j’ai pas pu le faire :/ , j’ai ajouté une dernière ligne des zero mais ça n’a pas marché , j’ai essayé d’injecter le dernier tirage prédit dans la valeur “tom” pour faire la prédiction ça n’a pas marché

        Merci pour vos réponses. (je serai ravi de vous partager ce que j’ai fait)

        1. Wilfried dit

          Bonjour Said,
          Mon code de base prédit le prochain tirage et non le tirage déjà joué, si vous avez bien suivi les étapes du code vous devriez avoir le prochain tirage et non celui déjà joué comme vous le décrivez dans votre message.

    3. jona69 dit

      Bonjour Said

      Tes modifications sont-elles disponibles ? Je n’arrive pas à avoir une accuracy supérieur à 95%

    4. Deway dit

      Bonjour,
      Lorsque vous parlez de 98% d’accuracy, vous parlez de trouver au moins 1 chiffre correct ?https://ledatascientist.com/le-deep-learning-et-le-hasard-prediction-du-loto/#respond

  41. Laure dit

    Bonjour,
    Est-ce qu une âme charitable, pourrais expliquer pour les non initiés cimme moi comment utiliser le code de M. Wilfried , s’il vous plaît ?
    Quel logiciel utilisé ? Est-ce qu’un copier-coller du code suffit ? Faut il rattaché une base de données “genre un fichier excel des tirages précédent ? Si oui sur quelle ligne de code je fais le changement ?

    Je sais ça fait beaucoup de questions, et je vous remercie d’avance pour tout ceux qui prendront le temps d’y répondre.

    Encore bravo M. Wilfried pour votre travail 👏👏

    1. Said dit

      Bonjour Laure

      Vous pouvez utiliser “jupyter-notebook”, essayer de voir sur google comment l’installer et l’utiliser, une fois installer, installez les librairies qui viennent avec.
      vous avez rien a faire a part l’executer parce qu’il récupére la base de donnée automatiquement sur internet

      donc installer déja jupyter-notebook via ces commandes : https://janakiev.com/blog/jupyter-virtual-envs/

      apres installer les librairies manqantes dans votre environnement virtual que vous avez crée (à l’étape précédente) et apres vous lancer le code du Monsieur Wilfried

    2. Said dit

      Bonjour Laure,

      1 – Tu peux l’utiliser directement le code il est fonctionnel en installant ce logiciel “jupyter-notebook”, cella une procedure facile pour l’installer https://janakiev.com/blog/jupyter-virtual-envs/

      2 – Oui il vous suffit juste de faire un copier coller, le code est complet et il récupére la base de donnée automatiquement qui contient tout les autres tirages,

  42. Hugues dit

    Bonjour Wilfried,

    Un grand merci pour votre travail. Je fais un peu l’équivalent sous VB avec une dizaine de tests.

    J’ai une question: mon programme me donne un prochain tirage” possible” à partir de données comme celles que vous utilisez (nb pairs, nb dans une plage précédente, nb inférieur à x…etc), sauf que des combinaisons répondant à ces critères existent par milliers (sur 2 millions possibles).

    Comment votre programme détermine que c’est telle combinaison qui sera la suivante?

    Merci de votre réponse.

    Cordialement.

    1. wilfried dit

      Bonjour Hugues,

      La réponse à votre question réside dans le principe même du “Machine Learning”( Utilisé dans cet article) qui consiste à prédire un phénomène à partir d’observations passées grâce à des modèles(ce sont ces modèles mathématiques qui font le boulot).
      C’est ce que j’applique ici en entrainant un modèle qui à partir des statistiques sur les tirages passés estime un “prochain tirage possible”.

      Bien à vous,
      Wilfried.

  43. Hugues dit

    Bonjour et merci pour votre réponse.
    J’ai téléchargé python 3.8 ainsi que l’environnement tensor+keras dans Anaconda Navigator mais à chaque exécution de Jupyter note, il me dit que “keras” n’est pas trouvé (incompatibilité avec python 3.8 apparemment), quelqu’un aurait-il python 3.6? (lien ou envoi si possible svp)
    Merci et bonne journée à tous.
    Hugues

    ps: je peux vous communiquer (via mai)l quelques “tests” supplémentaires qui apparemment sont significatifs si vous le souhaitez. Je ne saurai les appliquer moi-même dans votre programme.

    1. Olivier dit

      Bonjour Hugues,

      Je penses que tu trouveras la version de python dont tu a besoin ici

    2. thierry dit

      Bonjour

      installe python 3.6 , puis dans un nouvel environnement dans anaconda , puis sur le menu de gauche dans anaconda navigator , tu peux installer les bibliothèques qui te manque

    3. Wilfried dit

      Bonjour Hugues,

      Une alternative à ces problèmes de compatibilité serait d’exécuter le code sur Google Colab où tous les packages nécessaires sont déjà installés avec du GPU à disposition qui accélère l’exécution.

      Pour vos tests, j’aimerais bien les voir, vous pouvez me les envoyer à l’adresse suivante: wilfriedkouadio3009@gmail.com

      Wilfried

  44. hugues dit

    Bonjour Olivier,

    Merci pour ce lien utile à tous.

    Ce matin, j’ai tenté avec anaconda 3.8.

    J’ai créé un environnement en downgradant vers 3.7 avec tensorflow 2.2.0 intégrant keras + bs4
    j’ai fait “INSTALL” dans le navigator sous cet environnement d’où je lance Jupyter notebook.

    Le notebook fonctionne bien jusqu’à l’entrée 14 avec l’erreur “notimplementederror” … là je sèche…

    Si quelqu’un a une solution…
    je mets une copie écran.
    https://www.cjoint.com/c/KDyltlf5eg1

    Ce sera intéressant pour ceux qui voudront ensuite installer sous anaconda 3.8….

    Bon we,

    Hugues

  45. jona69 dit

    Bonjour Wilfried,

    Merci pour votre code, le sujet est très intéressant. Je me demandais néanmoins s’il était possible de rajouter un test set pendant la phase de training. J’ai également tenté une version pour prédire les résultats de l’euro million, mais malgré une accuracy de 95%, je crains d’être en situation d’overfitting. Avez vous une idée pour ce type de problème ?

  46. jona69 dit

    Bonjour Wilfried,

    Merci pour cet article fort instructif. Jai essayé d’adapter votre code à une version EuroMillions mais malgré une accuracy de 95%, je n’ai pas l’impression que les prédictions obtenus soient correctes. Est-t-il possible d’ajouter un test set pendant l’apprentissage pour éviter ce problème d’overfitting ?

    Merci

    1. Said dit

      Bonjour Jona, J’ai pu adapté aussi le code pour pouvoir le faire marcher sur Euromillions, par contre je tombe toujours sur du overfitting,meme si je met la patience à 10, et Dropout à 0.5, je souhaite savoir comment avez vous fait pour le parametrage svp ? de mon coté, j’ai remit le num_features = 7 et j’ai essayé d’apprendre sur des longeurs de 18 (windows_length) vu qu’il y a que 1400 tirage. Merci d’avance

  47. Doc dit

    Jona69 Bonsoir, il vous suffit d’augmenter le dropout.

    1. jona69 dit

      Bonsoir Doc,

      Merci de votre réponse. J’ai testé votre proposition mais plus le dropout est élevé moins l’accuracy est bonne.
      Avec un dropout = 0 j’ai accuracy = 97.9% (mais j’obtiens à peine 2 bons numéros)
      Avec un dropout = 0.1 j’ai accuracy = 93%~94% (pareil j’ai au maximum 3 bons numéros)
      Avec un dropout = 0.8 j’ai accuracy = 77%

      1. wilfried dit

        Bonjour Jona69,

        Bravo pour l’exercice d’adaptation du modèle à l’Euromillions. Il y a là plusieurs paramètres à prendre en compte pour améliorer votre modèle notamment la complexité car dans l’Euromillion il y a 7 numéros à prédire contre 6 dans le Lotto. Vous pouvez donc tester de nouvelles métriques pertinentes pour cerner le deuxième numéro de chance.

        Avec un Dropout de 0 et une précision de 97.9 vous êtes clairement en overfitting. je vous conseille de faire un GridSearch de vos valeurs afin de trouver celles qui performent le mieux sans overfitting.

    2. Jona69 dit

      Merci de votre réponse Doc.
      J’ai essayé d’augmenter le dropout mais cela réduit l’accuracy (j’utilise dropout = 0.1)
      De plus lorsque je trace le graphique d’accuracy/epoch, la courbe est très instable et présente beaucoup d’oscillation

  48. Julia dit

    Bonjour,

    Je voudrais savoir à quoi ça sert la fonction “EarlyStopping” dans le code ? Est ce qu’il y a moyen de l’optimiser ou autre, car pour le moment le calcul s’arrête pour moi vers EPOCH entre 700 et 800 seulement, rarement au dessus, du coup j’obtiens un accuracy de 91 ou 92% et je n’ai quasiment jamais 1 ou 2 numéro de bon qui sort au tirage… Donc voila, comment faire pour au moins avoir 2 numéros bons, voir 3 minimum à chaque fois ? Que faut il que je modifie ?

    Merci

    1. Wilfried dit

      Bonjour Julia,
      EarlyStopping est une méthode qui permet de spécifier un grand nombre arbitraire d’EPOCH de formation et arrête la formation une fois que les performances du modèle cessent de s’améliorer. Dans votre cas le modèle cesse de s’améliorer entre 700 et 800 EPOCH.

      la réponse à votre deuxième question est tout simplement l’amélioration du modèle car comme spécifié dans l’article, les résultats de prédictions pour un même tirage varient a chaque nouvel apprentissage sur les même données ce qui le rend assez instable. ( Une personne peut donc lancer le modèle et avoir 1 à 3 numéros mais vous non). C’est l’un des grands défis du Machine Learning. Il faut donc encore beaucoup d’améliorations et réflexions pour approcher le Jackpot (:

  49. Deway dit

    Hello Said, could you share your work ?

  50. Said dit

    Bonjour Willfrid,

    Est ce que le fait qu’on a trié dés le debut les nombres pour chaque tirage n’influence t’il pas sur la prédiction? parce que le plus important dans le tirage c’est bien l’ordre d’apparition des boules ?

    Finalement mes résultats qui ont donnée 98% c’était du overfitting juste parce que les deux tirages étaient presque identiques, par contre pour contourner ça j’ai essayé d’augmenter le Dropout mais ça n’a pas donné de resultats non plus.

    Avez vous pensé à utiliser cette méthode développé par MIT: https://arxiv.org/abs/1803.03635 ?

    Cordialement.
    Merci enco

    1. wilfried dit

      Bonjour Said,
      Le fait que les numéros soient triés dès le départ influence effectivement le modèle puisque cela introduit une notion d’ordre que modèle apprend. Ce qui n’est pas le cas dans la réalité puisque les numéros tirés ne sont pas ordonnés de base. Malheureusement tous les sites qui recensent les résultats et que j’ai scrapé les trient dans l’ordre, ce qui m’a obligé à utiliser ces données ordonnés comme début pour mes tests . Je n’ai jusque là pas encore pu avoir les numéros dans le bon ordre de tirage pour réaliser de nouveaux tests.

      Avoir les numéros dans le vrai ordre de tirage pourrait effectivement améliorer le modèle en supprimant cette notion d’ordre même si l’objectif final est d’avoir tous les bon numéros .

      Pour l’article, merci pour le partage, je n’avais pas encore pensé à utiliser cette méthode.

      Cordialement,
      Wilfried

  51. Hugues dit

    Bonjour Wilfried,

    Hier soir, il y a eu un tirage “super loto”.

    Dans l’après-midi, j’ai voulu créer une base de “super loto” uniquement, pour lancer le programme.

    J’ai vu l’URL https…..dans le notebook, je voudrais savoir comment procéder pour modifier cette ligne du notebook (avec Word ?) pour changer l’adresse URL et comment créer une page avec un lien URL pour y mettre la base du super loto?

    Merci beaucoup et bon WE.

    Cordialement,
    Hugues

    PS: Comme vous, c’est le premier résultat du programme qui donne le meilleur pronostic (2 numéros souvent), si je relance le programme, même si le % de l’epoch est supérieur, le pronostic est plus mauvais…c’est bizarre non?
    Je pense aussi que certains tirages “atypiques” qui reviennent tous les 10 ou 15 tirages environ (de forme par ex 3 40 42 43 45 avec 4 quarantaines ou autres) “perturbent” l’apprentissage du programme, il faudrait peut-être les supprimer de la base et ne garder que la “normalité” ?

    1. Wilfried dit

      Bonjour Hugues,

      Vous pouvez modifier l’url et tout mon code directement dans le notebook. Si vous le faites ( modification url), la suite de mon code ne sera pas adapté à votre url, il faudra donc en fonction du html de votre nouvelle page adapter le code. Concernant “word” c’est juste un éditeur de texte ( pas de code)

      Etant donné que les donnés scrapées sur le site(url dans le notebook) contiennent à la fois les données du “super loto” et ceux des tirages en semaine, pour créer une base de super loto il faudra tout simplement écrire une condition (code python) sur les données scrapées pour récupérer les jours de tirage de “super loto” ( jours différents du lundi , mercredi et samedi), les stocker dans un DataFrame et ensuite réaliser les traitements que vous voulez. Par contre je crains que vous n’ayez pas assez de données sur le super loto (nombre de tirage) pour permettre un bon apprentissage .

      Concernant votre deuxième question, si vous parlez bien de créer une page web pour y stocker la base du super loto, il faudra faire du développement web , autrement vous pouvez tout simplement les stocker dans un CSV si c’est pour un usage en local.

      Pour le phénomène des tirages qui changent pour différents apprentissages, c’est un phénomène propre au Machine Learning. Je confirme également que mes meilleurs résultats proviennent toujours des premiers apprentissages
      Pour le dernier point, je pense qu’il faudrait des tests approfondis pour vérifier votre hypothèse.

      Cordialement,
      Wilfried

  52. hugues dit

    Bonsoir à tous,

    Voici la base de LOTO à partir de 2008 (1976 tirages) non ordonnée. (pour ceux qui voudraient tester)

    https://www.cjoint.com/c/KEwrYijPs20

    Cordialement
    Hugues

  53. Said dit

    Bonjour Wilfried,

    Effectivement, j’avais du mal à trouver des sites qui proposent le vrai ordre de tirages, j’ai du les collecter manuellement depuis des fichiers CSV, voici le fichier qui contient le tirage avec le bon ordre, je vous le partage : https://drive.google.com/file/d/1hlERJ48Lrs5lu6cZMDX11eulIR6gkQ_a/view?usp=sharing

    Cependant, même avec celui la, je tombe sur du Overfitting, je vous laisse voir si ça améliore le modele, je vous prie de me tenir au courant sur mon mail : saidamirouche1@gmail.com

    Cordialement.
    Said

  54. Wilfried dit

    Bonsoir Hugues et Said,

    Merci pour ces partages. Dans un soucis d’automatisation des traitements ,si jamais vous trouvez des sites qui collectent les numéros dans le bon ordre, je serai preneur.

    Cdt,
    Wilfried

  55. Arnaud dit

    Bonjour,

    j’ai déjà posté un message sur ce fil la semaine dernière mais je ne le vois pas apparaitre (peut être parce que j’avais l’adresse de mon site internet).
    J’ai mis en place un script qui met à jour un fichier CSV disponible depuis mon site internet et qui contient tous les tirages du loto dans l’ordre de sortie des boules.

    Si vous êtes intéressés mon email : glubok arobase hotmail point fr

  56. Steph dit

    Bonjour Wielfried,
    je me demandais comment remplacer le lien vers le site par un fichier CVS contenant les mêmes colonnes.
    De ce que je comprends Beautifulsoup parse une page web. Comment puis-je parser mon fichier ?

    Merci de votre guidance.

  57. Steph dit

    Bonjour Wilfried,

    je cherche à faire la même chose que cette fonction

    #fonction de scraping des tirages du loto
    def scrap_loto_numbers():
    my_list=[]
    time.sleep(2)
    loto_url = “http://loto.akroweb.fr/loto-historique-tirages/”
    page = requests.get(loto_url)
    soup = BeautifulSoup(page.text, ‘html.parser’)
    body = soup.find(‘table’)
    tirage_line = body.find_all(‘tr’)
    for value in tirage_line:
    my_dict = {}
    res = value.text.split(‘\n’)
    my_dict[‘day’]=res[2]
    my_dict[‘month_year’]=res[3]

    for i,val in enumerate(res[5:10]):
    my_dict[‘num’+str(i)]=int(val)
    my_dict[‘chance’]=int(res[10])
    my_list.append(my_dict)

    df=pd.DataFrame(my_list)
    return df

    mais à partir d’un fichier CSV
    J’arrive à lire le fichier CSV mais comment ajouter les lignes du fichier au dataframe.
    Je ne suis pas expert du tout en python

    Merci de votre aide.

    Stephane

    1. thierry dit

      Bonjour

      moi aussi je cherche a faire la même chose a partir d un fichier csv, mais sans succès , je suis preneur de la solution.
      merci
      cordialement

  58. Hugues dit

    Bonjour à tous,
    Je ne comprends pas bien en quoi le fait que les numéros soient ordonnés ou non change la prédiction? Il y aura toujours le même nombre de N° pairs, < à 24 etc… dans le tirage, ordonné ou pas. Ce n'est pas le quinté.
    Merci de m'expliquer cette différence d'apprentissage, si vous avez un moment.
    Bonne journée.
    Hugues

  59. Arnaud dit

    df = pd.read_csv(‘monFichier.csv’)

  60. Airday dit

    import csv

    header = []
    game_info = []
    max_chance = 139838160

    def addLineFromCSVBefore2019(filename):
    with open(filename, ‘r’) as csvfile:
    csvreader = csv.reader(csvfile, delimiter=’;’)
    header = next(csvreader)
    rest = csvreader
    for row in rest:
    line = {}
    line[‘annee_numero_de_tirage’] = row[0]
    line[‘jour_de_tirage’] = row[1].strip()
    line[‘date_de_tirage’] = row[2]
    line[‘boule_1’] = row[4]
    line[‘boule_2’] = row[5]
    line[‘boule_3’] = row[6]
    line[‘boule_4’] = row[7]
    line[‘boule_5’] = row[8]
    line[‘etoile_1’] = row[9]
    line[‘etoile_2’] = row[10]
    game_info.append(line)

    def addLineFromCSVAfter2019(filename):
    with open(filename, ‘r’) as csvfile:
    csvreader = csv.reader(csvfile, delimiter=’;’)
    header = next(csvreader)
    rest = csvreader
    for row in rest:
    line = []
    line = {}
    line[‘annee_numero_de_tirage’] = row[0]
    line[‘jour_de_tirage’] = row[1].strip()
    line[‘date_de_tirage’] = row[2]
    line[‘boule_1’] = row[5]
    line[‘boule_2’] = row[6]
    line[‘boule_3’] = row[7]
    line[‘boule_4’] = row[8]
    line[‘boule_5’] = row[9]
    line[‘etoile_1’] = row[10]
    line[‘etoile_2’] = row[11]
    game_info.append(line)

    addLineFromCSVBefore2019(‘euromillions.csv’)
    addLineFromCSVBefore2019(‘euromillions_2.csv’)
    addLineFromCSVBefore2019(‘euromillions_3.csv’)
    addLineFromCSVBefore2019(‘euromillions_4.csv’)
    addLineFromCSVAfter2019(‘euromillions_201902.csv’)
    addLineFromCSVAfter2019(‘euromillions_202002.csv’)

    print(game_info)

  61. Faissoil dit

    Salut à toi Jeune Padawan.

    Bravo pour ton précieux travail.

    Serait-il possible de upgrader ton travail en l’adaptant pour Euro Millions sachant que ce site met en ligne l’historique des tirages Euro Millions.

    https://www.loto-euromillions.net/euromillions/resultat-euromillions-historique.php

    Par avance Merci pour ton retour.

  62. Faissoil dit

    Bonjour Airday,
    Il est tout à fait possible de mettre tous les archives des tirages euromillions dans un seul fichier csv.
    Cordialement,

  63. Faissoil dit

    Bonjour,

    Est-que quelqu’un voudrait bien m’envoyer le code adapté pour l’Euro-Millions? SVP!

    faissoil1@me.com

    Merci

  64. Faissoil dit

    Pour faire des prévisions exactes de l’Euro-Millions,
    Il faut tenir compte des grilles jouées par tirages. Sachant qu’au tirage de Mardi, il y a 16 millions ou plus de grilles jouées et le Vendredi 25 millions de grilles jouées ou plus, selon le montant du jackpot en jeu.

    Les tirages de l’Euro-Millions se font selon les grilles jouées. Dans le nombre de grilles jouées, il y a disparité des numéros de 1 à 50.
    Il suffit de faire une simulation de 16 millions de grilles (Mardi) et à l’aide des statistiques (python) rechercher la combinaison à deux numéros (soit 1225 combinaisons (comb(50;2))) qui a été jouée 1 216 000 fois (76/1000 x 16 000 000) dans les 16 000 000 de grilles simulées.
    Par la suite, regarder dans les 1 216 000 grilles, la seule combinaison à 5 numéros peu jouée

  65. Ma bolton dit

    bonjour
    Merci pour cet article et pour le notebook. Je suis un peu novice mais effectue un projet dans ce domaine.
    J ai une erreur dans le notebook au niveau du training : train,label,model,scaler1 = create_lstm_dataset(df, window_length,nb_label_feature)
    Faut il télécharger quelque chose de special ?
    Merci

  66. Laurent dit

    Bonsoir Wilfried.
    Merci beaucoup pour votre article très explicite et très détaillé.
    J’ai récupéré le code et j’ai fait quelques tests avec.
    Je me pose une question afin d’approcher au plus près des vrais résultats : est-ce qu’il ne serait pas possible de prendre en compte les différences entre les prédictions et les vrais résultats pour chaque tirage et intégrer cette différence pour la prédiction suivante ?
    Par exemple : on travaille sur les 12 derniers tirages. On fait une prédiction sur les 3 premiers de la liste et on compare le résultat de la prédiction avec le 4ème vrai tirage. on “insère” cette différence (c’est là que je ne sais pas comment faire) pour que la prédiction sur le 5ème tirage puisse prendre en compte cette différence, etc …
    ceci afin de faire un “recalibrage” afin de s’approcher au plus près des vrais résultats ?

    Merci pour votre réponse.
    Cordialement.
    Laurent

  67. eyefighter dit

    bonjour,
    merci pour le code, je m’amuse avec le code.
    au début je voulais re programmer une IA sur Excel, mais après 4 jour de recherche, j’ai n’est toujours pas compris comme en programmer une (et je ne pence pas le comprendre ne 1 mois de recherche)
    j’ai essayé d’ajouter la racine carré de la somme des nombre au carre, mais je n’obtiens pas de mayeur résulta.

    la fonction à ajouter pour les curieux :
    def carre_racine(data):
    return ((data[‘num0’]**2 + data[‘num1’]**2 +
    data[‘num2’]**2 + data[‘num3’]**2 +
    data[‘num4’]**2)**0.5)

    puis : df[‘carre_racine’] = carre_racine(df)

  68. Hugues dit

    Bonjour à tous,

    Quelqu’un pourrait il me dire comment modifier le scraping vers l’URL pour mettre à la place un fichier Excel (xls) sur mon disque C (à la racine)?

    Le fichier comprend 8 colonnes remplies de A à H sous la forme:
    MERCREDI 25/08/2021 19 9 29 26 3 8

    il y a environ 500 lignes de tirages.

    et où et comment le remplacer dans le code existant de Wilfried.

    Merci et bon WE à tous.

  69. Vincent dit

    Bonjour,
    il est mentionné à plusieurs endroits que les prédictions pour un même tirage seront différentes d’un apprentissage à un autre. Vous mentionnez également que les prédictions sont souvent assez proches des vrais résultats à plus ou moins 1. Ne serait-il pas alors possible de faire un très grand nombre d’apprentissages et ainsi de calculer un intervalle de confiance autour de chaque numéro prédit. Certains numéros auront peut-être un très petit intervalle de confiance (inférieure à 1 et qu’il faudra donc jouer) tandis que d’autres auront un intervalle de confiance un peu plus grand mais pas trop (on l’espère) pour englober que quelques valeurs. Ainsi, le nombre de combinaisons avec une très forte probabilité de gagner sera peut-être réduit à quelques combinaisons (ou quelques dizaines).
    Ceci est une remarque de béotien donc n’hésitez pas à me dire si je me plante complètement !
    Merci et bonne journée

Laisser un commentaire

Votre adresse email ne sera pas publiée.

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.

Voulez-vous en savoir plus sur la Data Science ?

Inscrivez-vous alors à notre newsletter et vous receverez gratuitement nos derniers articles et actualités ! 
S'INSCRIRE MAINTENANT 
close-link