IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Influencer un nombre aléatoire


Sujet :

Python

  1. #1
    Membre habitué Avatar de memento80
    Homme Profil pro
    Boulot : ne rentre pas dans une case
    Inscrit en
    Novembre 2004
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Boulot : ne rentre pas dans une case
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2004
    Messages : 163
    Points : 125
    Points
    125
    Par défaut Influencer un nombre aléatoire
    Bonjour à tous,

    Je débute en Python... Jusqu'ici j'ai réussi à me débrouiller mais là, je bute sur un petit problème.
    Mon soucis serait peut-être plus proche d'un problème de math que du Python mais bon... peut-être que Python a une solution miracle.

    Voilà, j'essaye juste de générer des nombres aléatoires entre 0 et 100... mais je voudrais qu'il y ait plus de probabilité qu'il soit proche de 100 que de 0.

    Si quelqu'un peut calmer ma migraine, je lui en serais reconnaissant.

    A+
    Memento

  2. #2
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2010
    Messages
    140
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2010
    Messages : 140
    Points : 182
    Points
    182
    Par défaut Proba pondérée
    Bonjour, bienvenue dans python.

    Peut être qu'une solution toute faite existe, mais moi je vais te proposer un truc hancrafted.

    tu peux tenter de dire que la proba de tirer un nombre entre 0.5 et 1 est supérieure sur une probabilité définie disons à 70% de chances d'avoir un nombre de cette categorie. ce qui nous donne un truc tel que:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    import random
     
    #on définit une valeur aléatoire
    r = random.random()
     
    #on a 70%de chances que ce soit un nombre entre 0.5 et 1
    if random.random() > 0.3:
      while r < 0.5:
        r = random.random()
    else:
      while r > 0.5:
        r = random.random()
     
    #le reste du temps on cherche à générer un nombre compris entre 0 et 0.5.
    Voila, Bisou

  3. #3
    Membre averti Avatar de alexdevl
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    265
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Avril 2007
    Messages : 265
    Points : 344
    Points
    344
    Par défaut par r^2
    Bonjour,

    Moi je ferais une fonction sur r qui transforme la répartition entre 0 et 1 exemple r^2.
    (car il faut, sur la fonction, que pour x=0=>y=0, x=1=>y=1 et y toujours <1 sur la fonction)
    Tu peux même calculer la probabilité par zone en intégrant la surface d'une zone.

    Alex

  4. #4
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Points : 970
    Points
    970
    Par défaut
    salut,

    un petit lien vaut mieux qu'un long discours. je vais dans le sens d'alexdevl:

    http://fr.wikipedia.org/wiki/Fonctio...C3%A9partition

    regarde plus particulièrement le chapitre 4 c'est ce dont tu as besoin.

    en résumé:

    - tu définis ta fonction de répartition
    - tu définis la fonction réciproque
    - tu génères un nombre entre 0 et 1 que tu donnes à manger à ta fonction réciproque et tu obtiendra un "tirage" qui correspond à ta fonction de répartition.

  5. #5
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Bonjour.

    Citation Envoyé par memento80 Voir le message
    Voilà, j'essaye juste de générer des nombres aléatoires entre 0 et 100... mais je voudrais qu'il y ait plus de probabilité qu'il soit proche de 100 que de 0.
    Mathématiquement parlant, cela n'a pas de sens. D'un point de vue pratique peut-être... Il faudrait nous dire dans quel cadre tu as besoin de nombres aléatoires plus "proches" de 100 que de 0.

  6. #6
    Membre éprouvé
    Inscrit en
    Août 2010
    Messages
    1 124
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 1 124
    Points : 1 277
    Points
    1 277
    Par défaut
    Soit tu as en tete une fonction de repartition précise, dans ce cas suis la réponse de Kango. Sois n'importe quelle distribution pas trop dégénérée te convient, dans ce cas la piste de alexdevl semble la bonne. Par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    n= int(100*random.rand()**2)
    correspond à la distribution image par x|-> x^2 de l'uniforme

  7. #7
    Membre habitué Avatar de memento80
    Homme Profil pro
    Boulot : ne rentre pas dans une case
    Inscrit en
    Novembre 2004
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Boulot : ne rentre pas dans une case
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2004
    Messages : 163
    Points : 125
    Points
    125
    Par défaut
    Merci déjà pour vos premières réponses ou remarques.

    Je suis au boulot donc je ne peux approfondir ou tester cela pour le moment, j'essaierai dès ce soir et vous tiendrai au courant.

    Par contre juste pour répondre à rambc, plutôt que d'expliquer mon besoin précis (ça serait un petit peu long à expliquer), je vais prendre un autre exemple un peu plus simple que j'ai trouvé par hasard dans le magazine Ordinateur Individuel de ce mois (oui, une coïncidence).
    Leur réponse, sous la forme d'un calcul Excel, pourrait correspondre à mon besoin mais dans un contexte différent. Mais la précision du résultat, après quelques premiers tests, était encore un peu éloigné de la précision que je cherchais (en plus, c'est sous Excel... même si on pourrait transposer le principe).

    Bref, l'exemple du besoin en question était celui-ci :
    On veut simuler une liste de valeur sensée représenter les notes d'une classe de "bons élèves". Du coup, les notes sur 20 devaient être plus proches de 20 que de 0.
    On pourrait imaginer l'inverse avec une classe de "mauvais élèves".

    Voilà pour un exemple d'utilisation de l'influence sur un nombre aléatoire.
    Donc, pour moi, le besoin est le même... mais sur 100.

  8. #8
    Membre éprouvé
    Inscrit en
    Août 2010
    Messages
    1 124
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 1 124
    Points : 1 277
    Points
    1 277
    Par défaut
    influence sur un nombre aléatoire
    Simple remarque de vocabulaire: le nom usuel est plutôt Loi/Distribution/Repartition non uniforme, la notion d'influence etant liée à l'impact d'une variable aléatoire sur une autre

  9. #9
    Membre averti Avatar de alexdevl
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    265
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Avril 2007
    Messages : 265
    Points : 344
    Points
    344
    Par défaut
    Bonjour,

    J'ai fait un peu de code pour voir, il faut plutôt 1-r^2 en fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
    import random
     
    print "r"
    plages={}
    for i in range(10):
        plages[i]=(0,0)
    nValeurs=0
    for i in range (10000):
        r=random.random()
     
        plage = int(r*10)
        nValeurs+=1
        nPlage=plages[plage][0]+1
        pourcent=int(10000.0*nPlage/nValeurs)/100.0
        plages[plage]=(nPlage,pourcent)
    for i in plages:
        print "plage 0."+str(i),plages[i][0],"valeurs   ",plages[i][1],"%"
    print"-----"
     
    print "1-r^2"
    plages={}
    for i in range(10):
        plages[i]=(0,0)
    nValeurs=0
    for i in range (10000):
        r=random.random()
        r=(1-r*r)
        plage = int(r*10)
        nValeurs+=1
        nPlage=plages[plage][0]+1
        pourcent=int(10000.0*nPlage/nValeurs)/100.0
        plages[plage]=(nPlage,pourcent)
    for i in plages:
        print "plage 0."+str(i),plages[i][0],"valeurs   ",plages[i][1],"%"
    Et cela fait la sortie suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    r
    plage 0.0 996 valeurs    9.96 %
    plage 0.1 991 valeurs    9.92 %
    plage 0.2 1015 valeurs    10.17 %
    plage 0.3 960 valeurs    9.6 %
    plage 0.4 980 valeurs    9.8 %
    plage 0.5 1010 valeurs    10.11 %
    plage 0.6 993 valeurs    9.94 %
    plage 0.7 1003 valeurs    10.04 %
    plage 0.8 1028 valeurs    10.28 %
    plage 0.9 1024 valeurs    10.24 %
    -----
    1-r^2
    plage 0.0 527 valeurs    5.28 %
    plage 0.1 507 valeurs    5.07 %
    plage 0.2 569 valeurs    5.7 %
    plage 0.3 648 valeurs    6.48 %
    plage 0.4 638 valeurs    6.38 %
    plage 0.5 737 valeurs    7.37 %
    plage 0.6 821 valeurs    8.21 %
    plage 0.7 1043 valeurs    10.43 %
    plage 0.8 1293 valeurs    12.93 %
    plage 0.9 3217 valeurs    32.17 %

  10. #10
    Membre éprouvé
    Inscrit en
    Août 2010
    Messages
    1 124
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 1 124
    Points : 1 277
    Points
    1 277
    Par défaut Exact
    oui pardon, le carré va concentrer la répartition sur 0.
    Le fonction racine convient aussi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    n= int(100*math.sqrt(random.rand()))

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 9
    Points : 12
    Points
    12
    Par défaut
    Salut

    je m etais penché sur le meme probleme que toi
    c etait pour une sorte de jeux de role, ou je voulais un random modifié (par ex les items genérés devaient avoir + de chance d'etre du niveau du joueur, sans toutefois générer des valeurs aberrante trop nombreuses, genre etre lvl 20 et trouver des objets lvl 120 ou au contraire 4)

    j ai trouvé la fonction de distribution beta :
    voir l animation vers le milieu de la page qui represente simplement l'effet
    http://www.aiaccess.net/French/Gloss...eta_distri.htm

    en mettant alpha= 4, et beta = 1.25 tu as ~80% des valeurs random dans une fourchette entre 70%et 100% de l'echantillon (c pas clair mais sur le grahique c est tres simple), et un point maximum a 0.92 (%)
    Dans ce meme cas, il est toujours possible d avoir un random entre 1 et 50 mais une chance tres faible.

    Dans python, il y a l equivalent dans la partie .random
    http://docs.python.org/library/random.html

    voir random.betavariate(alpha, beta) au lieu du .random tout bete

  12. #12
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Il ne faut pas oublier les autres distributions proposées par Python. Pour des notes d'élèves, il me semble plus réaliste que cela suive une loi normale.
    Par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    import random
     
    def draw_distr(l, steps=10):
        dmin = min(l)
        dmax = max(l)
        drange = dmax -dmin
        for i in xrange(steps):
            lmin = dmin + drange*i/steps
            lmax = dmin + drange*(i+1)/steps
            cnt = len([1 for e in l if lmin <= e < lmax])
            print "[%.2f,%.2f[ --> %.2f%%" % (lmin, lmax, cnt*100.0/len(l))
     
    def clamp(x, xmin, xmax):
        return min(max(x,xmin),xmax)
     
    # exemple: moyenne 80, écart-type 12
    draw_distr([clamp(random.gauss(80,12),0,100) for _ in xrange(1000)])
    Résultat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [38.35,44.51[ --> 0.20%
    [44.51,50.68[ --> 0.30%
    [50.68,56.84[ --> 2.10%
    [56.84,63.01[ --> 4.50%
    [63.01,69.17[ --> 11.90%
    [69.17,75.34[ --> 17.30%
    [75.34,81.50[ --> 20.40%
    [81.50,87.67[ --> 17.40%
    [87.67,93.83[ --> 14.10%
    [93.83,100.00[ --> 7.60%
    Si cela ne convient pas, Python a d'autres distributions sous le coude. Une distribution Gamma pourrait convenir aussi...

  13. #13
    Membre éprouvé
    Inscrit en
    Août 2010
    Messages
    1 124
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 1 124
    Points : 1 277
    Points
    1 277
    Par défaut
    Pour des notes d'élèves, il me semble plus réaliste que cela suive une loi normale
    Il faut le dire vite quand meme : la loi normale charge TOUJOURS tous les réels (négatifsou aussi grand qu'on veut...pas génial pour des notes!)

  14. #14
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Citation Envoyé par VV33D Voir le message
    Il faut le dire vite quand meme : la loi normale charge TOUJOURS tous les réels (négatifsou aussi grand qu'on veut...pas génial pour des notes!)
    Bah c'est pour ça que j'ai clampé à [0,100]. C'est une bonne approximation quand-même...
    En tout cas ça me semble plus réaliste que de faire que la note la plus représentée soit la note maximale.

  15. #15
    Membre habitué Avatar de memento80
    Homme Profil pro
    Boulot : ne rentre pas dans une case
    Inscrit en
    Novembre 2004
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Boulot : ne rentre pas dans une case
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2004
    Messages : 163
    Points : 125
    Points
    125
    Par défaut


    Ma seule certitude pour l'instant en lisant tout ceci est que vous me semblez être assez calé en math. Bravo ! C'est loin d'être mon cas....
    J'aurais du suivre un peu plus les cours il y a une quinzaine d'années.

    A première vue, sans avoir encore trop approfondi les réponses, mais après quelques tests, il semblerait que la solution de Patatarte avec le random.betavariate se rapproche le plus de ce que je voudrais obtenir (même si, je l'avoue, je n'ai pas tout saisi aux différentes définitions "gamma", "béta", "réciproque" et Cie).

    Par contre, je ne suis pas à une question bête prêt : la solution de axeldvel n'équivaut pas justement à "simuler" le random.betavariate ? Non ? C'est quoi la différence ? Il y a une nuance qui m'échappe ?

    Il ne faut pas oublier les autres distributions proposées par Python. Pour des notes d'élèves, il me semble plus réaliste que cela suive une loi normale.
    Je suis d'accord avec toi dividee, ce n'est peut-être pas la bonne solution pour simuler de façon réaliste, des notes de (bons) élèves. Mais bon, c'était pour donner un exemple.

    Pour ce qui est de la solution de Kango, je sens qu'il y a quelque chose à creuser dans l'idée..... mais je ne vois pas vraiment comment l'exploiter.

  16. #16
    Membre éprouvé
    Inscrit en
    Août 2010
    Messages
    1 124
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 1 124
    Points : 1 277
    Points
    1 277
    Par défaut
    * Kango te propose de générer des variables de n'importe quelle loi (spécifiée par sa fonction de repartition)

    * gamma, beta, reciproque sont des familles de lois de probabilités (tu trouve facilement leur déf sur wiki, en particulier leur fonction de repartition)

    * la solution de axeldev part de variables uniformes et applique une transformation. Je ne pense pas que la transformation x|-> 1-x^2 envoie une uniforme sur une loi beta (flemme de faire le calcul par changement de variable).

    @dividee: Tu as tout à fait raison

  17. #17
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Points : 970
    Points
    970
    Par défaut
    Citation Envoyé par memento80 Voir le message
    Pour ce qui est de la solution de Kango, je sens qu'il y a quelque chose à creuser dans l'idée..... mais je ne vois pas vraiment comment l'exploiter.
    je prends un exemple tout bête. je souhaite avoir une distribution qui varie de manière linéaire: la valeur 0 est la plus probable (c'est la valeur modale) et la probabilité d'obtenir 100 est nulle.

    cette distribution est:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    p(x) = 1/50 * (1 - x/100)
    la probabilité d'obtenir 0 est de 1/50, la probabilité d'obtenir 50 est de 1/100 et la probabilité d'obtenir 100 est nulle.

    la fonction de distribution vérifie bien que l'intégrale de p(x) entre x = 0 et x = 100 est égale à 1.

    La fonction de répartition est (c'est la primitive):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    F(x) = x / 50 * (1 - x/200)
    La fonction réciproque de la fonction de répartition est:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    R(x) = 100 * (1 - sqrt(1 - x))
    On obtient cette équation réciproque en calculant la solution de la fonction:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    x / 50 * (1 - x/200) = y
    où y est une constante quelconque entre 0 et 1.

    Ensuite, tu génères un nombre aléatoire suivant une loi uniforme entre 0 et 1 que tu injectes dans ta fonction réciproque (R(x)) et tu obtiens un nombre aléatoire qui satisfait la distribution initiale.

    *petite musique des chiffres et des lettres*

  18. #18
    Membre habitué Avatar de memento80
    Homme Profil pro
    Boulot : ne rentre pas dans une case
    Inscrit en
    Novembre 2004
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Boulot : ne rentre pas dans une case
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2004
    Messages : 163
    Points : 125
    Points
    125
    Par défaut
    *Le compte est bon*

    Je comprends un peu mieux avec ces précisions. J'ai pu même faire quelques tests et simulations pour voir ce que je peux obtenir en fonction des différentes solutions.

    Je pense que le random.betavariate est la solution qui se rapprocherait le plus de ce que je veux... Reste à affiner les valeurs de beta et alpha.

    Merci en tout cas à tous pour vous être cassé un peu la tête pour mon problème.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Influencer un nombre aléatoire (le retour)
    Par memento80 dans le forum Langage
    Réponses: 10
    Dernier message: 26/12/2011, 19h49
  2. Nombres aléatoires
    Par Mat 74 dans le forum Assembleur
    Réponses: 20
    Dernier message: 29/08/2004, 13h31
  3. recherche algo de génération de nombre aléatoire
    Par Pascale38 dans le forum MFC
    Réponses: 2
    Dernier message: 26/01/2004, 14h20
  4. Nombre aléatoire en SQL
    Par sqlnet dans le forum Langage SQL
    Réponses: 8
    Dernier message: 19/08/2003, 12h38
  5. Générer un nombre aléatoire entre 0 et 1 (INCLUS !!!)
    Par haypo dans le forum Algorithmes et structures de données
    Réponses: 3
    Dernier message: 22/08/2002, 16h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo