Archiv der Kategorie: Pakete

Nützliche Erweiterungspakete für R.

dqrng v0.0.5: Neue und aktualisierte RNGs

Eine neue Version des dqrng Pakets ist auf den CRAN Servern verfügbar. Vielen Dank an die CRAN Maintainer im Allgemeinen und Uwe Ligges im Besonderen für ihren Einsatz.

In dieser Version gibt es einen neuen Zufallszahlengenerator, der zusammen mit den Verteilungsfunktionen benutzt werden kann: Die 64 bit Version des Threefry Engines mit 20 Runden (Salmon et al., 2011 <doi:10.1145/2063384.2063405>, http://www.thesalmons.org/john/random123/) aus dem sitmo Paket. Vielen Dank an James Balamuta für das Bereitstellen der C++11 Version von Threefry in seinem Paket.

Zusätzlich wurden die PCG-Header auf die neueste Version aktualisiert. Vielen Dank an Aaron Lun für die Erinnerung und den Hinweis auf zwei BioConductor-Pakete die dgrng nutzen: DropletUtils und scran.

Daneben gab es noch zwei technische Änderungen: Einerseits ist das Paket nun vorbereitet für die Zukunft, nachdem -DSTRICT_R_HEADERS in src/Makevars zu PKG_CPPFLAGS hinzugefügt wird.

Andererseits gibt es nun Unit-Tests für die C++ Schnittstelle. Zunächst hatte ich Catch probiert, nachdem ich bereits testthat nutze. Allerdings gefiel es mir nicht Testcode in die endgültige Bibliothek zu integrieren. Stattdessen gibt es nun C++ Dateien, die während des Tests durch Rcpp::sourceCpp() kompiliert und danach ausgeführt werden. Das ist zudem ein realistischerer Test der C++ Schnittstelle.

dqsample: Eine faire Alternative zu ‚base::sample‘

Das Erzeugen von zufälligen Stichproben eines Datensatzes wird in der Statistik oder Data Science oft angewendet. Für diese Aufgabe gibt es in R die Funktion base::sample. Leider ist der dabei verwendete Algorithmus nicht vollständig fair. Dies wurde zuletzt auf R-devel diskutiert, was auch die Motivation für das dqsample Paket darstellt. Derzeit ist dqsample nicht auf CRAN, kann aber über drat installiert werden:

Beispiel

Wählt man viele Zahlen zufällig aus, so sollten die Dichten der geraden und ungerade Zahlen in etwa gleich und konstant sein. Mit base::sample ist dies jedoch nicht er Fall:

plot of chunk base

Oder mit verändertem Parameter:

plot of chunk base-oszi

Dieses spezielle Beispiel stammt von Duncan Murdoch.

Daniel Lemire (2018, <arXiv:1805.1094>) hat einen alternativen Algorithmus vorgeschlagen, der in dqsample verwendet wird. Mit diesem Algorithmus gibt es keine Asymmetrie zwischen geraden und ungeraden Zahlen:

plot of chunk dqsample

Ursachenforschung

Intern benötigt die base::sample() Funktion zufällige ganze Zahlen die gleichmäßig in dem halb-offenen Bereich [0, n) verteilt sind.Um diese zu erzeugen, verwendet R zufällige Gleitkommazahlen aus [0, 1), multipliziert mit n und schneidet den Nachkommateil ab. Mit reellen Zahlen im mathematischen Sinn wäre das korrekt. Aber das ist hier nicht der Fall.

Standardmäßig verwendet R einen 32 bit Mersenne-Twister zum Erzeugen von Zufallszahlen. Dieser erzeugt ganze Zahlen aus [0, 2^32), die durch 2^32geteilt werden um Gleitkommazahlen aus [0, 1) zu erhalten.Wenn wir das oben beschriebene Verfahren invertieren, so können wir sehen wie viele mögliche Zufallszahlen zu einem Ergebnis gehören.  Mit sample(6, 10, replace = TRUE) kann man zum Beispiel den Wurf von zehn Würfeln simulieren. Da 2^32 kein Vielfaches von sechs ist, kann die Verteilung aber nicht gleichverteilt sein:

Eins und vier haben eine minimal geringere Wahrscheinlichkeit als die übrigen Zahlen. Dieser Effekt steigt mit der Größe des Datensatzes, aus dem gewählt wird. Verwenden wir das oben definierte m so können wir sehen, woher die ungleiche Verteilung gerader und ungerader Zahlen herkommt:

Während jeweils zwei Zahlen auf eine der ungeraden Zahlen abgebildet werden, sind es drei Zahlen für jede gerade Zahl. Dieses Muster verschiebt sich bei der Hälfte der möglichen Ergebnisse, was das erste Bild oben erklärt. Das Muster verschiebt sich öfter, wenn man sich von m entfernt, was die Oszillationen im zweiten Bild erklärt. Irgendwann werden die Oszillationen zu schnell, um sie in der Dichte sehen zu können. Das bedeutet aber nicht, dass die Verteilung fair ist. Für m - 2^20verschiebt sich das Muster beispielsweise zwischen 982 und 983:

Vorher sind gerade Zahlen wahrscheinlicher als ungerade Zahlen. Danach ist es umgekehrt.

Zusammenfassung

Der von base::sample verwendet Algorithmus ist nicht fair, was zusammen mit großen Datenmengen einen merkbaren Effekt haben kann. Das dqsample Paket stellt für die wichtigsten Anwendungsfälle einen fairen Algorithmus bereit. Es kann als direkter Ersatz für base::sample verwendet werden.

tikzDevice hat ein neues zu Hause

Im Februar diesen Jahres wurde das tikzDevice Paket auf CRAN auf ORPHANED gestellt. In der Folge suchten Kirill Müller und Yihui Xie eine neuen Maintainer. Als wir das einige Zeit später lasen, beschlossen wir uns hier einzubringen. Nach einem kurzen E-Mail-Dialog mit Yihui Xie wurde das GitHub Repository auf unsere Organization übertragen: https://github.com/daqana/tikzDevice. Derweil haben wir die bestehenden Warnungen aus den CRAN checks behoben und Version 0.12 hochgeladen.

Was kann man mit tikzDevice tun? es is ein graphics device vergleichbar zu pdf() oder png(). Aber an Stelle einer Bilddatei, die in einen Report als externe Graphik eingefügt werden kann, erzeugt es Dateien im TikZ format durch die LaTeX die Graphiken erstellt. Das ermöglicht konsistente Schriften für Text und Graphiken sowie die Verwendung von TeXs Fähigkeiten zur Darstellung mathematischer Formeln. Die PDF-Vignette enthält viele Beispiele.

Man kann es sogar in einem R-Markdown Dokument nutzen. Ein Dokument mit

im YAML Kopf und

in einem setup Block wird für Text und Graphiken die gleiche Schrift nutzen, wenn letztere mit dev = "tikz" erzeugt werden. In diesem Beispiel Palatino mit Minuskelziffern:

Palatino mit Minuskelziffern

 

Erste CRAN Veröffentlichung für dqrng

Das dqrng Paket ist jetzt über CRAN verfügbar. Zur Installation wird nur mehr

benötigt. Neben der vereinfachten Installation wurden auch die enthaltenen RNGs aktualisiert: Xorshift128+ und Xorshift1024* wurden zu Gunsten des neuen Xorshiro256+ entfernt, c.f. http://xoshiro.di.unimi.it/. Die Benutzung der RNGs aus R ist unverändert:

Schnelle Zufallszahlen für R mit dqrng

Wer nur wenige aber echte Zufallszahlen benötigt kann Würfel oder atmosphärisches Rauschen nutzen. Wer jedoch viele Zufallszahlen braucht kommt um einen Pseudo-Zufallszahlgenerator (random number generator (RNG)) nicht herum. R unterstützt verschiedene RNGs (vgl. ?Random) und eine Vielzahl von Verteilungsfunktionen (vgl. ?distributions). Die zugrundeliegenden Methoden sind zwar gut getestet, gehören aber nicht zu den schnellsten verfügbaren Methoden. Das dqrng Paket stellt schnelle Zufallszahlgeneratoren mit guten statistischen Eigenschaften für R bereit. Es verbindet diese RNGs mit schnellen Verteilungsfunktionen für Gleich-, Normal- und Exponentialverteilung.

Installation

Derzeit ist dqrng nicht auf CRAN. Die aktuelle Version kann aber über drat installiert werden:

Nutzung

Die Nutzung der enthaltenen RNGs in R ist sehr ähnlich zur Nutzung der eingebauten RNGs:

Diese Zufallszahlgeneratoren sind allerdings deutlich schneller. Zum Vergleich werden hier 10 Millionen Zufallszahlen mit verschiedenen Verteilungen erzeugt:

expr min lq mean median uq max neval
runif 248.16730 251.83371 262.20559 260.33073 265.69415 322.15771 100
dqrunif 34.77413 35.44569 39.40738 36.82459 38.42524 109.96758 100
rnorm 587.40975 596.92850 618.79356 613.08345 624.31043 706.79528 100
dqrnorm 63.17649 64.43796 68.77696 66.80184 68.39577 141.97466 100
rexp 392.79228 397.48715 413.66996 411.14180 420.42473 494.49631 100
dqrexp 52.75875 53.64510 57.15006 55.80021 58.65553 79.11577 100

plot of chunk unnamed-chunk-4

Die r* Funktionen nutzen hier den standard Mersenne-Twister, während für dqr* Xoroshiro128+ zum Einsatz kam. Für rnorm wurde die standard Inversionsmethode genutzt, während dqrnorm (und dqrexp) den Ziggurat Algorithmus aus Boost.Random mit zusätzlichen Verbesserungen nutzt.

Sowohl die RNGs als auch die Verteilungsfunktionen sind als C++ header only Bibliothek enthalten. Die Vignette zeigt Möglichkeiten zur Nutzung in C++.

Unterstützte Zufallszahlgeneratoren

Folgende 64 bit RNGs werden derzeit unterstützt:

  • Mersenne-Twister
    Die 64 bit Variante des Mersenne-Twister ist der standard RNG. Dies ist eine konservative Wahl die es erlaubt die schnellen Verteilungsfunktionen zu nutzen und dennoch nahe an Rs standard RNG (32 bit Mersenne-Twister) zu bleiben.
  • pcg64
    Die Standard 64 bit Variante aus der PCG Familie entwickelt von Melissa O’Neill. Siehe http://www.pcg-random.org für weitere Informationen.
  • Xoroshiro128+, Xorshift128+, and Xorshift1024*
    Diese überwiegend von Sebastiano Vigna enwickelten RNGs werden von Erlang und verschiedenen JavaScript-Implementierungen als standard RNG genutzt. Siehe http://xoroshiro.di.unimi.it/ für weiter Informationen.