---
title: "RLab: Distanze e dissimilarità"
output:
  html_document:
    df_print: paged
  pdf_document: default
---

## Introduzione 

Consideriamo un insieme di caratteristiche $x_1, x_2, \dots, x_p$ misurate su $n$ osservazioni.
Piuttosto che considerare la previsione di una variabile di risposta associata come è tipico nel quadro dei 
I metodi cosiddetti di apprendimento supervisionato (ad esempio, regressione e classificazione) consentono di ottenere una previsione relativa ad una variabile risposta; in questo contesto siamo invece interessati a estrarre informazioni sulla struttura dei dati:

- Esiste un modo informativo per visualizzare dati multivariati?
- Si possono individuare sottogruppi di unità che siano simili rispetto a quelle in gruppi diversi?

Per rispondere a domande come queste vengono utilizzate tecniche di apprendimento non supervisionato che includono l'analisi delle componenti principali e il clustering. Il problema fondamentale del clustering può essere formulato come segue:

*Dato un insieme di $p$ variabili rilevate su $n$ unità, si vogliono raggruppare le unità in modo tale che le unità appartenenti a ciascun gruppo siano il più possibili omogenee.*

Tale problema può essere affrontato utilizzando un'ampia varietà di metodi, a seconda dell'approccio specifico utilizzato per definire la somiglianza tra due punti dati, dell'algoritmo adottato per derivare i gruppi (ad esempio, metodi gerarchici e non gerarchici) e del tipo di dati specifico (alcuni tecniche sono applicabili solo a dati continui, alcuni altri metodi possono essere utilizzati su dati qualitativi o dati misti).


### Un esempio con dati simulati

L'esempio seguente utilizza dati simulati costituiti dal numero medio (mensile) di pasti consumati fuori casa (ad es., al ristorante) e dalla spesa per i pasti consumati a casa (annuale) per un insieme di 100 famiglie. Per prima cosa leggiamo i dati dal file ``food_spending.csv``, che contiene le colonne ``FreqAway`` e ``Home``, quindi otteniamo il grafico a dispersione dei dati o \emph{scatterplot}:

```{r, fig.height=4, fig.width=4}
FoodS<-read.csv("food_spending.csv", header=TRUE)
head(FoodS)
dim(FoodS)

library(ggplot2)
ggplot(FoodS, aes(FreqAway, Home)) + 
  geom_point()

``` 

Il grafico evidenzia due gruppi ben separati, il gruppo con una spesa bassa per i pasti consumati a casa e un’elevata frequenza di pasti fuori casa, e il gruppo di famiglie con una spesa elevata per i pasti consumati fuori casa e una bassa spesa per i pasti consumati a casa. 

In un problema non supervisionato miriamo a identificare cluster distinti sulla base delle variabili osservate su un insieme di unità. 
I gruppi risultanti sono tali che i membri dello stesso gruppo sono omogenei rispetto alle variabili coinvolte, mentre le osservazioni in gruppi diversi sono piuttosto diverse tra loro. Il primo passo è quantificare, per due unità qualsiasi, il grado di  'somiglianza'.

## Calcolo della matrice di dissimilarità o distanza 

In ``R``, la funzione  ``dist()`` consente di calcolare la distanza tra due punti (ad esempio, la distanza euclidea tra due vettori); il tipo di distanza da calcolare viene specificato con ``method``, che può essere  "euclidean" (default), "maximum", "manhattan", "canberra", "binary" o "minkowski":

```{r}
# distance matrix via dist function
D.<- dist(FoodS) # Euclidean distance
str(D.)
head(D.)
# coercion to matrix and 
#selection of 5 rows/columns
Dmat<-as.matrix(D.) 
Dmat[1:5, 1:5]
range(Dmat)
#View(Dmat)
```


In alternativa, il pacchetto ``cluster`` può essere utile per ottenere una matrice di dissimilarità attraverso la funzione ``daisy()`` ed ha il vantaggio di avere tra le possibili opzioni la scelta dell'indice di Gower per variabili miste. 

```{r}
library(cluster)  # load cluster library
```
Per conoscere meglio la funzione ``daisy()`` si ricorra alla documentazione dell'Help:

```
 ?daisy
``` 
 
Cominciamo calcolando la matrice delle distanze euclidee per il dataset ``FoodS`` (opzione di default per ``metric``)

```{r}
dist1<-daisy(FoodS)
``` 

Otteniamo le prime cinque righe e colonne della matrice delle distanze
(si noti che la funzione ``as.matrix`` è necessaria per trasformare l'output di ``daisy`` che restituisce un oggetto della classe \emph{dissimilarity}) 

```{r}
as.matrix(dist1)[1:5, 1:5]
``` 

Talvolta, quando le variabili presentano scale di grandezza diverse o variabilità molto eterogenea, è opportuno uniformare il contributo di ciascuna variabile trasformando preliminarmente i dati. 
Spesso, ad esempio, le variabili vengono centrate e divise per la loro deviazione standard, oppure si normalizza ciascuna variabile in base al range della stessa.

La funzione ``daisy()``  consente di centrare le variabili e riscalarle attraverso l'argomento ``stand`` (si veda l'Help per maggiori dettagli sulla trasformazione applicata ai dati originali): 

```{r}
dist2<-daisy(FoodS, stand=TRUE)
``` 

Dopo aver trasformato il risultato in una matrice, possiamo stampare le prime righe/colonne

```{r}
dist2m<-as.matrix(dist2)
dist2m[1:5, 1:5]
``` 

**$\color{red}{\text{Esercizio 1}}$** *Si ottenga la matrice di dissimilarità per ``FoodS`` utilizzando la distanza di Manhattan nella funzione ``dist()``. Si confronti il risultato con la matrice ottenuta mediante la standardizzazione preventiva dei dati effettuata con la funzione ``scale()``.*
 
 
Per calcolare le dissimilarità a partire da variabili di tipo misto è opportuno ricorrere all'indice di **Gower**. Nella funzione ``daisy`` occorre specificare ``metric = "gower"``. 

Consideriamo un dataset riferito ad un insieme di clienti di una assicurazione per i quali si dispone delle seguenti caratteristiche del sinistro:

- "litig": presenza di un contenzioso (no=0, sì=1)
- "soft_injury": presenza di lesione dei tessuti molli (no=0, sì=1)
- "emergency_tr": presenza di un trattamento di emergenza (no=0, sì=1)
- "NumTreat": numero di cure mediche 

Le prime tre variabili sono binarie e la quarta è numerica.

Importiamo i dati e codifichiamo le variabili categoriali come fattori:

```{r}
d<-read.csv(file="claims.csv", header = TRUE)
head(d)

d$litig<-as.factor(d$litig)
d$soft_injury<-as.factor(d$soft_injury)
d$emergency_tr<-as.factor(d$emergency_tr)

str(d)
 
```

**$\color{red}{\text{Esercizio 2}}$** *Descrivere le variabili del dataset utilizzando rappresentazioni grafiche e indici statistici appropriati.*


Per calcolare la dissimilarità  tra le unità mediante l'indice di Gower si ricorre ad una media ponderata dei contributi di ciascuna variabile, dove

- il contributo di una variabile nominale o binaria alla dissimilarità è 0 se entrambi i valori sono uguali, 1 altrimenti;

- il contributo delle altre variabili è la differenza assoluta di entrambi i valori, divisa per il \emph{range} di quella variabile

Si noti che è possibile assegnare un peso per ciascuna variabile invece di 1 nella formula originale di Gower. 

Limitandoci alle variabili binarie si ottiene la matrice di dissimilarità come segue 

```{r}
diss<-as.matrix(daisy(d[,-4], metric= "gower"))
diss[1:5, 1:5]
```

Considerando tutte le variabili si ottiene 

```{r}
diss<-as.matrix(daisy(d, metric= "gower"))
diss[1:5, 1:5]

```


```{r, fig.height=4, fig.width=4}
range(diss)
dim(diss)
d[as.vector(which(diss == max(diss), arr.ind = TRUE)[1,]), ] # two units with max dissim

Dvec<-as.vector(as.dist(diss))
ggplot() + 
  geom_boxplot(aes(y = Dvec)) + 
  scale_x_discrete( ) 
```
