07 maggio 2012

Big data in R

Segnalo questo interessantissimo post in cui sono riportati diversi link che trattano il problema del parallel computing e delle performance di R con grossi volumi di dati.

01 gennaio 2012

Algoritmi per il campionamento da popolazioni finite: un'analisi mediante simulazioni Monte Carlo

Inizio il nuovo anno con la condivisione delle slide della mia tesi di Ph.D. 
Mediante simulazioni Monte Carlo, ho testato il soddisfacimento di alcune proprietà (valide per costruzione) per i seguenti algoritmi di campionamento di tipo PPS (probability proportional to size):
  • Hanurav-Vijayan;
  • Rao-Sampford.
Ho effettuato l'analisi in tutti i software statistici che, al momento della realizzazione del mio lavoro di ricerca, mi risultavano essere gli unici a prevedere questi algoritmi: SAS, SPSS e R. In realtà, per l'algoritmo di Hanurav, ho provveduto alla scrittura del relativo codice in R, non essendo disponibile nelle library a me note.
I risultati sono interessanti e riassunti  nelle seguenti slide:


 

Spero di condividere al più presto il codice R di Hanurav-Vijayan in un package liberamente scaricabile.

29 dicembre 2011

RExcel e rpart

Nel numero di Dicembre di "The R Journal" è presente (tra gli altri) un articolo inerente lo sviluppo di "applicazioni" mediante RExcel e R. Nello specifico, abbiamo preso come esempio la libreria rpart, quindi gli Alberi di Classificazione, con un esempio di applicazione nel processo di approvazione di richiesta credito.

27 settembre 2011

RStudio per un agevole uso di R

Dopo un periodo di intenso utilizzo, posso concludere che RStudio sia  (... forse...) l'interfaccia più interessante per R (ovviamente, solo in base ad un mio personalissimo parere) . Attualmente, infatti, è divenuto uno strumento fondamentale che mi ha portato ad un utilizzo sempre più raro delle altre gui di cui ho sempre usufruito.
In particolare, tra le tante, evidenzio la possibilità di importare un dataset  in R (in "stile" csv), in maniera molto agevole e senza scrivere codice ... esattamente come accade con i software commerciali.
Il tutto avviene così come nelle immagini in basso, ossia disponendo di un menu sul lato destro della "schermata" del software:








Quindi, direi problemi risolti per il tanto noioso import di un csv!

05 giugno 2011

Rconsole: modificare le preferenze dell'interfaccia di R

Con questo post tratto un aspetto veramente banale, ma che ho notato essere molto irritante per i newbie (...e non solo...) di questo linguaggio! Effettivamente, mi sento di dire che non è affatto intuitivo il settaggio delle preferenze della GUI, ma che in realtà e tutto molto semplice con qualche piccolo accorgimento.
Innanzitutto, è necessario sottolineare che quando si installa R si sceglie un linguaggio che NON è quello che verrà poi impostato di default nella GUI di R.
Infatti, durante la fase di installazione (ossia, dopo il doppio click sull'installer exe), si otterrà la seguente finestra:


in cui si sta scegliendo la lingua per le finestre di dialogo relative alla sola installazione (che dovrebbe essere un approccio tipico di quanto accade, in genere, in Windows) e non alla lingua che si osserverà dopo nell'interfaccia di R.
Se non si cambiano le preferenze in Rconsole (e, dopo, vedremo come!), la lingua che si potrà osservare nei (pochi) menu presenti nella GUI di R e nei messaggi di output, sarà quella prevista per la macchina (pc) su cui avete installato R. Se, ad esempio, lavorate con Windows 7 in italiano, dopo l'installazione di R noterete che i menu saranno proprio in italiano. In pratica, quindi, la lingua di default prevista in R è quella impostata sulla macchina.
In genere, comunque, io consiglio sempre di impostare la lingua inglese. Oltre, infatti, ad essere una pratica sostanzialmente diffusa tra gli utenti (almeno in base a quanto riportato qui), capiterà sicuramente di volere discutere di problemi (e soluzioni) con il vastissimo gruppo di utenti che, nel mondo, sostengo questo linguaggio (gran punto di forza di R!!!). In tal caso, sarete costretti a scrivere in inglese e, in particolare, a riportare i messaggi di errore che vi restituirà il software (ovviamente, nessuno ci vieta di cercare aiuto nei forum italiani, come questo e quest'altro).
Quindi, la modifica delle preferenze dell'interfaccia di R, tra cui la lingua, è possibile dal menu "Modifica>Preferenze interfaccia..." :


Dopo il click si aprirà la seguente maschera che contiene tutte gli aspetti personalizzabili della GUI:

In particolare,  notiamo che per i singoli "aspetti" da modificare, nonostante stiamo lavorando con un menu in italiano, viene utilizzato il linguaggio inglese. Questo non è un errore, come spiegato meglio anche qui.
Oltre alla lingua, un'altra caratteristica molto importante è l'impostazione di una single o multiple document interface (SDI o MDI, ma non mi dilungo sulle differenze perché si tratta di un metodo di organizzazione delle GUI che non è specifico di R). Un tempo, se non ricordo male, il default era SDI, ma ora dovrebbe essere MDI (e credo che sia preferibile).
A questo punto, cambiare le lingua è immediato, in quanto basta impostare "EN" come di seguito:


L'aspetto che confonde tutti è che, probabilmente, viene naturale cliccare su "ok" o su "Apply" , ma  purtroppo non è così. Si otterrebbe, infatti, il seguente messaggio:


Il giusto "metodo" consiste nel salvare le impostazioni, prima di vederle attive: si cliccherà, quindi, su "save", scegliendo di salvare il file "Rconsole" nella relativa directory "\etc" che trovate nella cartella in cui è installato R (sostituendo il file già esistente). Normalmente, in Windows 7, sarà la seguente:  "C:\Program Files\R\R-2.13.0\etc":


A questo punto, sarà sufficiente cliccare su "cancel" (anche su ok, è la stessa cosa, ma otterrete nuovamente il messaggio di informazione di cui sopra), chiudere R e riaprirlo per vedere modificate le preferenze della GUI.
In pratica, quindi, Rconsole è un file di testo che contiene tutte le informazioni sulle preferenze di R. Se provate ad aprirlo con un editor di testo (blocco note), capirete che tutte le impostazioni possono essere modificate direttamente da qui.
L'aver impostato "EN" nella maschera che si apre da "Modifica>Preferenze interfaccia...", è equivalente a scrivere "language=EN" nel file Rconsole:


Infine, sottolineo che per modificare queste preferenze, dovrete agire da Amministratori. Se non sarà così, otterrete questo messaggio di errore, quando cercherete di salvare le nuove preferenze, cliccando su "save":


Per aprire R come amministratori, quindi, tasto destro sull'icona di R e "esegui come amministratore".
Infine, all'atto di salvare le preferenze, sarà fondamentale salvare il file Rconsole nella directory "\etc", appunto la directory di default per salvare le vostre preferenze della GUI!
Concludo dicendo che, probabilmente, troverete più comodo aprire direttamente il file Rconsole con il blocco note e cambiare direttamente le vostre preferenze! Anche in questo caso, inoltre, sarà necessario agire da Amministratori!

17 dicembre 2010

Installazione di RKWard su Windows

RKWard è un progetto molto curato in ambiente Linux, mentre è dichiaratamente un "progetto giovane" in ambiente Windows, con diversi bug legati soprattutto alle interfacce di selezione dei file e al download "interattivo" di file da internet (tipicamente, l'installazione di una libreria).
Tra le GUI che conosco è quella che, forse, si presenta con la migliore "veste grafica". 
Le maschere di dialogo con cui si interagisce sono perfettamente analoghe a software come SPSS o STATISTICA, in cui si seleziona il dataset di input, le variabili e le varie opzioni in base all'output che si vuole ottenere (...con questo non voglio dire che si tratta di strumenti equivalenti...). Ad esempio, questo è il menu per le statistiche descrittive:


L'output che si ottiene, inoltre, è analogo, ad esempio, a quanto si ottiene in SPSS, ossia un insieme di risultati in formato "report" (il tutto altamente personalizzabile). 

Per quanto riguarda l'installazione, che spesso è l'aspetto che blocca molti utenti (non molto esperti, in ambiente windows) nell'utilizzo di uno strumento software, nella pagina ufficiale si suggerisce il download di un "semplice" file .exe, così come avviene, in generale, in Windows.

Diversamente da quanto suggerito in tali pagine, io consiglio l'installazione personalizzata (della quale, comunque, se ne parla sempre nella pagina ufficiale). Quanto riporto di seguito, quindi, è consigliabile per chi dispone già di una versione di R installata sulla propria macchina. Preciso, inoltre, che ci riferiamo a Windows - 32 bit (XP, vista o 7).
Quindi, la prima cosa da fare è il download di:
Nello stesso ordine appena riportato, installate queste componenti.
Per quanto riguarda KDE, scegliete le impostazioni riportate negli screenshot qui di seguito (che dovrebbero presentarsi nello stesso ordine):

il complier mode è MinGW4


qui ho scelto il server ftp.unina.it







scegliere kdebase-workspace


A questo punto verranno scaricate una serie di pacchetti necessari al funzionamento corretto e sarà necessario un po' di tempo. Evidenzio che la seguente procedura prevede un'installazione su una macchina connessa ad internet!
Successivamente, si passerà all'installazione di RKWard. Si presenteranno due finestre in cui scegliere le directory di installazione di R e KDE (installato precedentemente). Se state usando questa "guida", immagino (e, in caso non sia così, consiglio) che abbiate una macchina con installazioni "standard" dei vari software che utilizzate. Quindi, la directory di riferimento sarà sempre quella in cui sono installati i programmi.
Ad esempio, nella maschera successiva ho selezionato la directory in cui è installato R: 



Analogamente, sceglierò quella in cui è installato KDE:


Al termine di questi step (se tutto è andato a buon fine) l'avvio di RKWard avviene diversamente da quanto siamo abituati con un generico "software" in Windows. Nella classica cartella "Programmi", infatti, non sarà disponibile la relativa directory.
Per il suo avvio, infatti, sarà necessario cliccare sul file rkward.bat che, se avete effettuato l'installazione in linea con quanto precedentemente indicato, sarà presente nella directory "\KDE\bin". Ad esempio, nella mia installazione su Vista, questa è la directory:






29 novembre 2010

Statistica 10

Esce la 10! Qui tutte le info.

20 settembre 2010

Importare in R le serie storiche di Yahoo! Finanza

Ho notato non essere chiaro, ad alcuni utenti di R, la possibilità di importazione "diretta" delle Serie Storiche disponibili in Yahoo! Finanza. Con una sola riga di codice, quindi, è possibile effettuare l'importazione del dataset e, quindi, lavorare con l'analisi delle serie storiche.
Dal sito è, in genere, disponibile il file csv relativo al titolo che ci interessa. Ad esempio, qui dovrebbero essere disponibili le quotazioni storiche del NASDAQ. In fondo alla schermata, è possibile cliccare su "Preleva i dati su foglio di calcolo" e salvare i dati in csv.
Per effettuare l'importazione direttamente in R, è sufficiente eseguire le seguenti istruzioni:
  • invece di cliccare su "Preleva i dati su foglio di calcolo", tasto destro > copia indirizzo;
  • digitare in R l'istruzione riportata di seguito (nelle prime tre righe, si può notare l'indirizzo che ho copiato al passo precedente).
  • Sucessivamente, in R sarà disponibile il data.frame "db" con i dati del NASDAQ.
db<-read.table("http://ichart.yahoo.com/table.csv?s=%5EIXIC&d=8&e=21&f=2010&g=d&a=1&b=5&c=1971&ignore=.csv",
dec=".",
sep=",",
header=T)

24 giugno 2010

Test F nel DOE per distribuzioni non normali

Chiunque si occupa di DOE (Design of Experiment), quindi di applicazioni della statistica in ambito industriale, si trova nella situazione di dover eseguire un test F per verificare la significatività dei trattamenti e delle loro interazioni. Parlando in un gergo più generale, non specifico della Statistica Industriale, tale analisi consiste (in genere) nell'esecuzione di una ANOVA, che sappiamo essere legata alle ipotesi di normalità e omoschedasticità.
La deviazione dall'assunto di normalità viene gestita mediante analisi non parametriche, mediante trasformazioni delle variabili, oppure giustificando il tutto mediante la robustezza del metodo allo scostamento da tale distribuzione.
In realtà, un'importante giustificazione è riportata in Design and Analysis of Experiments, noto testo di Montgomery. Secondo quanto evidenziaato, infatti, basta pensare al test F in un contesto non parametrico e, più precisamente, basato sulla teoria dei permutation test.
Nell'ipotesi nulla di assenza di diversa influenza tra trattamenti, è possibile costruire l'insieme di tutte le possibili suddivisioni (senza ripetizione) degli N elementi in k gruppi, dove k è il numero di fattori, N il numero totale di misurazioni (N=n * k). Per ognuna di queste suddivisioni, possiamo calcolare la statistica F (rapporto tra MSE) e considerare come si distribuisce al variare di tutte le possibili suddivisioni. A questo punto, secondo la metodologia che è alla base dei permutation test, è sufficiente verificare se il valore della F osservato mediante il nostro Disegno Fattoriale, è situato "troppo a destra" nella distribuzione ottenuta.
Ebbene, così come riportato nel testo citato, si dimostra che la distrubuzione "esatta" della statistica F calcolata in questo modo, distribuzione detta exact randomization distribution, è ben approssimata dalla distribuzione F di Snedecor, relativa all'ipotesi di normalità dei dati. Questo, in altri termini, significa che l'esecuzione di un Disegno Fattoriale mediante la F di Snedecor, quando non è valido l'assunto di normalità, può essere comunque visto come l'esecuzione di un test F non parametrico di tipo permutation test (continuando, quindi, a rimanere valido l'intero esperimento!).

20 maggio 2010

Grafici in PostgreSQL con R

Nel precedente post ho evidenziato le possibilità di integrazione di R in PostgreSQL, con un esempio sull'esecuzione di un test statistico per la normalità, direttamente nel db.
In questo breve post, faccio un altro esempio per la creazione di un grafico mediante un'opportuna funzione. Anche in questo caso, il motore di creazione dei grafici è R, eseguito in background mediante il linguaggio PL/R. Le potenzialità di questo metodo di lavoro sono evidenti: in Postgres è direttamente disponibile una vastissima gamma di grafici di alto livello.
Ovviamente ciò non significa che, in seguito alla chiamata della funzione, verrà visualizzato il grafico a video. L'esecuzione della procedura, invece, andrà a creare un grafico (nel mio caso, un file jpeg) in un'opportuna cartella.
Il codice per la creazione della funzione è il seguente e penso sia abbastanza immediato per gli utenti di R.

CREATE OR REPLACE FUNCTION createGraph(tb text)
RETURNS text AS
'
sql<-paste("select * from", tb)
rs<-pg.spi.exec(sql)
x<-rs[,1]
y<-rs[,2]
jpeg("graph.jpg")
plot(x,y)
dev.off()
print("done")
'
LANGUAGE 'plr';


L'utente dovrà successivamente scegliere un'opportuna tabella contenente dati da visualizzare in un grafico a due dimensioni. I dati saranno quelli contenuti in due specifici campi. Quindi, per esempio, la chiamata della funzione:

SELECT createGraph('tbOrdini');


andrà a creare un file jpg, contenente il grafico che in R visualizzo con il comando plot(x,y). Sottolineo che la directory di default in cui viene salvato il file è la cartella '...\PostgreSQL\8.X\data'. Ovviamente, è possibile cambiare il percorso in cui salvare il file .jpg, specificandolo nel comando jpeg (utilizzato in PL/R), ma questo potrebbe comportare qualche problema agli utenti Vista, nel caso dell'eventuale assenza di permessi in scrittura.
Ovviamente, l'esempio è volutamente semplice, ma può essere personalizzato ed esteso a situazioni più complesse.

05 marzo 2010

R in PostgreSQL

L'integrazione di R con i DBMS è un aspetto molto importante per la realizzazione di soluzioni analitiche in questo linguaggio. Se si lavora in ambito industriale, ad esempio, i dati saranno raccolti in un database. Quindi, sarà necessario sviluppare un'interfaccia "facile" al motore di calcolo e permettere all'utente di interrogare i dati, sia per estrarre informazioni "semplici" (in tal caso R dovrebbe essere superfluo), sia per applicare una qualche forma di sintesi. Se per quest'ultimo tipo di elaborazione, le funzioni di aggregazione previste nel db non fossero sufficienti, è possibile ricorrere ad R. Una prima possibilità, sicuramente molto più diffusa, è quella di lavorare importando i dati in R ed eseguendo, direttamente in tale ambiente, le necessarie elaborazioni. Tale tipo di approccio, ad esempio, lo si realizza facilmente mediante il package RODBC.
Esiste tuttavia un'altra possibilità che, in base ad una mia personale sensazione, è poco conosciuta. Nell'universo dei DBMS, esiste ed è molto diffuso PostgreSQL . Per tale tipo di database, è prevista la possibilità di utilizzare un particolare linguaggio procedurale, ossia PL/R, che permette di scrivere (ed utilizzare) direttamente in PostgreSQL, funzioni in linguaggio R (in realtà esiste anche la possibilità di lavorare in R mediante RPgSQL, ma spero di dedicarci un post a parte). Quindi, saranno disponibili tutte le normali funzioni già previste in R, nelle varie librerie, così come sarà possibile sviluppare nuove funzioni di PostrgreSQL, utilizzando la sintassi di R.
Per l'utilizzo di tali modalità, ovviamente, è necessario avere una certa conoscenza di questo database, oltre che una certa familiarità con R. Per le problematiche di installazione (in particolare, in ambiente Windows) ed utilizzo, in generale, si rimanda ai siti:
Oltre a fare questa segnalazione, quindi, intendo riportare degli esempi utili ad evidenziare le potenzialità di tale modalità di sviluppo.

Immaginiamo di progettare, in ambito industriale, un database che raccoglie dati sulla produzione di semilavorati in un centro siderurgico, ad esempio dei tubi di acciaio. Periodicamente, a campione, viene misurata e registrata la circonferenza esatta di tali prodotti che, ovviamente, deve rispettare determinati livelli di tolleranza prestabiliti. In tale processo industriale, quindi, ci si aspetta un "errore" nella produzione, ossia degli scostamenti dalla circonferenza media prevista. Per controlloare questo aspetto, ad esempio, si cercherà di testare l'ipotesi di normalità dei dati, quindi la casualità degli scarti. Nell'esempio che propongo successivamente, quindi, vado proprio ad eseguire un test statistico sulla normalità dei dati direttamente nel database, in maniera "nativa". A mio parere, questo è un risultato eccezionale! Non mi sembra esistano possibilità analoghe in altri DBMS!
Non è superfluo evidenziare che si tratta solo di un esempio! Nell'ambito del controllo statistico della qualità, il controllo della produzione è realizzato mediante processi più complessi.

Quindi, riepilogando, è sufficiente crare un'apposita funzione in PostgreSQL, mediante il seguente codice:

CREATE OR REPLACE FUNCTION testNormality(tb text, col text)
RETURNS double precision AS
'
sql<-paste("select", col, "from", tb)
rs<-pg.spi.exec(sql)
shapiro.test(rs[,1])$p.value
'
LANGUAGE 'plr';

In generale, in PostgreSQL è possibile utilizzare diversi estensioni di linguaggio procedurale (come pgSQL, Python, Java ...), che rendono altamente personalizzabili le funzioni presenti nel database. Nello specifico, qui stiamo usando il linguaggio PL/R che, appunto, mi permette di scrivere in R. La documentazione ufficiale la trovate qui. In particolare, si noti che tra gli apici va riportato il codice R, che verrà eseguito alla chiamata della funzione.
Nel nostro caso, quindi, sto definendo la funzione testNormality che prende in input due parametri di tipo testo: il nome di una tabella (tb) e il nome di un campo di quest'ultima (col). Tali informazioni vengono "passate" ad R in cui creo la stringa sql che, appunto è la query in linguaggio SQL:

SELECT col FROM tb;

10 febbraio 2010

Statistica e Scienza dell’Informazione: riflessioni di uno statistico

Non so quanti di voi siano informati del fatto che la SIS, Società Italiana di Statistica, dedica una sezione del sito per pubblicare il Sis-Magazine, giornale online ricco di riflessioni. Io ho l'impressione che sia poco conosciuto nel mondo di quelli che chiamo "statistici applicati", ossia quelli che lavorano per aziende private, ovviamente in ambito statistico. E' evidente che vengono trattati anche argomenti interessanti per questo tipo di utenti.
Ebbene, lo scorso mese è stato pubblicato un articolo (veramente bello) del prof. Isabella Verdinelli, ricco di riflessioni sulle similarità e differenze tra Metodi Statistici e Metodi di Machine Learning. Questo il link, invito tutti a leggerlo!
In merito a quanto scritto, io direi che uno statistico deve essere oggi anche un informatico: deve programmare, deve lavorare con i database, deve conoscere i sistemi operativi. Inoltre, non è pensabile oggi di proporre un metodo statistico senza valutare la sua fattibiltà da un punto di vista computazionale. Lo sforzo importante, in base a quelle che sono state le mie esperienze lavorative, sarebbe quello di "orientare" maggiormente all'informatica i corsi di laurea in Statistica (...ammesso ovviamente che questo oggi non stia già accadendo...).

22 dicembre 2009

SQL join in R

Consideriamo un classico esempio di 3 tabelle di un database, ognuna con i rispettivi campi:
  1. acquisti (codFornitore, numeroColli, codProdotto, codQualità)
  2. prodotti (codice, qualità, descrizione)
  3. fornitori (codice, nome)
I fornitori hanno un codice numerico ed un nome. Ogni prodotto ha un codice numerico ed uno di qualità e, per ognuna di queste combinazioni, c'è una descrizione. Infine, gli acquisti prevedono un codice di fornitori, uno di prodotto e di qualità, infine il numero colli acquistati.

In una situazione di questo tipo, è comune eseguire le operazioni di "congiunzione" (appunto, join) tra tabelle. Per ogni comando SQL in un db, esiste un analogo in R mediante la funzione merge. Riporto di seguito degli esempi di comparazione dei due linguaggi, ipotizzando di disporre in R dei relativi dataframe.

Visualizzo gli acquisti assieme al nome del fornitore.

Inner join in SQL:

SELECT a.*, b.nome
FROM acquisti AS a INNER JOIN fornitori AS b
ON a.codFornitore = b.codice;

Inner join in R:

>merge(acquisti,fornitori,by.x="codFornitore",by.y="codice")

Visualizzo gli acquisti assieme a tutti i fornitori, compresi quelli dai quali non ho comprato prodotti.

Right join in SQL:

SELECT a.*, b.nome
FROM Acquisti AS a RIGHT JOIN Fornitori AS b
ON b.codice = a.codFornitore;

Right join in R:

>merge(acquisti,fornitori,by.x="codFornitore",by.y="codice",all.y=T)

Visualizzo gli acquisti assieme alla descrizione del prodotto (descrizione relativa al tipo di prodotto ed alla sua qualità), compresi i prodotti che non sono stati acquistati.

Left join in SQL:

SELECT a.*, b.codFornitore, b.numeroColli
FROM Prodotti as a LEFT JOIN Acquisti as b
ON (a.qualità = b.codQualità) AND (a.codice = b.codProdotto);

Left join in R:

>merge(prodotti,acquisti,by.x=c("codice","qualità"),by.y=c("codProdotto","codQualità"),all.x=T)

Infine, solo per completezza, riporto il codice di una full, ma in tal caso il risultato è analogo alla left.

Full join in SQL:

SELECT a.*, b.codFornitore, b.numeroColli
FROM Prodotti as a FULL JOIN Acquisti as b
ON (a.qualità = b.codQualità) AND (a.codice = b.codProdotto);

Full join in R:

>merge(prodotti,acquisti,by.x=c("codice","qualità"),by.y=c("codProdotto","codQualità"),all.x=T,all.y=T)

Riassumendo, quindi, la logica in R è molto intuitiva, alla pari dell'SQL.
Con by.x e by.y, si determinano i campi su qui eseguire la join, ossia i campi da "legare". Mediante all.x e all.y si stabilisce se left, right o full join.
Per tutte le varianti della funzione, si rimanda all'help di R.

26 novembre 2009

Configurazione di natbib_ita in MikTex 2.8 per Vista

Mi arrivano parecchie richieste relative all'installazione su Vista di MikTex. Io ho effettuato alcune configurazioni e non ho avuto particolari problemi. Quindi, l'installazione rimane esattamente quella descritta in questo mio post. Ovviamente, è necessario procedere con privilegi da amministratore!
Qualche "problemino" di configurazione riguarda invece natbib_ita, il pacchetto per la gestione della bibliografia in italiano. In MikTex (versione >=2.7) sono già previsti alcuni file .bst che servono all'uso di bibtex, ma non quelli per lo "stile" italiano.
Quindi, qui scaricate quello che vi serve, e noterete i seguenti file:
  1. natbib.sty
  2. plain_ita.bst
  3. natbib_ita.bst
  4. natbib.bst
Gli altri file servono per testare la configurazione, consiglio di leggerli attentamente!!!
A questo punto:
  1. copiate il file natbib.sty in "C:\Program Files\MiKTeX 2.8\tex\latex\natbib" (cancellando quindi il file con lo stesso nome che trovate in questa cartella);
  2. copiate i rimaneti 3 file in "C:\Program Files\MiKTeX 2.8\bibtex\bst\base";
  3. tramite il "programma" miktex options (start -> tutti i programmi -> MikTex 2.8 -> Maintenance -> Settings), eseguite il refresh, ossia, nella scheda General, cliccate su "Refresh FNDB" e su "Update Formats".
Nelle configurazioni eseguite non ho riscontrato nessun problema. Per maggiori informazioni c'è sempre il sito del GUIT.

26 ottobre 2009

Vectorizing computing in R

Un forte limite nell'utilizzo di R (in particolare per chi è già abituato a sviluppare in altri linguaggi di programmazione) è la lentezza dell'esecuzione di algoritmi basati sui classici "cicli di for". Eseguire un blocco di codice ripetutamente, infatti, è un'operazione concettualmente semplice che, quindi, ci permette di gestire facilmente la ripetizione di un insieme di "operazioni" (eventualmente effettuando il controllo di alcune condizioni con dei sempici "if"). Putroppo in R è fortemente sconsigliato questo approccio e per questo motivo si parla di vectorizing computing: trasformare il ciclo di for in operazioni tra vettori o matrici. Quindi la ripetizione di un blocco di codice controllato da un contatore deve essere trasformato, ad esempio, in un prodotto di matrici. Questo metodo di sviluppo ha come fine quello di sfruttare al meglio il motore di calcolo di R, che è appunto ottimizzato per il calcolo matriciale. Ovviamente questo approccio può portare ad altro tipo di problemi, ossia alla gestione dei dati mediante matrici "troppo grandi" e difficilmente gestibili. L'esperienza comunque permette di arrivare alla soluzione megliore, e non credo si possa stilare un elenco di situazioni in cui preferire un approccio ad un altro: ogni soluzione va valutata singolarmente "sul campo" (...bella novità...).
Riporto di seguito alcuni esempi di for in R con le relative "vettorizzazioni".

Creo un vettore p composto da 500.000 valori estratti da una normale standardizzata e, da questo, ne derivo il vettore formato dagli stessi 500.000 valori rapportati alla loro somma. Forse la vettorizzazione di questo esempio è veramente banale, ma serve a rendersi conto dei tempi di esecuzione.
Il relativo ciclo di for è semplicissimo:


p<-rnorm(500000)
s<-sum(p)
for (i in 1:500000) p[i]<-p[i]/s


Per la valutazione dei tempi di esecuzione basta osservare il risultato di system.time(),che esegue il codice in parentesi e riporta il tempo in secondi. Nel nostro caso ci limitiamo ad osservare il tempo elapsed (in blu è roportato l'output di R):


system.time(for (i in 1:500000) p[i]<-p[i]/s)
user system elapsed
3.2 0.0 3.2


La cosiddetta vettorizzazione è in tal caso banale (p/s), ma il risultato è notevole:


system.time(p<-p/s)
user system elapsed
0.0 0.02 0.02



In termini assoulti, un risparmio di 3.18 secondi può sembrare inutile, ma se si ragiona in termini relativi si osserva un risparmio del 99% del tempo di esecuzione, quindi molto importante per calcoli più complessi!

Prendiamo in esame un esempio in cui la vettorizzazione è meno immediata.
Consideriamo un insieme di 1.000.000 di dati estratti da una normale standardizzata. Pensate ad esempio ad un tipica applicazione in ambito industriale, in cui si controlla che il prodotto rispetti determinate caratteristiche (peso, dimensioni, ecc. ...) e in cui ci si aspetti che gli "errori" nella produzione siano distribuiti normalmente. In elaborazioni effettuate in tale ambito, quindi, si dispone di un vettore di questo tipo. I calcoli che svolgo di seguito, comunque, sono solo a titolo di esempio e non rappresentano alcun indicatore o controllo tipico della statistica industriale.
Immaginiamo di avere i dati in forma matriciale: 1000 casi controllati (in riga) per 1000 caratteristiche (in colonna). Da questo dataset vogliamo ricavare una matrice di valori dicotomici, con 1 o 0 a seconda che il valore sia maggiore o uguale a zero (1), oppure negativo (0), rispettivamente.
Anche in questo caso il codice da usare per un ciclo di for è immediato:


N<-1000
mtx<-matrix(rnorm(N*N),N,N)
mtx2<-matrix(0,N,N)

system.time(for (i in 1:N) for (j in 1:N) if(mtx[i,j]>=0) mtx2[i,j]<-1)
user system elapsed
6.20 0.00 6.52


La vettorizzazione si può effettuare mediante il comando ifelse(), che analizza ogni singolo elemento della matrice e esegue un'operazione a seconda che il test sia positivo o negativo (da notare che è differente da if() else):


system.time(mtx2<-ifelse(mtx>=0,1,0))
user system elapsed
0.90 0.05 0.98



Anche qui la riduzione del tempo di elaborazione è molto significativa: 85%.

Riporto infine un esempio di vectorizing computing in cui si fa uso di matrici triangolari, molto utili in questo tipo di programmazione in R.
Consideriamo sempre la matrice mtx di 1000 casi per 1000 caratteristiche. Per ogni singolo caso (vettore riga) vogliamo calcolare il rapporto tra l'(i)-esimo elemento e la somma dei successivi 1000-i elementi (quindi la somma dei casi da (i+1) a 1000). La soluzione con un for necessita lo scorrimento dell'intera matrice in questo semplice modo:


N<-1000
mtx<-matrix(rnorm(N*N),N,N)
mtx2<-matrix(0,N,N) system.time(for (i in 1:N) for (j in 1:(N-1)) mtx2[i,j]<-mtx[i,j]/sum(mtx[i,(j+1):N]))
user system elapsed
37.99 0.17 39.93

Per la trasformazione in codice vettorizzato faccio uso del comando lower.tri(), che crea una matrice triangolare inferiore con valori TRUE e FALSE. Dal relativo help di R: "Returns a matrix of logicals the same size of a given matrix with entries TRUE in the lower or upper triangle".

Questo il codice:



N<-1000
mtx<-matrix(rnorm(N*N),N,N)
mtx2<-matrix(0,N,N)
system.time(mtx2<-mtx/(mtx%*%(1*lower.tri(matrix(0,N,N)))))
user system elapsed
2.55 0.00 2.67


Ho praticamente sostituito lo scorrimento dei dati mediante for, con un prodotto matriciale in cui vi è un'opportuna matrice triangolare inferiore. La riduzione del tempo di elaborazione è del 93%.