Python >> Tutoriel Python >  >> Python

Module aléatoire de Python - Tout ce que vous devez savoir pour commencer

La vie est imprévisible. Parfois, de bonnes choses arrivent à l'improviste, comme si vous trouviez 100 $ par terre. Et parfois, de mauvaises choses arrivent, comme l'annulation de votre vol à cause du mauvais temps.

La plupart des langages de programmation ont un module pour gérer le hasard. Python ne fait pas exception avec le module nommé random et dans cet article, nous examinerons les fonctions les plus essentielles dont vous avez besoin pour l'utiliser.

Les bases absolues

Avant d'utiliser une fonction du module random, nous devons l'importer.

import random

Parce que nous avons affaire à un programme informatique, les nombres aléatoires ne sont pas aléatoires à 100 %. Au lieu de cela, le module crée des nombres pseudo-aléatoires à l'aide d'une fonction de générateur.

La fonction de générateur de base utilisée par Python s'appelle le Mersenne Twister. C'est l'un des générateurs de nombres aléatoires les plus testés au monde. Cependant, les nombres aléatoires sont prédéterminés. Si quelqu'un voit 624 itérations d'affilée, il peut prédire, avec une précision de 100 %, quels seront les prochains chiffres. C'est aussi une séquence répétitive. Heureusement, il faut un certain temps pour se répéter. Vous devez passer par 2**19937 – 1 numéros (un nombre premier de Mersenne, d'où le nom) avant d'atteindre à nouveau le début de la séquence.

Par conséquent, vous ne devez PAS utiliser le module random pour tout ce qui concerne la sécurité, comme la définition de mots de passe. Utilisez plutôt le module secrets de Python.

Il est utile que random ne crée pas de nombres 100% aléatoires car cela nous permet de reproduire nos résultats ! C'est extrêmement important pour ceux qui travaillent dans la science des données.

Mais comment s'assurer de pouvoir reproduire nos résultats ? Nous devons d'abord planter une graine.

random.seed()

Au début de tout travail impliquant le hasard, il est recommandé de définir une « graine ». Cela peut être considéré comme le « point de départ » de notre séquence aléatoire. Pour ce faire, nous entrons n'importe quel float ou int dans random.seed() .

Définissons la graine sur 1.

import random
random.seed(1)

Nous allons maintenant générer des nombres aléatoires dans la plage [0.0, 1.0) en appelant le random.random() fonctionner quelques fois. Si vous faites de même, vous verrez que vos numéros sont identiques aux miens !

>>> random.random()
0.13436424411240122

>>> random.random()
0.8474337369372327

>>> random.random()
0.763774618976614

Si nous réinitialisons la graine et appelons random.random() encore une fois, nous obtiendrons les mêmes chiffres.

>>> random.seed(1)
>>> seed_1 = [random.random() for i in range(3)]
>>> seed_1
[0.13436424411240122, 0.8474337369372327, 0.763774618976614]

J'ai utilisé une compréhension de liste pour une meilleure lisibilité mais vous pouvez la saisir manuellement si vous préférez.

Nous pouvons maintenant générer des nombres aléatoires. Mais à quoi cela ressemblerait-il si nous en générions des centaines de milliers et les traçions ? De tels tracés sont appelés distributions.

Répartition

Si nous lançons un dé, tous les nombres de 1 à 6 ont la même probabilité. Ils ont tous une probabilité de 1/6. On dit que ces probabilités sont uniformément distribuées. Pour vous en souvenir, rappelez-vous qu'un groupe de personnes portant des uniformes se ressemblent toutes.

Si nous lançons deux dés et additionnons leurs résultats, les résultats ne sont pas uniformément distribués. La probabilité d'obtenir 2 et 12 est de 1/36 mais 7 a une probabilité de 1/6. Que se passe-t-il? Tout n'est pas uniformément réparti.

Pour comprendre ce qui se passe, lançons un dé 100 000 fois et deux dés 100 000 fois, puis traçons les résultats. Nous utiliserons le random.choice() fonction pour nous aider. Il prend n'importe quelle séquence et renvoie un élément choisi au hasard - en supposant une distribution uniforme.

Remarque :J'appelle sns.set() au début pour utiliser les paramètres par défaut de Seaborn car ils ont l'air beaucoup plus agréables que matplotlib.

Lancer un dé 100 000 fois

import matplotlib.pyplot as plt
import seaborn as sns

sns.set()

# Create our data
outcomes = [1, 2, 3, 4, 5, 6]
one_dice = [random.choice(outcomes) for i in range(100000)]

# Plot our data
plt.hist(one_dice, bins=np.arange(1, 8), density=True)
plt.show()

Voici un exemple parfait de distribution uniforme. Nous savons que 1/6 =0,1666 et chaque barre est à peu près à cette hauteur.

Expliquer le code

Nous utilisons des compréhensions de liste pour générer 100 000 valeurs. Puis tracez-le en utilisant plt.hist() . Définir density=True pour s'assurer que l'axe des y montre des probabilités plutôt que des comptes. Enfin, définissez bin=np.arange(1, 8) pour créer 6 bacs de largeur 1. Chaque bac est à moitié ouvert – [1, 2) inclut 1 mais pas 2. Le bac final est fermé – [6, 7] – mais comme 7 n'est pas un résultat possible, cela n'a pas d'impact nos résultats. Nous pouvons définir les bacs sur un nombre entier, mais cela crée un graphique plus difficile à interpréter, comme vous pouvez le voir ci-dessous.

Chaque barre a une largeur ~ 0,8 et une probabilité de 0,2, ce que nous n'attendions ni ne voulions. Ainsi, il est toujours préférable de définir manuellement les bacs en utilisant np.arange() . Si vous rencontrez des difficultés avec NumPy range , consultez le tutoriel complet de la fonction d'arrangement de NumPy sur notre blog !

Le module aléatoire contient la fonction random.uniform(a, b) qui renvoie des flottants choisis au hasard dans l'intervalle [a, b] . Si vous dessinez 100 000 nombres et tracez les résultats, vous verrez un tracé similaire à ceux ci-dessus.

Lancer deux dés 100 000 fois

Le code est presque identique au premier exemple.

outcomes = [1, 2, 3, 4, 5, 6]
two_dice = [random.choice(outcomes) + random.choice(outcomes)
           for i in range(100000)]
plt.hist(two_dice, bins=np.arange(2, 14), density=True)
plt.show()

La forme est très différente de notre premier exemple et illustre ce que nous attendions. Les nombres 2 et 12 ont une probabilité de 1/36 =0,0277 et 7 est de 1/6 =1,666. La forme peut vous rappeler l'une des distributions les plus célèbres au monde :la distribution normale .

Dans la distribution normale, les valeurs proches du centre sont beaucoup plus susceptibles de se produire que celles situées aux extrémités. Vous verrez cette distribution plusieurs fois tout au long de votre carrière car elle peut être utilisée pour modéliser d'innombrables événements aléatoires, par ex. taille, poids et QI.

Il existe de nombreuses distributions différentes et tout bon manuel de statistiques les explique en détail. Consultez la liste des 101 livres Python gratuits sur le blog Finxter et téléchargez simplement celui de votre choix.

Le module random a des fonctions qui tirent des valeurs des plus courantes. Nous ne couvrirons ici que la distribution normale par souci de brièveté.

Étant donné que la distribution normale est également appelée distribution gaussienne, random a deux fonctions pour générer des échantillons :random.gauss() et random.normalvariate() . Les deux prennent deux paramètres, mu et sigma – la moyenne et la variance de la distribution respectivement. Pour plus d'informations, consultez la page Wikipedia.

Nous tracerons les deux graphiques sur les mêmes axes en utilisant le code suivant.

normal = [random.normalvariate(7.5, 2.35) for i in range(100000)]
plt.hist(two_dice, bins=np.arange(2, 14), density=True, 
        alpha=0.7, label='Dice Data')
sns.distplot(normal, hist=False, color='r', label='Normal Approx.')
plt.legend()
plt.show()

L'approximation normale avec mu=7.5 et sigma=2.35 est une très bonne approximation du lancer de deux dés. Je les ai trouvés après avoir essayé quelques valeurs aléatoires. Nous l'appelons 100 000 fois en utilisant la compréhension de liste et le tracé en utilisant sns.distplot paramètre hist=False pour montrer juste l'approximation.

Ceci est très utile notamment dans le domaine de la science des données. Si nous pouvons approximer nos données à l'aide de distributions bien connues et bien documentées, nous en savons instantanément beaucoup sur nos données.

Il existe toute une branche de la statistique dédiée à l'approximation des données à des distributions connues. Il peut être dangereux de trop déduire d'un petit échantillon de données. La méthode que nous avons utilisée ci-dessus n'est pas statistiquement valable mais constitue un bon point de départ.
Notez que la distribution normale n'a pas de sélection finie de valeurs, ni de limite supérieure ou inférieure. C'est peu probable mais random.normalvariate(7.5, 2.35) peut générer des nombres <2 et> 12. Ainsi, il n'est utile que comme approximation et non comme remplacement.

Trois idées pour utiliser le module aléatoire

C'était une visite éclair du module aléatoire et maintenant vous avez tout ce dont vous avez besoin pour commencer à l'utiliser.
Étant donné que la meilleure façon d'apprendre est par le biais de projets, voici quelques idées à essayer :

  • Lors du scraping Web, utilisez time.sleep() combiné avec random.uniform() attendre un laps de temps aléatoire entre les requêtes.
  • Créez un jeu "devinez le nombre". L'ordinateur choisit un nombre aléatoire entre 1 et 10 - en utilisant random.choice() – et vous devinez des nombres différents avec le input() commande. Consultez ce livre pour plus d'idées.
  • Créez une liste de numéros de téléphone et de noms de vos proches. Créez une autre liste de messages d'amour. Utilisez Twilio pour envoyer chaque jour un message d'amour aléatoire à une personne choisie au hasard.

Bonne chance et que le hasard soit avec vous !

Attribution

Cet article est une contribution de l'utilisateur Finxter Adam Murphy (scientifique des données, grand maître du code Python) :

Je suis un programmeur autodidacte avec un diplôme de première classe en mathématiques de l'Université de Durham et je code depuis juin 2019.

Je connais bien les principes de base du web scraping et de la science des données et je peux vous fournir très rapidement une grande variété d'informations sur le Web.

J'ai récemment récupéré des informations sur toutes les montres que Breitling et Rolex vendent en seulement 48 heures et je suis convaincu que je peux vous fournir des ensembles de données de qualité similaire, quels que soient vos besoins.

Étant de langue maternelle anglaise, mes compétences en communication sont excellentes et je suis disponible pour répondre à toutes vos questions et fournirai des mises à jour régulières sur l'avancement de mon travail.

Si vous souhaitez embaucher Adam, consultez son profil Upwork !