Analisi dei Dati ed Estrazione della Conoscenza

Il sistema R: analisi di classificazione

Package

R dispone di una enorme numero di funzionalità aggiuntive al nucleo fondamentale del linguaggio, che sono organizzate sotto forma di package. Ecco un elenco di funzioni per manipolare i package.

Alberi di classificazione / regressione

Nel package rpart è implementato un algoritmo per l'induzione di alberi di classificazione e di regressione.

Ad esempio, consideriamo la seguente sessione di lavoro sul dataset iris:


> model=rpart(Species ~ .,iris)
> model
n= 150 

node), split, n, loss, yval, (yprob)
      * denotes terminal node

1) root 150 100 setosa (0.33333333 0.33333333 0.33333333)  
  2) Petal.Length< 2.45 50   0 setosa (1.00000000 0.00000000 0.00000000) *
  3) Petal.Length>=2.45 100  50 versicolor (0.00000000 0.50000000 0.50000000)  
    6) Petal.Width< 1.75 54   5 versicolor (0.00000000 0.90740741 0.09259259) *
    7) Petal.Width>=1.75 46   1 virginica (0.00000000 0.02173913 0.97826087) *
> plot(model)
> text(model)
> model=rpart(Species ~ .,iris,minbucket=2)
> model
n= 150 

node), split, n, loss, yval, (yprob)
      * denotes terminal node

 1) root 150 100 setosa (0.33333333 0.33333333 0.33333333)  
   2) Petal.Length< 2.45 50   0 setosa (1.00000000 0.00000000 0.00000000) *
   3) Petal.Length>=2.45 100  50 versicolor (0.00000000 0.50000000 0.50000000)  
     6) Petal.Width< 1.75 54   5 versicolor (0.00000000 0.90740741 0.09259259)
      12) Petal.Length< 4.95 48   1 versicolor (0.00000000 0.97916667 0.02083333) *
      13) Petal.Length>=4.95 6   2 virginica (0.00000000 0.33333333 0.66666667) *
     7) Petal.Width>=1.75 46   1 virginica (0.00000000 0.02173913 0.97826087) *

Nell'output della variabile model abbiamo una serie di righe, ognuna della forma "node), split, n, loss, yval, (yprob)", che danno informazioni sull'albero generato. L'indentazione evidenzia la relazione genitore-figlio tra i nodi, mentre i dati della singola riga hanno questo significato:

Le foglie sono inoltre etichettate con un asterisco. Per sapere il numero di errori compiuti nell'insieme di addestramento, basta sommare il valore di loss per tutti i nodi foglia.

> iris2=data.frame(Sepal.Length=c(6.1,5.1),Sepal.Width=c(3.3,2.3),Petal.Length=c(5.4,3.9),Petal.Width=c(2,1.1));
> plot(iris$Petal.Length,iris$Petal.Width,col=as.integer(iris$Species),pch=as.integer(iris$Species))
> points(iris2$Petal.Length,iris2$Petal.Width,col="blue",pch="X")
> predict(model,iris2)
     setosa versicolor  virginica
[1,]      0 0.02173913 0.97826087
[2,]      0 0.97916667 0.02083333

Dal diagramma si può vedere come la prima istanza sia nel mezzo del territorio dell'iris virginica, mentre la seconda sia nel territorio dell'iris versicolor. Applicando il metodo predict si vede che queste considerazioni visuali trovano conferma dal risultato del classificatore: ad ogni riga corrisponde una distribuzione di probabilità per la corrispondente istanza, ottenuta semplicemente copiando la distribuzione di probabilità della foglia del modello che corrisponde all'istanza.

Nearest Neighbour

Il package class implementa l'algoritmo k-nearest neighbour. La distanza utilizzata è quella euclidea, e funziona solo con attributi numerici. Le funzioni da usare sono le seguenti:

Esercizio

Confrontare la precisione di knn e rpart sul data-set dell'iris.

Regressione lineare

Esistono varie funzioni in R che consentono di effettuare la regressione lineare, semplice o multipla. Il comando di base è il seguente:

In pratica, il risultato di lm è una lista con varie componenti che contengono, oltre ai parametri della regressione, altre informazioni aggiuntive. Normalmente, però, R ci visualizza soltanto i parametri di regressione. Se vogliamo visualizzare la lista completa, possiamo usare il comando unclass:

> florida <- read.table("florida.txt");
> unclass(lm(BUCHANAN ~ BUSH, data=florida))
$coefficients
 (Intercept)         BUSH
45.289861271  0.004916828

$residuals
           1            2            3            4            5            6
  49.2331397    0.1267330   12.7386511   -6.9046518  -41.6347069 -127.9402315
           7            8            9           10           11           12
.... omissis ....

Il risultato di lm viene tipicamente salvato e usato come input ad una delle seguenti funzioni, che consentono di esplorare ulteriormente il modello trovato dalla regressione lineare:

Alcuni set di dati su cui poter fare esperimenti sono:

Esempio di analisi

Usando la funzione di regressione lineare, esaminiamo i risultati delle elezioni presidenziali USA del 2000. Vi ricordo che queste elezioni hanno suscitato molto scalpore perché in una delle circoscrizioni della Florida (Miami-Dade), il posto che normalmente era occupato da Gore nella scheda elettorale era invece occupato da Buchanan. A detta dei sostenitori di Gore, questo potrebbe aver causato un certo numero di errori nella votazione, che hanno consentito a Bush di vincere le elezioni in Florida, e quindi in tutti gli USA. Vediamo se questa ipotesi è plausibile.

Esaminiamo graficamente la relazione tra i voti di Bush e quelli di Buchanan nelle varie contee.

> florida = read.table("florida.txt")
> attach(florida)
> plot(BUSH, BUCHANAN)

Vediamo che ci sono due contee (una in particolare) che si comportano da outliers. Identifichiamo queste contee con il comando identify.

> identify(BUSH, BUCHANAN, n=2)
[1] 13 50
> florida[c(13,50),]
       County   GORE   BUSH BUCHANAN NADER BROWN HAGELIN HARRIS MCREYNOLDS MOOREHEAD PHILLIPS  Total
13       DADE 328702 289456      561  5355   759     119     88         36       124       69 625269
50 PALM BEACH 268945 152846     3407  5564   743     143     45        302       103      188 432286

Una delle due contee "strane" è proprio quella di Dade. Supponiamo allora che effettivamente ci sia stato un errore consistente nella procedura di votazione, e proviamo a calcolare il numero di voti corretto per Buchanan con la regressione lineare.

> model = lm(BUCHANAN ~ BUSH, data=florida[-50,])
> abline(coef(model)[1],coef(model)[2],col="red")
> predict(model, data.frame(BUSH=BUSH[50]))
       1 
597.7677
> BUCHANAN[50]
[1] 3407

Dunque, secondo i nostri conti, Buchanan avrebbe dovuto prendere circa 598 voti nella contea di Dade, e non 3407. La differenza è di 2809. Se questi fossero veramente voti "perduti" da Gore, siccome la differenza tra i voti di Bush e di Gore in Florida è soltanto 975, Gore avrebbe vinto le elezioni presidenziali.

Valid XHTML 1.1 Valid CSS!