Vitesse de calcul en R?


16

J'ai été chargé de déplacer l'un de nos grands modèles stochastiques actuels hors de SAS et dans un nouveau langage. Personnellement, je préfère un langage compilé traditionnel, mais le PI veut que je vérifie R, que je n'ai jamais utilisé. Notre motivation pour sortir le modèle de SAS est (1) beaucoup de gens n'y ont pas accès parce que SAS est cher, (2) nous cherchons à nous éloigner d'un langage interprété, et (3) SAS est lent pour le type de modèle que nous avons.

Pour (1), évidemment R satisfait le besoin d'être libre. Pour (2), idéalement, nous aimerions créer un exécutable, mais R est normalement utilisé comme langage de script. Je vois que quelqu'un a récemment sorti un compilateur R - cela a-t-il été bien reçu? Est-il facile à utiliser? Nous préférons ne pas forcer l'utilisateur à télécharger R lui-même. Pour (3), notre problème avec SAS est tout le temps passé à écrire et lire des ensembles de données d'E / S. Notre modèle est intensif en calcul et nous sommes souvent limités par l'exécution. (Par exemple, il n'est pas rare que quelqu'un détourne les ordinateurs des gens au cours du week-end pour effectuer des courses.) Nous avons un modèle similaire construit à Fortran qui n'a pas le même problème car tout le travail se fait en mémoire. Comment fonctionne R? Sera-ce le même que SAS, en ce sens qu'il fonctionne dans datasteps, lire et écrire des fichiers? Ou peut-il manipuler des tableaux en mémoire?


Vous pouvez généralement accélérer sas en effectuant tout votre travail en une seule étape de données. Cela devrait réduire les temps d'E / S, car vous ne lisez effectivement les données qu'une seule fois. L'utilisation de nombreuses procédures vous ralentira également. Par exemple, si vous modélisez de manière répétée proc glm ou proc logistic (par exemple pour un bootstrap), il est plus rapide de créer un énorme ensemble de données et d'utiliser une instruction by que d'invoquer de nombreux appels proc (par exemple, en utilisant une boucle macro% do). si vous programmez bien sas, vous ne devriez pas avoir des problèmes de temps d'exécution en raison de la lecture et les fichiers outputing (au moins pas plus que d' autres logiciels
probabilityislogic

De plus, vous pouvez utiliser des tableaux temporaires dans les étapes de données sas de la même manière que vous utiliseriez des matrices dans R.
probabilislogic

Réponses:


18

R fonctionne en mémoire - vos données doivent donc tenir en mémoire pour la majorité des fonctions.

Le paquet du compilateur, si je pense à la chose à laquelle vous pensez ( compilateur de Luke Tierney package de fourni avec R), n'est pas la même chose qu'un langage compilé au sens traditionnel (C, Fortran). Il s'agit d'un compilateur d'octets pour R au sens de bytecode Java exécuté par la machine virtuelle Java ou de compilation d'octets du code Emacs LISP. Il ne compile pas le code R en code machine mais prépare plutôt le code R en bytecode afin qu'il puisse être utilisé plus efficacement que le code R brut à interpréter.

Notez que si vous avez bien formé Fortran, vous pourriez probablement avoir le meilleur des deux mondes; R peut appeler des routines Fortran compilées.


Merci! Il est bon de savoir que je pourrais avoir les superbes graphismes R et appeler des routines Fortran compilées. C'est peut-être la réponse!
Melissa

2
Juste pour développer la note de Gavin sur la mémoire: consultez la section sur la grande mémoire dans cette vue de tâche CRAN si vous travaillez avec des ensembles de données plus volumineux: cran.r-project.org/web/views/HighPerformanceComputing.html
Brandon Bertelsen

1
Pensez également qu'il est important de noter que Rcpp pourrait probablement être utilisé pour obtenir des gains de performances incrémentiels.
Brandon Bertelsen

Rcpp est utile pour envelopper C ++ pour une utilisation dans / avec R. Il facilite le processus (énormément) mais utilise toujours les outils de base de R pour appeler du code compilé. Si l'OP a déjà des codes Fortran ou des compétences Fortran, Rcpp peut être d'une moindre utilité.
Rétablir Monica - G. Simpson

13

Je l'utilise SASdepuis 15 ans et j'ai commencé à l'utiliser Rsérieusement au cours des 6 derniers mois, avec quelques bricolages pendant quelques années avant cela. Du point de vue de la programmation, R les manipulations de données sont-elles effectuées directement, il n'y a pas d'équivalent DATAou de PROC SQLprocédures car elles ne sont pas nécessaires (ces dernières étant plus efficaces SASlorsqu'il y a beaucoup de manipulations de données à effectuer à partir de sources de données externes, par exemple des données administratives). Cela signifie que, maintenant que je comprends, la manipulation des données est plus rapide Ret nécessite beaucoup moins de code.

Le principal problème que j'ai rencontré est la mémoire. Tous les packages R n'autorisent pas WEIGHTles spécifications de type, donc si vous avez des SASensembles de données avec des variables utilisées dans FREQou des REPLICATEinstructions, vous pouvez avoir des problèmes. J'ai examiné les packages ffet bigmemorydans R, mais ils ne semblent pas compatibles avec tous les packages R, donc si vous avez de très grands ensembles de données qui nécessitent des analyses relativement rares et agrégées, vous pouvez avoir des problèmes de mémoire.

Pour l'automatisation, si vous en avez, SAS macrosvous devriez pouvoir programmer l'équivalent dans Ret l'exécuter en batch.

Pour coder R, j'utilisais Notepad++et définissais la langue R, et je découvre maintenant les joies de R Studio. Ces deux produits sont gratuits et marquent le langage comme l' SASinterface graphique de syntaxe améliorée (je n'ai utilisé que l'écran de syntaxe SAS).

Il existe un site Web et un livre connexe pour les personnes qui passent de SASà R. Je les ai trouvés utiles pour essayer de comprendre comment traduire certaines SAScommandes en R.

Mise à jour: une chose qui m'a rendu fou en venant à Rest que Rne suppose pas tout est un ensemble de données ( data framedans le Rlangage), parce que ce n'est pas un paquet statistique de la manière que SAS, SPSS, Stata, etc sont. Ainsi, par exemple, il m'a fallu un certain temps pour que les ifinstructions fonctionnent parce que je continuais à obtenir de l'aide pour les ifinstructions avec des vecteurs (ou peut-être des matrices) alors que j'avais besoin d'une ifinstruction qui fonctionnait avec data frames. Les pages d'aide doivent donc probablement être lues plus attentivement que vous ne le feriez normalement, car vous devrez vérifier que la commande que vous souhaitez exécuter fonctionnera avec le type d'objet de données dont vous disposez.

Le bit qui me rend encore fou quand j'apprends une nouvelle Rcommande (par exemple, une méthode d'analyse dans un package contribué) est que l'aide pour les commandes n'est souvent pas entièrement autonome. Je vais aller à la page d'aide pour essayer d'apprendre la commande et les notes d'utilisation qui y sont souvent ...contenues. Parfois, essayer de déterminer ce qui peut ou devrait aller là où il ...est m'a conduit dans une boucle récursive. La brièveté relative des notes d'aide, SASqui fournit des exemples détaillés de syntaxe et des exemples pratiques avec une explication de l'étude dans l'exemple, a été un choc assez important.


2
+1 Veuillez envisager de mettre à jour notre méta-fil où nous avons collecté des liens vers les ressources du logiciel de statistiques. Il y a une réponse pour R et une autre pour SAS: les deux gagneraient à avoir un lien vers r4stats.com. (Ce fil fait en fait partie de notre FAQ. Nous espérons le garder à jour et utile.)
whuber

1
R propose également des packages qui prennent en charge l'accès SQL via des pilotes RODBC ou SQLite.
DWin

1
Je suis d'accord avec vos commentaires sur l'aide de R. En fait, j'ai souligné essentiellement ce que vous dites sur l'une des listes de diffusion R il y a de nombreuses années. La réponse n'a pas été positive. En toute honnêteté, je (a) ne me suis probablement pas très bien exprimé, je n'ai pas donné d'exemples concrets et (b) je n'ai pas poursuivi l'affaire. Pour résumer, le problème 1 est des exemples trop compliqués et impliquent trop de concepts non liés. Les exemples compliqués sont corrects mais devraient suivre des exemples simples. Le problème 2 est qu'il n'y a presque pas d'annotation ou d'explication de ce que font les exemples.
Faheem Mitha

En ce qui concerne le «aide» R, je pense à quelque chose que mon patron m'a dit. "vous apprenez R en le faisant avec quelqu'un qui connaît déjà R assis à côté de vous devant l'ordinateur"
probabilislogic

Et pour tout le monde, il y a des livres et Stack Overflow. Oui, apprendre R par toi-même est assez difficile, du moins ça l'a été pour moi.
Michelle

10

R est un langage de programmation. Cela ne fonctionne pas dans datasteps. Il fait tout ce que vous voulez qu'il fasse, car ce n'est qu'un langage de programmation, un esclave pour vos désirs, exprimé dans un langage entre accolades et deux points.

Pensez-y comme Fortran ou C, mais avec une vectorisation implicite pour que vous n'ayez pas à parcourir les tableaux et une gestion dynamique de la mémoire pour ne pas avoir à malloc () ou déclarer des tailles de tableau à tout moment.

Il fait principalement tout son travail en mémoire, mais si vous voulez lire une partie d'un fichier, le mung, puis cracher certains résultats et lire le bit suivant, eh bien, vous allez de l'avant et écrivez un programme R qui est-ce que.

Vous vous contredisez en disant que le modèle est intensif en calcul mais que SAS est lent à cause des E / S ... L'un ou l'autre sûrement ...

Si vous avez déjà quelque chose de similaire dans Fortran et que vous dites que vous voulez vous éloigner d'un langage interprété, alors pourquoi ne pas le faire aussi dans Fortran?

Le compilateur R peut provoquer des accélérations, mais si votre code R est bien écrit de toute façon, vous n'obtiendrez rien de trop massif - pas comme l'écrire en C ou en Fortran.


Ah, je ne me suis pas bien expliqué. Il est intensif dans sa manipulation des ensembles de données, ce qui, en SAS, signifie trop de temps passé en E / S. Ma suggestion initiale était Fortran, mais le PI est intéressé à ce que nous passions à R, alors il voulait que je vérifie. Merci!
Melissa

7

Je comprends que par défaut, SAS peut fonctionner avec des modèles plus grands que la mémoire, mais ce n'est pas le cas avec R, sauf si vous utilisez spécifiquement des packages comme biglm ou ff.

Cependant, si vous faites un travail de tableau dans R qui peut être vectorisé, ce sera très rapide - peut-être la moitié de la vitesse d'un programme C dans certains cas, mais si vous faites quelque chose qui ne peut pas être vectorisé, alors cela semblera assez lent. Pour vous donner un exemple:

# 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

Quand j'ai augmenté N d'un facteur de dix à 100 000, j'ai abandonné le test 4 après 20 minutes, mais les tests 1: 3 ont pris 61, 3 et 37 millisecondes chacun

Pour N = 10 000 000, la durée des tests 1: 3 est de 3,3 s, 0,6 s et 1,6 s

Notez que cela a été fait sur un ordinateur portable i7 et à 480 Mo pour N = 10 millions, la mémoire n'était pas un problème.

Pour les utilisateurs sur des fenêtres 32 bits, il y a une limite de mémoire de 1,5 Go pour R, peu importe la quantité de mémoire dont vous disposez, mais il n'y a pas de telle limite pour les fenêtres 64 bits ou Linux 64 bits. De nos jours, la mémoire est très bon marché par rapport au coût d'une heure de mon temps, donc j'achète juste plus de mémoire plutôt que de passer du temps à essayer de contourner cela. Mais cela suppose que votre modèle tiendra en mémoire.


1
(+1) Merci d'avoir offert les illustrations utiles, Sean!
whuber

3

(2), idéalement, nous aimerions créer un exécutable, mais R est normalement utilisé comme langage de script

Oui, et c'est la bonne raison de passer à R. L'intérêt d'écrire un package R est de permettre aux utilisateurs de faire facilement interagir vos fonctions avec d'autres outils fournis par R, par exemple en leur fournissant des données bootstrapées ... ou tout ce qu'ils veulent. Si vous ne pensez pas que ce soit important, restez en C / C ++ ou votre langage compilé préféré.

O() de la complexité asymptotique peuvent être énormes ou petites ... par exemple, si vous êtes intéressé par des exécutions dans vos données, vous utiliserezrle() , ce sera rapide (c'est un précompilé une fonction). Si vous scriptez exactement le même algorithme, il sera lent (il sera interprété). Ceci est un exemple de base: vous avez beaucoup d'astuces à l'aide de vecteurs et de matrices, pour éviter les boucles interprétées et faire en sorte que les fonctions précompilées fassent tout le travail.

Soyez donc très prudent. Après vos premiers essais, vous aurez sûrement un dégoût de R, car vous le trouverez lent, avec une syntaxe bizarre, etc. Une fois que vous le savez, cela peut être un outil très efficace. Vous pouvez même finir par écrire vos méthodes dans R comme une phase préliminaire pour le codage C / C ++. L'étape ultime sera d'apprendre l'API de R pour créer des fonctions précompilées, et vous serez un assistant R :)


2

Apparemment, la manipulation de tableaux en mémoire est une grande chose pour SAS. Je ne connais pas les détails concernant R, mais je présume que R fonctionne en mémoire par défaut, car les packages d'extension de mémoire pour R, ff et bigmemory, déplacent les données de la mémoire vers le disque. J'ai des pointeurs pour vous si vous souhaitez améliorer la vitesse ou l'utilisation de la mémoire. Afin d'améliorer la vitesse, vous devez d'abord utiliser R comme prévu, c'est-à-dire: vectoriser votre code et utiliser la compilation de code d'octets. (Aussi: évitez autant que possible les opérations de copie de mémoire.) Deuxièmement, utilisez le profileur de code fourni Rprof () pour identifier les correctifs lents dans votre code et réécrivez-les en C ou C ++ si nécessaire. Si vous avez besoin de plus de mémoire, vous pouvez utiliser l'argument skip dans la fonction read.table () pour lire vos données un morceau à la fois et vous pouvez également utiliser un package tel que RMySQL, qui ajoute des utilitaires de manipulation de base de données à R. Si vous avez besoin de plus de mémoire et que vous pouvez vous permettre la diminution concomitante de la vitesse, vous pouvez utiliser le pack neige pour exécuter R en parallèle. (Vous pouvez trouver des détails à ce sujet, et bien plus, dans le livre "The Art of R Programming", de Norman Matloff, publié à la fin de l'année dernière. Les détails sur les packages mentionnés ici peuvent être trouvés en ligne.)

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.