2013-12-18 19 views
6

Aggiornamento (agosto 2014): Non sono mai arrivato a fondo e non ho mai ricevuto feedback sul forum di Revolution. Questo problema, tuttavia, sembra essere stato risolto in Revolution R 7.2 (con R 3.0.3, ancora una volta nella versione accademica). Ho eseguito il test lme() sotto alcune centinaia di volte, tutti hanno prodotto risultati uguali, come previsto. [fine aggiornamento]lme() risultati diversi eseguiti sotto Revolution R (MKL da incolpare?)

Ho appena installato la versione accademica di Revolution R 7.0 (R 3.0.2) su un nuovo PC e sto ottenendo risultati strani per il codice qui sotto. Ogni volta che il codice viene eseguito, dà risultati diversi. Sotto CRAN-R il risultato è sempre lo stesso (come penso dovrebbe essere). Lo snippet di codice proviene dal test 527 della versione 1.8.10 test.data.table(), che mi ha indirizzato all'errore.

library(nlme) 
all.equal(lme(distance ~ age, data=Orthodont), lme(distance ~ age, data=Orthodont)) 

Ho qualcosa di simile sotto, ma diverso ogni volta.

> all.equal(lme(distance ~ age, data=Orthodont), lme(distance ~ age, data=Orthodont)) 
[1] "Component 4: Component 2: Component 1: Mean relative difference: 1.774149e-08" 
[2] "Component 7: Mean relative difference: 0.0003335902" 

La cosa 'divertente' è che il pacchetto nlme (di cui fa parte lme()) in sé è identico, ho disinstallato e reinstallato per essere sicuri (il file nlme_3.1-113.zip del pacchetto è po ' -per-bit identico).

Non so ancora abbastanza per andare sotto il cofano. Qualsiasi suggerimento o idea sarebbe apprezzato. Ho anche postato sul forum di Revolutions ma sembra molto meno popolato di qui ...

Questo è sotto Windows 8.1 a 64 bit, 64-bit R e CPU Intel i7-4770 se è importante. Sia l'attuale versione di Revolution R (R 3.0.2) che quella precedente (2.15.3) producono il comportamento inaspettato (per me). CRAN-R 3.0.1 e 3.0.2 producono risultati identici.

sessionInfo() output per Revolution R:

> sessionInfo() 
R version 3.0.2 (2013-09-25) 
Platform: x86_64-w64-mingw32/x64 (64-bit) 

locale: 
[1] LC_COLLATE=English_United States.1252 
[2] LC_CTYPE=English_United States.1252 
[3] LC_MONETARY=English_United States.1252 
[4] LC_NUMERIC=C       
[5] LC_TIME=English_United States.1252  

attached base packages: 
[1] stats  graphics grDevices utils  datasets methods base  

other attached packages: 
[1] nlme_3.1-113  Revobase_7.0.0 RevoMods_7.0.0 RevoScaleR_7.0.0 
[5] lattice_0.20-24 rpart_4.1-3  

loaded via a namespace (and not attached): 
[1] codetools_0.2-8 foreach_1.4.1  grid_3.0.2  iterators_1.0.6 
[5] pkgXMLBuilder_1.0 revoIpe_1.0  tools_3.0.2  XML_3.98-1.1 

UPDATE 1: ho tracciato il problema (in seguito alcuni dei puntatori dalla risposta & commenti qui sotto) per il fatto che utilizza Revolution R la libreria Intel MKL BLAS. Se passo alla libreria BLAS fornita da CRAN, i problemi scompaiono. (Nota: non so abbastanza per compilare me stesso, quindi non ho testato OpenBLAS e le altre alternative.In Revolution R è solo una questione di rinominare due dll-s.).

Sembrerebbe che altre persone ottengano inconsistent results with MKL as well. Le differenze ci sono all'interno della tolleranza della macchina, ad esempio all.equal() è TRUE mentre identical() è FALSE. I diversi risultati nel mio caso sembrano essere significativamente grandi.

Ho postato questo problema sul forum di Revolution R e aggiornerò qui se ottengo una risposta. Suppongo che a questo punto la mia domanda debba essere modificata come "quando usare MKL BLAS e quando CRAN-R BLAS". Non è un problema di velocità (*) ma di risultati coerenti e corretti. Passerò ancora un po 'di tempo a cercare una suite di test standard (non sono sicuro della terminologia qui?) Per verificare l'output di R rispetto all'output noto-to-be-correct. Questa è una delle cose che amo di data.table, ha il suo test visibile all'utente finale. Sono consapevole che non dovrei aspettarmi un singolo test che comprenda tutti (o anche la maggior parte) pacchetti, ma qualcosa che riguardi almeno la funzionalità di base.

(*) La velocità dipende dal flusso di lavoro concreto. In questo caso particolare, il BLAN CRAN è più veloce di MKL (entrambi funzionano a thread singolo). In altri lavori, Revolution R è stato sostanzialmente più veloce, ecco perché lo sto esaminando.

+0

Questa è una ricerca accurata! –

+0

interessante, ho riscontrato un problema simile durante l'elaborazione di SVD, dare un'occhiata qui: http://stackoverflow.com/questions/40052770/strange-behaviour-when-computing-svd-on-a-covariance-matrix-different- results-b –

risposta

4

Ad una ipotesi, Revo R la sta parallelizzando sui core della CPU e l'aritmetica nella ricomposizione delle cose parallele non è sempre associativa. In altre parole, dipende dall'ordine delle operazioni. Se i thread terminano in ordini diversi, cosa che può succedere se i core devono fare qualcos'altro, i risultati vengono sommati in un ordine diverso e (a + b) + c non è sempre uguale a a + (b + c) in floating point ...

Per verificare, c'è un modo per dire a Revo R di utilizzare solo un core della CPU?

+1

+1: Su Windows vai a Task Manager, processi, fai clic destro sul tuo processo revoR, imposta affinità e deseleziona tutti tranne un core –

+1

Questa è una buona idea ma non sembra essere la causa. Ho controllato impostando l'affinità con un singolo core, lo stesso comportamento. Le differenze sono molto più grandi di quanto ci si potrebbe aspettare da errori in virgola mobile. AFAIK 'all.equal()' si occupa dell'arrotondamento della macchina, al contrario di 'identico()'. In ogni caso, un 'grado professionale' R dovrebbe occuparsi di tali incoerenze, giusto? – Peter

+0

Questo comportamento e il RNG (e bug) sono le uniche ragioni per cui ho mai visto che le cose falliscono in questo modo. Hai provato con set.seed (99) prima di eseguire più corse? Altrimenti le tue scelte sono a) per rintracciare dove in lme4 le risposte divergono eb) chiedi al popolo Revo. – Spacedman