Prędkość obliczeniowa w R?

16

Zadanie polegało mi na przeniesieniu jednego z naszych obecnych dużych modeli stochastycznych z SAS do nowego języka. Osobiście wolę tradycyjny skompilowany język, ale PI chce, żebym sprawdził R, którego nigdy nie używałem. Naszą motywacją do wyciągnięcia modelu z SAS jest (1) wiele osób nie ma do niego dostępu, ponieważ SAS jest drogi, (2) chcemy odejść od tłumaczonego języka i (3) SAS jest wolny dla rodzaj modelu, jaki mamy.

Dla (1) oczywiście R zaspokaja potrzebę, aby był wolny. W przypadku (2) najlepiej byłoby utworzyć plik wykonywalny, ale R jest zwykle używany jako język skryptowy. Widzę, że ktoś niedawno wypuścił kompilator R - czy został dobrze przyjęty? Czy to jest łatwe w obsłudze? Wolelibyśmy nie zmuszać użytkownika do samodzielnego pobrania R. W przypadku (3) naszym problemem z SAS jest cały czas spędzany na zapisywaniu i odczytywaniu zestawów danych we / wy. Nasz model wymaga dużych mocy obliczeniowych i często ogranicza nas czas działania. (np. zdarza się, że ktoś przechwytuje komputery w weekendy w celu wykonania uruchomień). Mamy podobny model zbudowany w Fortran, który nie ma tego samego problemu, ponieważ cała praca jest wykonywana w pamięci. Jak działa R? Czy będzie taki sam jak SAS, ponieważ działa w trybie danych, czytać i zapisywać pliki? Czy może manipulować tablicą w pamięci?

Melisa
źródło
Zazwyczaj można przyspieszyć sas, wykonując całą pracę w jednym kroku danych. Powinno to skrócić czas operacji we / wy, ponieważ skutecznie odczytujesz dane tylko raz. Zastosowanie wielu procedur również spowolni. Na przykład, jeśli modelujesz wielokrotnie wywoływać proc glm lub proc logistic (powiedzmy w przypadku bootstrap), szybciej jest stworzyć ogromny zestaw danych i użyć instrukcji by niż wywoływać wiele wywołań proc (powiedzmy używając makra% do loop). jeśli dobrze programujesz, nie powinieneś mieć problemów z czasem pracy z powodu odczytu i wysyłania plików (przynajmniej nie więcej niż inne oprogramowanie
probabilityislogic
Dodatkowo możesz używać tablic tymczasowych w krokach danych SAS w podobny sposób, jak używałbyś macierzy w R.
probabilityislogic

Odpowiedzi:

18

R działa w pamięci - więc większość funkcji musi pasować do pamięci.

Pakiet kompilatora, jeśli mam na myśli rzecz, o której myślisz ( kompilator Luke'a Tierneya pakiet dostarczany z R), to nie to samo, co język kompilowany w tradycyjnym znaczeniu (C, Fortran). Jest to kompilator bajtowy dla języka R w sensie bajtu kodu Java wykonywanego przez maszynę wirtualną Java lub kompilacja bajtów kodu LISP Emacsa. Nie kompiluje kodu R w dół do kodu maszynowego, ale raczej przygotowuje kod R do kodu bajtowego, aby można go było używać bardziej wydajnie niż surowego kodu R do interpretacji.

Zauważ, że jeśli dobrze uformowałeś Fortran, prawdopodobnie masz najlepsze cechy obu światów; R może wywoływać skompilowane procedury Fortrana.

Przywróć Monikę - G. Simpson
źródło
Dzięki! Miło wiedzieć, że mogłem mieć świetną grafikę R i wywoływać skompilowane procedury Fortrana. To może być odpowiedź!
Melissa,
2
Aby rozwinąć uwagę Gavina na temat pamięci: patrz sekcja Duża pamięć w tym widoku zadań CRAN, jeśli pracujesz z większymi zestawami danych: cran.r-project.org/web/views/HighPerformanceComputing.html
Brandon Bertelsen
1
Należy również pamiętać, że ważne jest, aby pamiętać, że Rcpp można prawdopodobnie wykorzystać do uzyskania przyrostowego wzrostu wydajności.
Brandon Bertelsen
Rcpp jest przydatny do owijania C ++ do użycia w / z R. Pomaga to proces (ogromnie), ale nadal używa podstawowych narzędzi R do wywoływania skompilowanego kodu. Jeśli OP ma już kody Fortran lub umiejętności Fortran, Rcpp może być mniej użyteczny.
Przywróć Monikę - G. Simpson
13

Używam SASod 15 lat i zacząłem używać Rpoważnie w ciągu ostatnich 6 miesięcy, a niektóre z nich majstrowały przez kilka lat przed tym. Z punktu widzenia programowania, R manipulowanie danymi odbywa się bezpośrednio, nie ma odpowiednika DATAani PROC SQLprocedur, ponieważ nie są one potrzebne (ta ostatnia jest bardziej wydajna, SASgdy jest dużo manipulacji danymi z zewnętrznych źródeł danych, np. Danych administracyjnych). Oznacza to, że teraz rozumiem, że manipulowanie danymi jest szybsze Ri wymaga znacznie mniej kodu.

Głównym problemem, jaki napotkałem, jest pamięć. Nie wszystkie pakiety R zezwalają na WEIGHTspecyfikacje typów, więc jeśli masz SASzestawy danych ze zmiennymi używanymi w FREQlub REPLICATEinstrukcjach, możesz mieć problemy. Patrzyłem na pakiety ffi bigmemoryw R, ale nie wydają się one być kompatybilne ze wszystkimi pakietami R, więc jeśli masz bardzo duże zestawy danych, które wymagają analiz, które są stosunkowo rzadkie i zostały zagregowane, możesz mieć problemy z pamięcią.

W przypadku automatyzacji, jeśli masz SAS macros, powinieneś być w stanie zaprogramować ekwiwalent Ri uruchomić jako partię.

Do kodowania w Rużywałem Notepad++i Ustawianie języka R, i jestem teraz odkrywanie radości R Studio. Oba te produkty są bezpłatne i zawierają znaczniki językowe, takie jak ulepszony SASgraficzny interfejs użytkownika (do tej pory używałem tylko ekranu składni SAS).

Istnieje strona internetowa i powiązana książka dla osób zmieniających się z SASna R. Uznałem je za przydatne przy próbach przetłumaczenia niektórych SASpoleceń R.

Aktualizacja: jedną rzeczą, która zawiozła mnie orzechy, kiedy zbliża się do Rjest to, że Rnie przyjmuje wszystko to zestaw danych ( data framew Rżargonie), ponieważ nie jest to pakiet statystyczny w taki sposób, że SAS, SPSS, Stata, itp są. Na przykład zajęło mi trochę czasu, aby ifinstrukcje działały, ponieważ ciągle otrzymywałem pomoc dla ifinstrukcji z wektorami (lub może macierzami), podczas gdy potrzebowałem ifinstrukcji, która działała data frames. Tak więc strony pomocy prawdopodobnie powinny być czytane dokładniej niż normalnie, ponieważ musisz sprawdzić, czy polecenie, które chcesz wykonać, będzie działać z typem obiektu danych, który masz.

To, co wciąż doprowadza mnie do szału, kiedy uczę się nowego Rpolecenia (np. Metody analizy w paczce), polega na tym, że pomoc dla poleceń często nie jest całkowicie samodzielna. Przejdę do strony pomocy, aby spróbować nauczyć się polecenia i często ...w nim zawartych notatek dotyczących użytkowania . Czasami próba ustalenia, co może lub powinna pójść tam, gdzie ...jest, doprowadziła mnie do pętli rekurencyjnej. Względna zwięzłość notatek pomocy, z SASktórych pochodzą szczegółowe przykłady składni i przykładów roboczych z wyjaśnieniem badania w tym przykładzie, była dość dużym szokiem.

Michelle
źródło
2
+1 Rozważ zaktualizowanie naszego meta wątku, w którym zebraliśmy linki do zasobów oprogramowania statystycznego. Jest jedna odpowiedź dla R i druga dla SAS: obie skorzystałyby na linku do r4stats.com. (Ten wątek jest w rzeczywistości częścią naszego FAQ. Mamy nadzieję, że będzie aktualny i przydatny.)
whuber
1
R ma również pakiety obsługujące dostęp do SQL za pośrednictwem sterowników RODBC lub SQLite.
DW
1
Zgadzam się z twoimi komentarzami na temat pomocy R. Właściwie wskazałem zasadniczo to, co mówisz na jednej z list mailingowych R wiele lat temu. Odpowiedź nie była pozytywna. Uczciwie, ja (a) prawdopodobnie nie wyraziłem się zbyt dobrze, nie podałem żadnych konkretnych przykładów i (b) nie zajmowałem się tą sprawą. Podsumowując, problem 1 to przykłady zbyt skomplikowane i obejmujące zbyt wiele niepowiązanych pojęć. Skomplikowane przykłady są w porządku, ale powinny podążać za prostymi przykładami. Problem 2 polega na tym, że prawie nie ma adnotacji ani wyjaśnienia tego, co robią przykłady.
Faheem Mitha
Odnośnie „pomocy” R przypomina coś, co powiedział mi mój szef. „uczysz się R, robiąc to z kimś, kto już zna R siedzącego obok ciebie przy komputerze”
probabilityislogic
A dla wszystkich innych są książki i przepełnienie stosu. Tak, nauka R na własną rękę jest dość trudna, przynajmniej dla mnie.
Michelle,
10

R jest językiem programowania. To nie działa w trybie danych. Robi wszystko, co chcesz, bo jest to tylko język programowania, niewolnik twoich pragnień, wyrażony w języku nawiasów klamrowych i dwukropków.

Pomyśl o tym jak o Fortranie lub C, ale z niejawną wektoryzacją, abyś nie musiał zapętlać tablic i dynamicznym zarządzaniem pamięcią, abyś nie musiał malloc () ani deklarować rozmiarów tablic w dowolnym momencie.

Przeważnie wykonuje całą swoją pracę w pamięci, ale jeśli chcesz odczytać część pliku, mung go, a następnie wypluć niektóre wyniki i przeczytać następny kawałek, cóż, naprzód napisz program R, który robi to.

Przeciwstawiasz się twierdzeniu, że model jest intensywny obliczeniowo, ale SAS jest powolny z powodu I / O ... Tak czy inaczej ...

Jeśli masz już coś podobnego w Fortranie i mówisz, że chcesz odejść od tłumaczonego języka, to dlaczego nie zrobić tego również w Fortranie?

Kompilator R może powodować pewne przyspieszenia, ale jeśli i tak kod R jest dobrze napisany, nie otrzymasz nic zbyt masywnego - nie tak jak pisanie go w C lub Fortranie.

Spacedman
źródło
Ach, nie wytłumaczyłem się dobrze. Intensywnie manipuluje zestawami danych, co w SAS oznacza zbyt dużo czasu spędzanego na we / wy. Moją początkową sugestią był Fortran, ale PI jest zainteresowany tym, żebyśmy przeszli na R, więc chciał, żebym to sprawdził. Dzięki!
Melissa,
7

Rozumiem, że domyślnie SAS może pracować z modelami większymi niż pamięć, ale nie jest tak w przypadku R, chyba że użyjesz pakietów takich jak biglm lub ff.

Jednak jeśli wykonujesz pracę tablicową w R, którą można wektoryzować, będzie to bardzo szybkie - może w niektórych przypadkach połowa prędkości programu C, ale jeśli robisz coś, czego nie można wektoryzować, to wydaje się całkiem powolny. Aby dać ci przykład:

# create a data.frame with 4 columns of standard normally distributed RVs
N <- 10000

# test 1
system.time( {df1 <- data.frame(h1=rnorm(N),
                h2=rpois(N, lambda=5),
                h3=runif(N),
                h4=rexp(N))
} )
# about 0.003 seconds elapsed time

# vectorised sum of columns 1 to 4
# i.e. it can work on an entire column all at once
# test 2
system.time( { df1$rowtotal1 <- df1$h1 + df1$h2 + df1$h3 + df1$h4 })
# about 0.001 seconds elapsed time

# test 3
# another version of the vectorised sum
system.time( { df1$rowtotal2 <- rowSums(df1[,c(1:4)]) })
# about 0.001 seconds elapsed time

# test 4
# using a loop... THIS IS *VERY* SLOW AND GENERALLY A BAD IDEA!!! :-)
system.time( {
        for(i in 1:nrow(df1)) {
                df1$rowtotal3 <- df1[i,1]+ df1[i,2] + df1[i,3] + df1[i,4]
        }
} )
# about 9.2 seconds elapsed time

Kiedy zwiększyłem N dziesięciokrotnie do 100 000, zrezygnowałem z testu 4 po 20 minutach, ale testy 1: 3 trwały 61, 3 i 37 milisekund każdy

Dla N = 10 000 000 czas testów 1: 3 wynosi 3,3, 0,6 i 1,6 s

Zauważ, że zostało to zrobione na laptopie i7 i przy 480 MB dla N = 10 milionów, pamięć nie była problemem.

Dla użytkowników w 32-bitowych oknach obowiązuje limit pamięci 1,5 Gb dla R, bez względu na ilość pamięci, ale nie ma takiego limitu dla 64-bitowych okien lub 64-bitowego systemu Linux. W dzisiejszych czasach pamięć jest bardzo tania w porównaniu z godziną mojego czasu, więc po prostu kupuję więcej pamięci, niż spędzam czas próbując obejść ten problem. Ale zakłada to, że Twój model zmieści się w pamięci.

Sean
źródło
1
(+1) Dziękujemy za zaoferowanie użytecznych ilustracji, Sean!
whuber
3

(2), najlepiej chcielibyśmy utworzyć plik wykonywalny, ale R jest zwykle używany jako język skryptowy

Tak, i to jest dobry powód, aby przejść do R. Celem napisania pakietu R jest umożliwienie użytkownikom łatwego współdziałania funkcji z innymi narzędziami udostępnianymi przez R, np. Dostarczanie im danych rozruchowych ... lub cokolwiek chcą. Jeśli nie uważasz, że to ważne, trzymaj się C / C ++ lub swojego ulubionego skompilowanego języka.

Chcę dodać zastrzeżenie: jesteś już programistą, nauka R będzie łatwa i szybka; nauka efektywnego programowania R będzie dłuższa. Ponieważ R jest interpretowane, stałe ukryte wO()asymptotycznej złożoności może być ogromna lub mała ... na przykład, jeśli interesują Cię przebiegi w twoich danych, użyjesz rle(), to będzie szybkie (jest to funkcja wstępnie skompilowana). Jeśli napiszesz dokładnie ten sam algorytm, będzie on wolny (zostanie zinterpretowany). Jest to podstawowy przykład: masz wiele sztuczek za pomocą wektora i macierzy, aby uniknąć interpretowanych pętli i sprawić, że wstępnie skompilowane funkcje wykonają całą robotę.

Więc bądź bardzo ostrożny. Po pierwszych próbach na pewno będziesz odczuwał obrzydzenie do R, ponieważ będziesz go spowalniał, z dziwną składnią itp. Gdy się zorientujesz, może to być bardzo wydajne narzędzie. Możesz nawet zakończyć skryptowaniem swoich metod w języku R jako wstępną fazą kodowania C / C ++. Ostatecznym etapem będzie poznanie API R do tworzenia wstępnie skompilowanych funkcji, a ty będziesz kreatorem R. :)

Elvis
źródło
2

Najwyraźniej manipulacja tablicą w pamięci jest dla SAS bardzo ważna. Nie znam szczegółów dotyczących R, ale przypuszczam, że R domyślnie działa w pamięci, ponieważ pakiety rozszerzające pamięć dla R, ff i bigmemory przenoszą dane z pamięci na dysk. Mam dla ciebie wskazówki, jeśli chcesz poprawić szybkość lub zużycie pamięci. Aby zwiększyć szybkość, musisz najpierw użyć R zgodnie z przeznaczeniem, to znaczy: zektoryzować kod i użyć kompilacji bajtów. (Również: unikaj w jak największym stopniu operacji kopiowania pamięci.) Po drugie, użyj dostarczonego profilera kodu Rprof (), aby zidentyfikować wolne poprawki w kodzie i, jeśli to konieczne, przepisz je w C lub C ++. Jeśli potrzebujesz więcej pamięci, możesz użyć argumentu pominięcia w funkcji read.table (), aby odczytywać fragment danych naraz, a także możesz użyć pakietu takiego jak RMySQL, który dodaje narzędzia do manipulacji bazą danych do R. Jeśli potrzebujesz jeszcze więcej pamięci i możesz sobie pozwolić na jednoczesne zmniejszenie prędkości, możesz użyć pakietu śniegu, aby uruchomić R równolegle. (Szczegółowe informacje na ten temat i wiele innych można znaleźć w książce „The Art of R Programming” Normana Matloffa, opublikowanej pod koniec ubiegłego roku. Szczegółowe informacje na temat wymienionych tu pakietów można znaleźć w Internecie.)

Jean-Victor Côté
źródło