In R habe ich eine Matrix wobei die -te Reihe von einer Verteilung auf . Im Wesentlichen muss ich aus jeder Zeile effizient probieren. Eine naive Implementierung ist:P i P { 1 , . . . , K }
X = rep(0, N);
for(i in 1:N){
X[i] = sample(1:K, 1, prob = P[i, ]);
}
Das ist viel zu langsam. Im Prinzip könnte ich dies nach C verschieben, aber ich bin mir sicher, dass es dafür einen bestehenden Weg geben muss. Ich möchte etwas im Sinne des folgenden Codes (der nicht funktioniert):
X = sample(1:K, N, replace = TRUE, prob = P)
EDIT: Zur Motivation nimm und . Ich habe Matrizen alle und ich muss von jedem einen Vektor abtasten.K = 100 P 1 , . . . , P 5000 N × K
Antworten:
Wir können dies auf ein paar einfache Arten tun . Der erste ist einfach zu codieren, leicht zu verstehen und relativ schnell. Die zweite ist etwas kniffliger, aber für diese Problemgröße viel effizienter als die erste Methode oder andere hier erwähnte Ansätze.
Methode 1 : Schnell und schmutzig.
Um eine einzelne Beobachtung aus der Wahrscheinlichkeitsverteilung jeder Zeile zu erhalten, können wir einfach Folgendes tun.
Dies ist im Allgemeinen keine äußerst effiziente Methode, um dies zu tun, nutzt jedoch die
R
Vektorisierungsfunktionen, die normalerweise die Hauptdeterminante für die Ausführungsgeschwindigkeit sind. Es ist auch einfach zu verstehen.Methode 2 : Verketten der cdfs.
Hier ist der Code.
findInterval
runif(N)+i
Da
findInterval
diese Methode sowohl algorithmisch als auch implementierungsmäßig schnell ist, erweist sie sich als äußerst effizient.Ein Maßstab
Die Ausführung des Codes für Methode 1 dauerte fast genau 15 Minuten oder etwa 55.000 zufällige Variationen pro Sekunde. Die Ausführung des Codes für Methode 2 dauerte ungefähr viereinhalb Minuten , oder ungefähr 183.000 zufällige Variationen pro Sekunde.
Hier ist die Ausgabe.
Nachtrag : Wenn
findInterval
wir uns den Code ansehen, können wir feststellen, dass die Eingabe überprüft wird, obNA
Einträge vorhanden sind oder ob das zweite Argument nicht sortiert ist. Wenn wir also mehr Leistung daraus ziehen möchten, könnten wir unsere eigene modifizierte Version erstellenfindInterval
, die diese in unserem Fall unnötigen Überprüfungen entfernt.quelle
Eine
for
Schleife kann furchtbar langsam seinR
. Wie wäre es mit dieser einfachen Vektorisierung mitsapply
?Natürlich dient dieses einheitliche p nur zum Testen.
quelle