2015-07-16 6 views
21

x = numpy.random.rand(1) erzeugen, um eine Zufallszahl zwischen 0 und 1 zu generieren. Wie mache ich es so, dass x > .5 ist 2 mal wahrscheinlicher als x < .5?Machen Sie eine Zahl wahrscheinlicher von

+0

das ist nicht zufällig – Jodrell

+3

@Jodrell es ** ist ** zufällig. Nur nicht gleichmäßig verteilt zufällig. –

+0

Sie müssen angeben, welche Art von Wahrscheinlichkeitsverteilung Sie suchen - es gibt unendlich viele mögliche Verteilungen, wobei * p (x> 0,5) = 2 * p (x <0,5) *. –

Antwort

26

vermuten, dass ein passender ist Name!

Machen Sie nur ein wenig Manipulation der Eingänge. Zuerst x im Bereich von 0 bis 1.5 einstellen.

x = numpy.random.uniform(1.5) 

x hat eine 2/3 Chance größer als 0.5 und 1/3 Chance kleiner ist. Dann, wenn x größer als 1.0 ist, subtrahieren .5 daraus

if x >= 1.0: 
    x = x - 0.5 
+0

.Mai muss '> =' sein, wenn der Bereich am Ende exklusiv ist – paxdiablo

+3

sollte random.uniform sein Ich denke: P –

+0

würde es einen Unterschied machen? – AZhao

8
tmp = random() 
if tmp < 0.5: tmp = random() 

ist ziemlich einfach, wie es

ehh zu tun, denke ich dies als wahrscheinlich 3x ist ... das ist, was ich für das Schlafen durch diese Klasse bekomme ich

from random import random,uniform 

def rand1(): 
    tmp = random() 
    if tmp < 0.5:tmp = random() 
    return tmp 
def rand2(): 
    tmp = uniform(0,1.5) 
    return tmp if tmp <= 1.0 else tmp-0.5 

sample1 = [] 
sample2 = [] 
for i in range(10000): 
    sample1.append(rand1()>=0.5) 
    sample2.append(rand2()>=0.5) 

print sample1.count(True) #~ 75% 
print sample2.count(True) #~ 66% <- desired i believe :) 
+1

Wäre das nicht 3 Mal wahrscheinlicher für eine Zahl größer als 0,5? Ich mag diesen Weg, obwohl – Jeremy

+0

Ich glaube, es wäre 2x so wahrscheinlich zu 0,5 oder größer sein meine Tests zeigen ~ 75% der Zeit ist es, was ich denke, ist 3x so wahrscheinlich .... gute Mathematik: P –

+0

hmmm wiederholte Tests (nur eine große Liste zu füllen) zeigen die andere Lösung (Rand (1.5) zu 0,5 oder mehr nur etwa 50% der Zeit ergeben .... was seltsam scheint ... –

3

Zunächst einmal hat numpy.random.rand(1) keinen Wert im [0,1) Bereich zurückzukehren (halboffenes, enthält Null, aber nicht ein), gibt sie ein Array der Größe einer, mit Werten in diesem Bereich, mit dem oberen Ende des Bereichs nichts mit dem Argumente übergeben zu tun.

die Funktion, die Sie wahrscheinlich nach sind, ist die gleichmäßige Verteilung ein, da diese numpy.random.uniform() wird ein a erlauben Oberer Bereich.

Und, um die obere Hälfte doppelt so wahrscheinlich zu machen, ist eine relativ einfache Angelegenheit. B. einen Zufallszahlengenerator r(n), der eine gleichmäßig verteilte Ganzzahl im Bereich [0,n) zurückgibt. Alles, was Sie tun müssen, ist, die Werte einstellen, um die Verteilung zu ändern:

x = r(3)  # 0, 1 or 2, @ 1/3 probability each 
if x == 2: 
    x = 1 # Now either 0 (@ 1/3) or 1 (@ 2/3) 

Nun sind die Chancen Null zu bekommen 1/3 sind

während die Chancen für eine 2/3 bekommen sind, im Grunde, was Sie erreichen wollen mit Ihren Gleitkommawerten.

So würde ich einfach eine Zufallszahl im Bereich [0,1.5), dann subtrahieren 0,5, wenn es größer als oder gleich eins ist.

x = numpy.random.uniform(high=1.5) 
if x >= 1: x -= 0.5 

Da die ursprüngliche Verteilung auch über den [0,1.5) Bereich sein sollte, sollte die Subtraktion [0.5,1.0) machen doppelt so häufig (und [1.0,1.5) unmöglich), während die Verteilung optimal halten, auch innerhalb der einzelnen Abschnitte ([0,0.5) und [0.5,1)):

[0.0,0.5) [0.5,1.0) [1.0,1.5) before 
<---------><---------><---------> 
[0.0,0.5) [0.5,1.0) [0.5,1.0) after 
+0

@Blackhole, es war ziemlich viel zur gleichen Zeit gepostet, so dass die Antwort von AZ tatsächlich nicht existierte als ich anfing (das passiert ziemlich oft). Sobald ich es gesehen habe, hatte es einen Fehler in der Verteilung (der seitdem im Code behoben wurde, wenn nicht der Text), weshalb ich meine nicht gelöscht habe. Auf jeden Fall glaube ich, dass es bei mir eine zusätzliche Erklärung gibt, die es nützlich macht. – paxdiablo

15

Das ist für Sie Overkill, aber es ist gut, eine tatsächliche Methode zum Generieren einer Zufallszahl mit einer Wahrscheinlichkeitsdichtefunktion (pdf) zu kennen.

Sie können dies tun, indem scipy.stat.rv_continuous Unterklassen, vorausgesetzt, Sie tun es richtig. Sie müssen ein normalisiertes PDF haben (so dass sein Integral 1 ist). Wenn nicht, passt numpy automatisch den Bereich für Sie an. In diesem Fall hat Ihr PDF einen Wert von 2/3 für x < 0,5 und 4/3 für x> 0,5, mit einer Unterstützung von [0, 1] (0 ist das Intervall, in dem es ungleich Null ist):

import scipy.stats as spst 
import numpy as np 
import matplotlib.pyplot as plt 
import ipdb 


def pdf_shape(x, k): 
    if x < 0.5: 
     return 2/3. 
    elif 0.5 <= x and x < 1: 
     return 4/3. 
    else: 
     return 0. 


class custom_pdf(spst.rv_continuous): 
    def _pdf(self, x, k): 
     return pdf_shape(x, k) 

instance = custom_pdf(a=0, b=1) 

samps = instance.rvs(k=1, size=10000) 

plt.hist(samps, bins=20) 
plt.show() 

Example histogram

+1

Ich wollte zeigen, dass es ein Fenster für Sie öffnet, es wird nicht nur automatisch irgendwo gespeichert. – Joel

0

, wenn Sie eine flüssigere Zufälligkeit möchten, können Sie nur die Ausgabe der Zufallsfunktion quadratisch

(und subtrahieren sie von 1 x > 0.5 wahrscheinlicher statt x < 0.5 zu machen).

x = 1 - sqr(numpy.random.rand(1)) 
+0

Mit Flüssigkeit, ich nehme an, Sie meinen "anders als das, was angegeben wurde" :-) Ich kann nicht sehen, wie das die obere Hälfte zweimal wahrscheinlich machen würde, tatsächlich vermute ich, dass es eine kontinuierlich variable Wahrscheinlichkeit eingeführt am oberen Ende gewichtet. – paxdiablo

1

Sie könnten einen „Mischmodell“ -Ansatz, wo Sie den Prozess in zwei Schritte aufgeteilt: Erstens, entscheiden, ob die Option A oder B zu nehmen, wobei B doppelt so wahrscheinlich wie A ist; Wenn Sie A wählen, geben Sie eine Zufallszahl zwischen 0.0 und 0.5 zurück. Wenn Sie B wählen, geben Sie eine Zahl zwischen 0.5 und 1.0 zurück.

In dem Beispiel gibt der randint nach dem Zufallsprinzip 0, 1 oder 2 zurück, so dass der else Fall doppelt so wahrscheinlich ist wie der if Fall.

m = numpy.random.randint(3) 
    if m==0: 
    x = numpy.random.uniform(0.0, 0.5) 
    else: 
    x = numpy.random.uniform(0.5, 1.0) 

Dies ist ein wenig teurer (zwei zufällig zieht statt eins), aber es kann in einem ziemlich einfachen Weg, um kompliziertere Verteilungen verallgemeinern.

Verwandte Themen